CNN笔记(CS231N)——训练神经网络II(Training Neural Networks, Part 2)

训练神经网络

我们接着上一讲继续,这一讲主要讲的是优化、正则化与迁移学习

高级优化

我们首先来看看传统的随机梯度优化有什么问题,如果损失函数在一个维度上梯度比较小,在另一个维度上梯度比较大,那么这种情况下就会出现沿着梯度小的维度变化缓慢,另一个方向变化迅速,出现如下图这种震荡现象导致收敛缓慢

除此以外就是局部最小值与驻点的问题,局部最小值在多维特征的情况下出现的几率比较小,最常见的是驻点问题,这种情况下权重的梯度为0导致权重无法更新

在采用随机梯度更新的时候由于损失函数是在一个批内计算的,因此损失函数不一定完全朝全局最小值进行衍进,而可以看在是在朝全局最小值衍进的曲线上叠加了噪声

一种解决方案是采用Momentum的方案,Momentum是物理中的动量,可以看做是引入了速度这个概念,意思是权重的变化量不仅与当前的梯度有关,还与之前的变化量有关(将此看做速度)

这样可以解决以上提到的三个问题,对于驻点来说,由于当前变化量等于之前的变化量乘以ρ加上梯度,虽然当前梯度为0,但是之前变化量不是0,因此当前权重仍会改变。而第二个震荡的问题我觉得下图的图例不是很准确,因此找了另外一个专栏的图,因为这种情况下梯度和上一时刻变化量相反,因此会有一定的补偿效果,但不能完全消除震荡现象。第三个噪声的问题也相应的会有改善

我们讲的Momentum实际上是将当前时刻的梯度与上一时刻的速度作为向量相加作为当前变化量,而另一种方法叫做Nesterov Momentum,实践证明有更好的效果。这种方法是在本时刻先加上上一时刻的速度,计算变化后的点的梯度,再加上负梯度的值作为本时刻的变化量

说起来很复杂,看下面公式就比较清楚了,但基本思路就是加上上一时刻的速度后再求梯度来对改变量进行修正,已获得更好的收敛效果

以下是三种方法实践过程中的对比

第二种方法是AdaGrad,这种方法是给梯度加一个尺度变换因子,这个因子与之前梯度的平方有关,因此这种情况下梯度小的分母小,因此变化量大;反之,梯度大的变化量小。这样也能解决之前提到的都抖动问题

但是这种方法有个问题,就是随着时间变长,这个分母的值越来越大,导致权重变化量过小,收敛缓慢

为了对这个问题进行改进,又有RMSProp方法,它的思路跟之前的Momentum有些类似,将权重因子的计算公式改为与之前的权重因子与当前的导数平方有关,这种方法能够让权重改变量不会下降那么快

我们以上提到了两种思路,一种是给变化量加上之前的速度,一种是将变化量除以权重因子,那么我们为什么不将这两种方案结合起来呢?这就是Adam优化方法,也是我们最常用的优化方法之一,他把以上两种方法都结合了起来。另外,当最开始的时候偏移量为0,由于beta的值非常大,那么下一时刻的偏移量就会接近最开始的偏移量,也就是接近于0,导致刚开始的时候变化缓慢,为了解决这个问题我们加了一个偏移矫正,对刚开始时刻的两项进行矫正

以下是这几种方案的对比

学习速率

这几种方法都需要将学习速率作为混合参数,因此我们也要注意学习速率的选择。随着代价函数逐步毕竟全局最小值,我们需要相应减小我们的学习速率,保证步长减小,来做更精细的调整

我们经常看到以下这样的损失函数变化曲线,这种情况就是学习速率采用了step decay,学习速率下降使得损失函数能够进一步调整

我们之前做的求梯度作为变化量实际上是一阶优化

在实践过程中我们还可以采用二阶优化来对函数进行更好的逼近

这种方案的好处是我们不需要学习速率这么一个参数来进行步长调整,但是它需要我们求出黑塞矩阵,加大了计算量,因此我们在实践中很少使用这种方法

