使用tensorflow训练模型时可能出现nan的几种情况
最近在做基于MTCNN的人脸识别和检测的项目,在训练模型的过程中总是会不定时地出现损失值为nan的情况,Debug了好久终于找到了问题所在,这里总结以下可能出现nan的几种情况:
1、在分类问题中,我们经常使用到交叉熵损失函数,需要注意的是:由于交叉熵损失函数里有对数计算,因此对数的真数部分不能为0,所以我们在计算计算交叉熵时需要给这个真数部分限定一个范围,否则会出现数值下溢的问题,我们可以采取的办法是使用tf.clip_by_value(input,min_value,max_value)函数来限定真数的下限;
2、另一种情况是在训练开始时后出现损失函数值为nan,这种情况一般是由于学习率太大,我们需要减小学习率;或者是在训练一段时间后出现nan,这种情况可能是由于梯度爆炸导致的,一种典型的情况是在训练RNN的过程中会出现梯度爆炸,我们可以对梯度进行裁剪,将梯度的最大值限定在某个常数;
3、还有一种就比较奇葩了,就是我遇到的情况,准确地讲这是一个bug,我在计算一个批次的损失时使用了tf.reduce_mean()这个函数,在将tensor丢进这个函数之前,tensor是根据一个索引筛选过的,问题来了:要是这个经过选择的tensor为空会出现什么情况?我特意将这个情况实验了以下,结果发现:这种情况下返回的就是nan。果断使用tf.reduce_sum(),与前面不同的是此时计算出来的损失会是原来的倍数,将代码修改之后,这个bug终于被解决掉了。