神经网络模型、loss不收敛、不下降原因和解决办法

一、模型不收敛

主要有以下几个原因:

1、learning rate设大了会带来跑飞(loss突然一直很大)的问题
     这个是新手最常见的情况——为啥网络跑着跑着看着要收敛了结果突然飞了呢?可能性最大的原因是你用了relu作为激活函数的同时使用了softmax或者带有exp的函数做分类层的loss函数。当某一次训练传到最后一层的时候,某一节点激活过度(比如100),那么exp(100)=Inf,发生溢出,bp后所有的weight会变成NAN,然后从此之后weight就会一直保持NAN,于是loss就飞起来辣。我的depth estimation相关项目的loss曲线,如下:

神经网络模型、loss不收敛、不下降原因和解决办法_第1张图片

可以看出跑飞了,(幸lr设的并不是非常大所以又拉了回来)。如果lr设的过大会出现跑飞再也回不来的情况。这时候你停一下随便挑一个层的weights看一看,很有可能都是NAN了。对于这种情况建议用二分法尝试。0.1~0.0001.不同模型不同任务最优的lr都不一样。

2、数据库太小一般不会带来不收敛的问题
只要你一直在train总会收敛(rp问题跑飞了不算)。反而不收敛一般是由于样本的信息量太大导致网络不足以fit住整个样本空间。样本少只可能带来过拟合的问题,你看下你的training set上的loss收敛了吗?如果只是validate set上不收敛那就说明overfitting了,这时候就要考虑各种anti-overfit的trick了,比如dropout,SGD,增大minibatch的数量,减少fc层的节点数量,momentum,finetune等。

3、尽量用小模型
如果数据太少尽量缩小模型复杂度。考虑减少层数或者减少kernel number。

二、模型loss 不下降

train loss与test loss结果分析

train loss 不断下降,test loss不断下降,说明网络仍在学习;
train loss 不断下降,test loss趋于不变,说明网络过拟合;
train loss 趋于不变,test loss不断下降,说明数据集100%有问题;
train loss 趋于不变,test loss趋于不变,说明学习遇到瓶颈,需要减小学习率或批量数目;
train loss 不断上升,test loss不断上升,说明网络结构设计不当,训练超参数设置不当,数据集经过清洗等问题。

相关链接:以下两个链接必须看一下

参考链接1:神经网络训练与注意点

参考链接2:Loss和神经网络训练

 

二、Loss 函数不收敛

下面,这段在使用caffe的时候遇到了两个问题都是在训练的过程中loss基本保持常数值,特此记录一下。

1、loss等于87.33不变

loss等于87.33这个问题是在对Inception-V3网络不管是fine-tuning还是train的时候遇到的,无论网络迭代多少次,网络的loss一直保持恒定。

查阅相关资料以后发现是由于loss的最大值由FLT_MIN计算得到,FLT_MIN是1.17549435e−38F​1.17549435e−38F​其对应的自然对数正好是-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由两部分计算得到:一部分是输入数据,另一部分是各层的权值等组成

  1. 减小初始化权重,以使得softmax的输入feature处于一个比较小的范围

  2. 降低学习率,这样可以减小权重的波动范围

  3. 如果有BN(batch normalization)层,finetune时最好不要冻结BN的参数,否则数据分布不一致时很容易使输出值变得很大(注意将batch_norm_param中的use_global_stats设置为false )。

  4. 观察数据中是否有异常样本或异常label导致数据读取异常

  5. 本文遇到的情况采用降低学习率的方法,learning rate设置为0.01或者原来loss的1/51/5或者1/101/10。

2、loss保持0.69左右

采用VGG-16在做一个二分类问题,所以计算loss时等价与下面的公式:

当p=0.5时,loss正好为0.693147,也就是训练过程中,无论如何调节网络都不收敛。最初的网络配置文件卷积层的参数如下所示:

 

从VGG-16训练好的模型进行fine-tuning也不发生改变,当在网络中加入初始化参数和decay_mult以后再次训练网络开始收敛。
但是具体是什么原因造成的,暂时还没有找到,难道是初始化参数的问题还是?

总结

训练网络的时候loss一直居高不下或者准确度时高时低,震荡趋势,一会到11,一会又0.1,不收敛

首先你要保证训练的次数够多,不要以为一百两百次就会一直loss下降或者准确率一直提高,会有一点震荡的。只要总体收敛就行。若训练次数够多(一般上千次,上万次,或者几十个epoch)没收敛,则试试下面方法:

1、数据和标签

数据分类标注是否准确?数据是否干净?数据的输入是否正常,data和label是否一致?数据库太小一般不会带来不收敛的问题,只要你一直在train总会收敛(rp问题跑飞了不算)。反而不收敛一般是由于样本的信息量太大导致网络不足以fit住整个样本空间。样本少只可能带来过拟合的问题

2、学习率设定不合理

在自己训练新网络时,可以从0.1开始尝试,如果loss不下降的意思,那就降低,除以10,用0.01尝试,一般来说0.01会收敛,不行的话就用0.001. 学习率设置过大,很容易震荡。不过刚刚开始不建议把学习率设置过小,尤其是在训练的开始阶段。在开始阶段我们不能把学习率设置的太低否则loss不会收敛。我的做法是逐渐尝试,从0.1,0.08,0.06,0.05 ......逐渐减小直到正常为止,

有的时候候学习率太低走不出低估,把冲量提高也是一种方法,适当提高mini-batch值,使其波动不大。,

 3、网络设定不合理

网络架构的选择,一般是越深越好,也分数据集。 并且用不用在大数据集上pre-train的参数也很重要的。如果做很复杂的分类任务,却只用了很浅的网络,可能会导致训练难以收敛,换网络换网络换网络,重要的事情说三遍,或者也可以尝试加深当前网络。

4、数据集label的设置

检查lable是否有错,有的时候图像类别的label设置成1,2,3正确设置应该为0,1,2。

5、数据归一化

神经网络中对数据进行归一化是不可忽略的步骤,网络能不能正常工作,还得看你有没有做归一化,一般来讲,归一化就是减去数据平均值除以标准差,通常是针对每个输入和输出特征进行归一化

 

 

你可能感兴趣的:(AI之路,-,Face)