loss收敛过小或finetune时跑飞情况分析

在使用L2 Loss训练REDNet去噪网络时,发现在归一化0-1的输入下,loss先下降后上升,最终收敛值低于预期。可能原因包括学习率设置过大、训练数据偏差及梯度更新问题。分析指出,学习率过大可能导致loss跑飞,而网络在0-1输入下中间层几乎没有学习,表现为残差的均值差异显著。通过对梯度和残差的观察,确认了输入尺度和学习率设置对网络学习效果的影响。
摘要由CSDN通过智能技术生成

   最近在跑REDNet去噪网络,基于pytorch框架,输入输出图像被归一化到了0-1之间,loss使用的是L2 loss,理论最终收敛值为33左右。结果在之前训练好模型的基础上finetune,出现了这种情况:



   当使用L1或者输入为0-255时,并没有出现这种情况。这里使用L2 loss,输入0-1之间,loss先下降,再上升,这是很反常的,一般来说有以下问题导致:
1.学习率设置不正确。
2.训练数据出现了偏差。
3.梯度更新出现问题,爆炸或者消失。

   这里后来经过分析,很可能是学习率设置导致,当然梯度更新不正确也有影响,学习率设置不正确分析如下:



   也就是说,学习率如果设置过大,会导致其直接跑到另外一边,从而导致loss跑飞。当然真实的loss变化是在一个奇异空间里的,不是图上的那种二维曲线。
   但是最后还发现了一个现象,那就是最后的网络的收敛值只有30出头,而不是理论的33.多,也就是说网络学习不充分!如下图所示:



   网络学习不充分,前面finetune的loss还跑飞了一段,很可能网络的梯度更新出现了问题,需要打印网络的每层梯度进行查看,代码如下所示:

self.optimizer.step()
for params in self.net.named_parameters():
    [name,param] = params
    print(name,':',param.grad.data.mean())
    print(count)

   迭代2000次,打印出来梯度值就是下图左图这个样子,右图是数据归一化到0-255之间时各层的梯度值:



   上图的现象说明了当数据归一化到0-1之间时,该网络的中间部分几乎没有学习,参数缺少更新,为了验证这个想法,我分别输出迭代2000次时0-1输入时该网络的残差的均值和输入0-255时网络的残差的均值,分别为2.5x10^-3和0.26,差了两个数量级,验证了猜想,即输入为0-1时网络基本没有学到东西。
   由于网络的残差是在deconv10层,直接获得该层输出的代码(不通过参数返回的方式)如下所示:

activation = {}
def get_activation(name):
def hook(model, input, output):
    activation[name] = output.detach()
    return hook
model = self.net
model.deconv10.register_forward_hook(get_activation('deconv10'))
output = model(lr_imgs)
print('res:', activation['deconv10'].mean())

   现在通过结论寻找原因,当输出为output,网络权重为w,损失函数为L2 loss,目标为target,分析loss对权重更新也就是梯度的影响,如下式所示:

(outp
  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值