Caffe CNN生成图像梦境时出现除零运行时警告问题求助
解决Caffe图像梦境中的"divide by zero" RuntimeWarning
我来帮你分析下这个除零警告的问题,结合你提供的代码、模型配置和操作流程,大概率是这几个地方出了问题,咱们一步步来排查修复:
1. 先搞定tmp.prototxt的完整性与结构匹配问题
你贴出来的tmp.prototxt内容明显是截断了,最后一行停在inner_pr,这会导致Caffe解析网络时出现参数缺失,后续计算很容易触发数值异常(包括除零)。另外还有个关键问题:
- 原始
VGG_FACE_deploy.prototxt里的conv1层num_output是96,但你tmp.prototxt里改成了64!而你的权重文件是基于原始结构训练的,这会导致权重加载不匹配,层参数异常,进而引发计算错误。
修复方案:
- 把
tmp.prototxt补全,完全对齐原始VGG_FACE_deploy.prototxt的层结构,只保留你需要修改的blobs_lr: 0(用来固定这些层的权重,只优化输入图像),不要改动num_output这类结构参数。补全后的fc6及后续层应该和原始配置一致:
layers { name: "fc6" type: INNER_PRODUCT bottom: "pool5" top: "fc6" inner_product_param { num_output: 4048 } blobs_lr: 0 blobs_lr: 0 } layers { name: "relu6" type: RELU bottom: "fc6" top: "fc6" } layers { name: "drop6" type: DROPOUT bottom: "fc6" top: "fc6" dropout_param { dropout_ratio: 0.5 } } # 后面的fc7、relu7、drop7、fc8_cat、prob层也要完整复制过来
- 把
tmp.prototxt里conv1的num_output改回96,和权重文件的结构完全匹配。
2. 排查LRN层的数值异常
你的模型里有norm1这个LRN层,它的计算逻辑涉及到除以局部区域的归一化值,如果输入图像预处理后出现大面积零值,就会导致局部区域的和为0,触发除零警告。
修复方案:
- 确认图像预处理流程:你设置的均值是
[104.0, 116.0, 122.0],通道转换是BGR,要确保输入图像是先转成float32,再减去均值,而不是先减均值再转类型,避免出现数值截断导致的零值。 - 可以尝试在预处理后给图像加一个极小的偏移值(比如
1e-8),防止出现绝对零值,比如:
# 预处理时添加小偏移 processed_img = (img.astype(np.float32) - mean) + 1e-8 processed_img = processed_img[:, :, ::-1] # 对应channel_swap(2,1,0)
3. 优化图像梦境过程的数值稳定性
图像梦境的反向传播优化容易出现数值突变,极端的像素值会引发后续层计算异常。
修复方案:
- 在优化循环中对输入图像做数值约束,比如限制像素值在合理范围(比如减去均值后在
[-127, 127]之间):
# 每次优化步后约束数值 img = np.clip(img, mean - 127, mean + 127)
- 降低优化的学习率,避免单次更新幅度过大导致数值溢出或零值出现。
- 添加L2正则项到损失函数中,防止输入图像的像素值变得极端。
最后验证步骤
- 先确保
tmp.prototxt结构完整、和权重文件匹配,能正常加载模型不报错; - 用一张正常的测试图像跑一遍前向传播,确认各层输出没有NaN或无穷大值;
- 再启动图像梦境的优化流程,观察除零警告是否消失。
内容的提问来源于stack exchange,提问作者user7830303
相关产品推荐
相关产品推荐

