loss等于87.33这个问题是在对Inception-V3网络不管是fine-tuning还是train的时候遇到的,无论网络迭代多少次,网络的loss一直保持恒定。
查阅相关资料以后发现是由于loss的最大值由FLT_MIN计算得到,FLT_MIN是其对应的自然对数正好是-87.3356
,这也就对应上了loss保持87.3356了。
这说明softmax在计算的过程中得到了概率值出现了零,由于softmax是用指数函数计算的,指数函数的值都是大于0的,所以应该是计算过程中出现了float溢出的异常,也就是出现了inf,nan等异常值导致softmax输出为0.
当softmax之前的feature值过大时,由于softmax先求指数,会超出float的数据范围,成为inf。inf与其他任何数值的和都是inf,softmax在做除法时任何正常范围的数值除以inf都会变成0.然后求loss就出现了87.3356的情况。
解决办法
由于softmax输入的feature由两部分计算得到:一部分是输入数据,另一部分是各层的权值等组成
-
减小初始化权重,以使得softmax的输入feature处于一个比较小的范围
-
降低学习率,这样可以减小权重的波动范围
-
如果有BN(batch normalization)层,finetune时最好不要冻结BN的参数,否则数据分布不一致时很容易使输出值变得很大(注意将
batch_norm_param
中的use_global_stats
设置为false
)。 -
观察数据中是否有异常样本或异常label导致数据读取异常
本文遇到的情况采用降低学习率的方法,learning rate设置为0.01或者原来loss的或者。
可以在solver里面设置:
debug_info: true
看看各个层的data和diff是什么值,一般这个时候那些值不是NAN(无效数字)就是INF(无穷大),
一般的解决办法是:
1、检查数据的标签是否从0开始且连续
2、把学习率base_lr调低
3、数据问题
4、中间层没有归一化,导致经过几层后,输出的值已经很小了,这个时候再计算梯度就比较尴尬了,
这也是我遇到的问题,所以我再各个卷积层加入了BN层和SCALE层,不过FC层没有必要加吧?
5、把base_lr调低,然后batchsize也调高
6、把data层的输入图片进行归一化,就是从0-255归一化到0-1,使用的参数是:
-
transform_param {
-
scale: 0.00390625//像素归一化,1/255
-
}
7、网络参数太多,网络太深,删掉几层看看,可能因为数据少,需要减少中间层的num_output
8、记得要shuffle数据,否则数据不够随机,几个batch之间的数据差异很小,一旦连续几个batch把loss调很小,然后就。。。 现在不造解释,
上述博文内容中,第5和第8条引起我的注意:
-
5、把base_lr调低,然后batchsize也调高
-
8、记得要shuffle数据,否则数据不够随机,几个batch之间的数据差异很小,一旦连续几个batch把loss调很小,然后就。。。 现在不造解释,
虽然不太知道为什么,但是这改变了我的一个想法,数据层中的batch_size其实与训练过程是有关的。它的改变会引起accuracy或者loss的改变。
小编的batch_size 因为问题1的出现被小编严重调低,将batch_size设为了1 。为了调高batch_size,只能缩小图像,所以小编使用crop_size对图像进行裁剪,这时奇迹发生了,小编的loss值再没上来过。
所以,如果你的loss值一直loss=87.3365恒不变,你又找不到其他的原因,那你请试试提高你的batch_size.小编最后train部分的batch_size值增加到了20.