前言
最近运行darknet项目,重新划分数据集进行训练,一定迭代次数之后loss数值突然暴增,然后突然变为Nan,之后一直为Nan,与之前训练相比,只有数据集重新划分,其他源码都没有变动。
问题解释
训练过程数据几乎都是nan,查看train log发现迭代到997次时loss突然暴增,之后迭代到1009次的时候avg特别大,再之后就变成nan了。。。
分析
这个loss nan,首先排除代码错误,然后再排除数据错误,最后考虑使用调参技巧。。。
- 脏数据: 检查输入数据是否准确,是否存在nan的坏数据(很重要)
- 计算不合法: 注意分母和Log函数:查看是否除0了, 在经过log操作时,数值不稳定和,log里面的数太小;
如果一开始就是nan,而且是多分类问题,很可能是数据标签出了问题,比如标签超过类别数。
如果用的是成熟的网络,和数据的关系很大,排查一下数据。
如果是自己构建的网络,就要看看有一些变量是不是设置为可求导的。
原因总结
1. 数据集中包含脏数据;计算loss的时候有log0,可能是初始化的问题,也可能是数据的问题;
脏数据一般是指数据的质量非常差,或者label与数据的实际差别很大,使用这些脏数据很可能把模型带偏。
2. 梯度爆炸;
解决方法:
1)数据归一化(减均值、除方差,或者加入normalization,BN,L2 Norm);
2)更新参数初始化方法(xavier/msra);
3)减小学习率、减小batch size;
4)加入gradient clipping;
问题原因
针对博主项目中的这个问题,查看数据集似乎没什么问题,重新训练,和之前的log不一样,没有数值暴增和nan的问题,个人认为是梯度爆炸引起的,这也许和参数初始化有关;
参考
1. 训练深度学习网络时候,出现Nan是什么原因,怎么才能避免?
完