这种方案还有其它的一些改进

有的方法在一些场景下也有应用,我们在full batch的时候有的时候也会尝试L-BFGS方法

模型整合

为了取得更好的效果,很多时候我们会对一个问题训练很多不同的模型,在测试的时候将他们的结果平均来提升表现。不同的模型可以是不同的混合参数,也能是不同的网络结构等等

一些前沿的论文证明了我们保存在训练过程中同一网络的不同副本,最后将这几种副本整合起来也能获得更好的效果

正则化

我们之前讲过为了防止过拟合,我们可以采用正则化的方案,比如L1正则、L2正则。还有一种比较常用的方法是dropout,这种方法的思路很简单,就是在每次前向传播的时候都人为随机地把网络中的神经元置0

这种方法实现起来也非常简单

这种方法为什么是一个好想法呢?我们可以认为dropout是不同模型的大集合,每次前项传播的路径都是不同的。

并且从另外一个角度理解,它使得输出是所有输出特征的加权平均,而阻止模型对某个神经元输出的过分依赖

但是采用这种方法我们需要注意我们在训练的时候是将神经元随机置0,那我们测试的时候显然不能这么做,因为这么做会导致对于同一个输入,每次的测试结果都是不同的,这显然不是我们想要的,我们想要的是将这种随机性平均掉

我们看以下这个例子,我们在进行dropout的时候有四种可能的情况,而我们将这四种情况平均下来得出的结果跟利用全部神经元得出的结果只差一个系数。由此我们可以通过将输出乘以dropout的概率,来得到一个dropout平均的结果

以下是实践中采用的代码

这种情况下我们在测试的时候需要进行额外的乘法计算,会减慢我们的测试速度,因此我们可以采用在训练的时候除以dropout概率来达到相同的效果

以下是正则化的一个常用的模式,也就是在训练的时候引入某种随机性,防止模型对训练集过拟合,再在输出的时候来平均掉这种随机性,从这个角度来看批归一化也是一种正则化的方法,因为它用了随机的minibatch进行网络的训练,然后用了固定的网络结构与权重进行测试

另一种正则化的方案是数据增强

也就是通过翻转、剪切、尺度变化等方法将原图变为很多不同的图片,算是对训练集的一个扩展,增强了模型的普适性

以下是数据增强的常用方法

除此以外还有dropconnect方法与druoout类似

还有fractional max pooling,在池化的时候采用不同的采样窗口大小引入一定的随机性

以下就是对正则化方案的一个总结。最后一种方式是随机深度,也就是随机采用不同的网络层进行训练

迁移学习

我们知道机器学习最重要的就是数据,有的时候数据量大远远比一个网络结构好更重要,那么当我们来到一个新问题上,无法得到这么多数据的时候应该怎么做呢?我们常常采用迁移学习的方法,迁移学习是将在另一个问题上(这个问题往往有很大的训练集)的网络搬移到新的问题上来,再利用这个问题的数据集对网络结构进行精细调整

举一个例子,如果我们在Imgenet上训练了一个对1000钟物体分类的网络,此时我们需要对狗的品种进行特别的分类,那么我们可以做的就是直接将网络结构搬过来,前面的网络结构不变,将最后全连接层的权重全部重新训练,来得到我们的新网络,这种方法在实践中取得了很好的效果,因为我们可以理解为网络浅层学习到的低级特征我们可以利用起来,而在深层网络才对高阶特征进行判断分类,因此我们需要训练网络分辨不同品种的狗只需要改变网络后几层就可以了。如果我们有更多的训练数据,我们也可以多将一些网络层进行重训练来获得更好的效果

一下是在数据集相似性与数据量这两个维度下我们针对不同的情况应该采取的方案

现在的网络框架已经集成了很多现有的网络结构来供我们进行迁移学习

猜你喜欢

转载自blog.csdn.net/shanwenkang/article/details/86726722