简介
最近又开始使用 Pytorch 进行训练了,但是遇见了不少问题,主要问题集中在 loss 不收敛上,本章节就此问题进行探讨,由于是一遍码代码一遍写文章,本文最后不一定会给出解答,但会记录我寻找答案的经历和过程。
1. 经典的 Cross Entropy 问题
注意,许多初学者这么使用交叉熵 loss
F.softmax(y)
F.cross_entropy(y, label)
Wrong × 错误的
在别的深度库里这么使用可能正确,但在 torch 中使用是极大的错误,因为在这里 cross_entropy = softmax + log + corss_entropy(一般意义的交叉熵)。所以如果使用交叉熵时注意不要使用 softmax 了,我在犯了如上错误的时候出现 loss 不收敛的问题。
2. 学习率 Learning rate 设定
学习率过大
学习率过大是很严重的问题,我在使用均方误差时设置了过大的学习率,导致甚至无法将一个矩阵通过学习网络拟合目标矩阵。由此可窥见,学习率设置过大,等同于直接寄了
3. 学会查看梯度和结果
在训练网络中发现了结果一直不变的问题,就去输出看看网络参数:
for p in model.parameters():
print(p.grad.data)
4. 数据集大小的问题
这个问题我还在探究中,目前我将一个大数据集(约60+G)挖了一小部分(2G左右)进行训练,暂时不知道会不会导致结果直接不收敛的问题。
正在探究中ing......
5. 梯度消失/梯度爆炸
上图,千万别以为这种情况是正常滴,大大滴错误(前一半的grad为0,后一半的grad正常)
这种情况其实就叫梯度消失,它是影响我们 loss 下降的敌人。还有一种情况相反的状况,梯度不为0,而是nan,这种是梯度爆炸。遇到这种情况,一般 loss 表现为不下降或者直接是 loss=nan了。
总结一下从网上找到的解决方法
5.1 Learning rate 过大
前面提过,这个略过,反正设为 0.001 或者 0.0001 就行
5.2 Batch size 过大
没错,batch size 也可能会对拟合结果造成影响,可以适当调低 batch size
5.3 初始化权重的问题
有人提到,可能是初始化权重更新错误导致,在模型中加入Xavier初始化
for layer in self.modules():
if isinstance(layer, nn.Linear):
nn.init.xavier_normal_(layer.weight)
nn.init.constant_(layer.bias, 0)
5.4 梯度归一化
nn.BatchNorm1d(input_num)
使用 BatchNorm1d 进行归一化,在梯度消失的每层都进行帝都诡异
5.5 数据和label确实出现了问题
这个是我感觉最难找出来的问题了,但实际上很多情况下,这个问题又很容易出现。特别是在数据集和测试集是自己生成、合成的情况下,特别容易出现这种问题。
推荐先排除 5.1 - 5.4,都试试,最后再来看是不是发生了此类问题
6. 一些建模上的问题
!注意!:Batch Norm 和 Layer Norm 应放在激活函数和输出结果之间,BatchNorm适合图像,LayerNorm适合音频和NLP
!!有些模型中需要用的mean或者sum,注意不要放在softmax之后了,不然会出现概率都相同的情况。