一、Recipe of Deep Learning
DL训练完后,要先在训练集上测试,如果训练集的测试结果不好,就要回去进行修改。如果在训练集上的测试结果较好,那么再去测试集上测试效果。如果结果不好的话,是overfitting,这个时候要解决过拟合的问题。
不要看到训练结果就认为是overfitting,如果都按照是overfitting去直接通过调整model的话,你的model的效果可能会更差。
下面这个例子,就不是overfitting的问题。
看到这个图,56层的神经网络效果还不如20层的,是不是感觉56层的神经网络过拟合了呢?其实不然,看下图,model在训练模型上的测试结果同样不如20层的model。
为什么会出现56层不如20层呢?
这是因为56层model因为某种原因训练的不好(可能卡在了局部最低点,或遇到鞍点等),需要重新调整,再次训练。这也不是underfitting,因为可以认为56层网络中前20层把20层网络的功能实现了,后面的层没用,并不是层数不够。
所以,在做DL时,一定要搞清训练到底是遇到了什么问题。这里主要是从测试集和训练集的角度考虑,确定问题后,再采取相应的解决办法。例如:dropout,只有在测试集上效果很差时,才会使用;如果在训练集的效果很差,强行使用dropout只会让效果变得更差。
神经网络的layer越多,效果不一定越好。例如:
是不是有人看完这个图之后,感觉9层、10层的时候参数太多,导致overfitting了。NO!!!上面刚说了,这是在训练集上的测试结果就坏掉了。我们可以试着分析一下原因:
一个原因是这样的:梯度消失。在靠近output的地方梯度较大,靠近input的地方梯度较小。这就导致:靠近output的地方参数更新快,靠近input的地方参数更新慢,在浅层还在随机状态时,深层就已经收敛。这样就很容易陷在局部最小。
我们可以再进一步分析一下产中这种现象的原因:sigmoid激活函数。
当input很大时,微分值反而会变小,每经过一次sigmoid函数,对loss的影响越小,这样神经网络越深,最终对loss的影响越小。
1.New Activation function
怎样解决这种问题呢?
一个方法就是使用新的激活函数。普遍使用ReLU函数。
使用ReLU作为激活函数,某些weight为0的neuron就可以删除,这样就简化了network。
这不就退化为Linear Function了吗?那还称Deep Learning?
实际上,network整体来看还是非线性的。当每一个neuron参数的改变量一样时,network是线性的;但是当参数的改变量不同时,仍然是非线性的。
这里,还有另外一个问题:ReLU函数在0处不可微。
在0点处的可微问题可以忽略不计。小于零的域中,微分值等于0;大于零的域中,微分值等于1。而在训练的过程中,参数的改变量不会为0(如果没有改变,就不需要再训练了)。
还有几个ReLU的变形:
规定好的α=0.01的ReLU。 α可训练的ReLU。
还有可自我学习的激活函数:Maxout。
ReLU是特殊的Maxout。
与常规激活函数不同的是,它是一个可学习的分段线性函数。
*Maxout网络中的激活函数可以是任何分段线性凸函数。
*Maxout函数有多少段取决于一组中有几个元素(如何分组是自己定的)。
Maxout不能微分,那怎么训练呢?
Maxout是选择最大值,那么针对最大值时,其实就是个线性函数。其实也就是训练一个细长的Linear network。
这个产生另一个问题,没被训练到的neuron怎么办?
因为我们的输入足够多,对于不同的输入,得到的细长的Linear network也是不同的,因此,到最后每个神经元还是都可以被训练到的。
2.Adaptive Learning Rate
先回顾一眼Adagrad
Adagrad的loss函数很简单,有时候会卡在极值点或者鞍点。
【注】有人认为,较大的network遇到局部最小的概率很小。
一个改进后的方法叫RMSProp。
下面是RMSProp的计算过程。
为了解决卡在某点,可以加入“惯性”。
当计算梯度的时候,将上一次的梯度也考虑在内。