关于这个问题全网上也没有多少博客出现这种问题的,所以能够出现这种问题也不知道是我的幸运还是不幸。在我跑数据集的过程中,就出现了这种情况,可能前一个epoch还没有这种问题,下一个epoch就会有这种情况出现。可能上一个epoch出现的是全0,下一个epoch出现的就是全1的情况,就如下图所示。
测试数据集标签全为1
测试数据集标签全为0
针对这种情况,只能一步步的排查。后来发现不仅测试数据集,甚至连训练数据集都是这样的情况。发现在某一个卷积层之后,进行了linear线性变换,经过线性变换后的结果就是一列为正一列为负,所以这个时候预测出来的结果就全是为正的列所在的索引。
解决办法:
- 设置不同的学习率,0.1,0.01和0.001等
- 设置不同的batch_size
检查步骤:
- 从权重开始检查,发现学习率为0.1的时候,第一个epoch的模型权重就已经很小很小了,目前猜测是学习率太大,导致权重降的很快,现在从0.0000001开始试。
- 和师姐的baseline代码对比,发现我没有进行RandomOverSampler。任务是2分类,数据集是不平衡的,label数量是1:3。所谓over-sampling,我们可以理解为将少的一部分样本进行重采样,使其变多。(这里重采样的方式会有很多) 比如说trainset有9924张,标签为1的有7583张,标签为0的有2341张,它会把标签为1的扩充到7583张,使得整个数据集有15166张。
- 进行了数据集平衡后,尴尬的事发生了,train accuray 和 test accuracy都为0.5,网络输出的标签都是1,说明了不是数据集样本不平衡的问题。猜测是初始化权重的问题,如果一个神经网络层的权重非常小,那么在反向传播算法就会计算出很小的梯度(因为梯度gradient是与权重成正比的)。
- 接下来查看了第1个epoch和第27个epoch模型的权重参数,发现参数是更新了的,说明模型的梯度没有消失。
- 检查图像的输入,每个batch的图像会不会是同一张图像,经检查发现图像加载没有问题。而且所有的图像也都经过了归一化处理。
总结:
试了常见的学习率后,结果仍一点都不变,一定要及时检查更新的权重、梯度。设置BN层归一化。初始化权重尽量不要太小,导致梯度消失。不平衡的数据集也要进行平衡。
参考链接1:https://blog.csdn.net/weixin_38314865/article/details/106174761
参考链接2:https://blog.csdn.net/qq_42037837/article/details/105741945