当我们编程实现了神经网络模型,将模型用于测试集时,经常会发现测试的准确率非常的低,神经网络层数很深,通常我们不容易判断具体的梯度下降求解参数的过程,那我们该怎么办呢?从机器学习视频中总结的办法!!小程序亲身体验过!
首先要明白,测试集上的准确率低并不一定是过拟合。有可能在训练集上准确率就很低,也就是说你的模型压根没有训练好!!
所以:首先,要用训练好的模型在训练集上跑一遍,如果在训练集上准确率就很低,那么就不是过拟合,而是欠拟合。
原因是在梯度下降求导时,卡在了local minima(在求导为0,是极小值),saddle point(求导为0,不是极小值),plateau(求导近似为0)上。
解决这个问题可以有两个做法:1是改变激活函数;2是改变梯度下降求导方式;后边会详细讲。
然后:如果在训练集上准确率很好,在测试集上准确率低,那么就是过拟合(overfitting)。
解决办法是:1是早点停止梯度更新;2是更多的数据(通过数据增强获得更多数据);3是正则化(l1-torm和l2-torm);4是Dropout方法。下边将详细介绍。
解决欠拟合的1方法:改变激活函数。一定程度上,欠拟合是因为激活函数选择了sigmoid函数。对于sigmoid函数来说,致命的问题就是梯度消失,sigmoid会衰减输入。梯度消失的含义是:在靠近输出层的参数更新梯度很大,在靠近输入层的参数更新梯度很小,导致在学习率一致的情况下,在靠近输出层的后几层参数更新快,在已经收敛的时候,靠近输入层参数更新很慢,还是接近随机状态,使得靠近输出层参数接收的input接近随机。
我们换用RELU激活函数就可以解决梯度消失的问题。在input<0时,output = 0, 在input>0时,output = input,这样在计算时,参数会少于整体神经元个数,RELU计算很快。Leaky RELU、Parametric RELU等是RELU的变种,用RELU可以解决一般欠拟合。
另外maxout也是一种激活函数,RELU是maxout的一种特例,它可以实现每个神经元都有自己不同的激活函数,但是maxout参数多于其他激活函数(因为每有一个输出,都要在一组给定数目的输出(参数)中选择一个最大的作为输出,而其他的激活函数,都是给一组参数,产生一个输出)。虽然参数变多了,但是在训练时,我们梯度下降只更新一组输出中选出的那个输出对应的参数!!!!并且训练集数据很多,每个数据都会梯度更新不同的参数。maxout是根据数据自动学习权重,模型参数训练好了,模型固定了,也就得到不同的激活函数。
解决欠拟合方法2:改变梯度下降策略;
可以尝试其他的梯度下降函数,比如Adagrad、RMSProp、Momentum、Adam(=Momentum RMSProp),它们按照一定权重考虑了新梯度值和旧梯度值。