基于MNIST的FSRCNN超分辨率模型训练20轮输出异常问题咨询
FSRCNN训练轮次增加后输出失真问题成因及解决方案
核心成因
- 训练数据未做归一化
代码中直接将cv2读取的0~255范围的像素值输入模型训练,MSE损失的计算数值会达到1e4甚至更高量级,训练初期优化器可以正常更新参数,但训练到后期梯度波动会显著增大,导致参数更新偏离合理区间,最终输出像素值异常。注意你仅在demo阶段做了/255的归一化,训练阶段完全没有做归一化操作,这是最核心的问题。 - 最后一层激活函数选择错误
原FSRCNN论文中反卷积输出层为线性激活,直接回归像素值,你的代码中在反卷积层加了activation='relu',训练到后期输出值超过合理范围后会被ReLU截断,或者出现大量异常高值,直接导致图像显示失真。 - 固定学习率未做衰减
你使用固定1e-3的学习率,10轮训练后模型已经接近收敛,继续训练时过大的固定学习率会导致参数在最优值附近反复震荡甚至偏移,验证损失不会出现明显上升(你误以为没有过拟合),但实际参数已经偏离可生成合理图像的区间。 - 无用代码存在运行风险
代码中保留的未完成的pickle序列化代码是无效的,变量y未定义,运行时会报错,不影响训练逻辑但存在隐患。
修复方案
- 训练前对输入输出图像做归一化:将
train_small_array、train_normal_array、测试集数组全部除以255,转换为0~1范围的float32类型。 - 移除反卷积层的ReLU激活,改为线性激活(删除
activation='relu'参数即可)。 - 添加学习率衰减策略,比如在训练10轮后将学习率降低为1e-4,或者使用Keras自带的学习率衰减回调。
- 可适当调小batch_size到256~512区间,降低梯度震荡的概率。
- 直接删除无效的pickle序列化代码段。
内容的提问来源于stack exchange,提问作者Noether
相关产品推荐
相关产品推荐

