- 简介
- Data Argumentation
- Pre-Processing
- 网络初始化(Initialization)
- 训练过程中的Tips
- 激活函数s
- Regularization
- 来自图例的直观
- 神经网络的融合
- 数据不均衡
文章题目: Must Know Tips/Tricks in Deep Neural Networks
简介
本文是Lambda实验室魏秀参写的关于深度神经网络训练技巧,非常齐全。我对它进行了整理。
Data Argumentation
一般来说用扭曲数据的方法进行数据增广是可行的。如果数据库只有少量的图片的时候,数据增广是增加表现的理想手段。
一般来说可以用水平翻转,随机采样等技术进行。作则还说了一个非常有用的fancy PCA方法
Pre-Processing
几个有效的手段:
- 数据中心化
- 数据正则化
一般图片需要用到中心化思想。
网络初始化(Initialization)
全零初始化的坏处
理论上因为输入是一个对称的初始化操作,那么是否可以给神经网络全0初始化呢?当然不可以。因为全0了之后相当于后面几层神经网络接受了相同的输入(反正前面都是0)。或者说如果神经网络的参数都一样的话,那么第一层的输出是参数对输入的乘积,第一层输出全部相同,第二层输出也全部相同,这样神经网络所有参数梯度都一样,这样就没办法改变了。
随机小数字初始化的
一般用期望为0的分布初始化。用$weights-0.001\times N(0,1)$进行初始化和$[-1,1]$的均匀分布基本差不多。
###Xavier
为了保证输入与输出的方差都是一样的,因此对权重进行了操作。
如果初始化参数太小,那么输入信号在每一个单元里就会收缩,以至于最后没有了。如果初始化参数太大,那么信号就会在每一个layer内迅速爆炸,使得最后的输出非常混乱。使用Xavier初始化,能够让权重不太大,也不太小。
其本质就是让输入X与输出Y的方差一致。最后得到的一个结果是权重应该以0为均值,然后方差为$Var(W_i)=\frac{2}{n_{in}+n_{out}}$
据说这个初始化是可以无脑用的?我可以在如果网络跑了好多次然后仍然不收敛的时候用。
一般推荐
一般使用正态分布,然后参数$\times \sqrt{2/n}$ 来进行初始化,无脑xavier
训练过程中的Tips
过滤器尺寸与池化尺寸
一般输入图片尺寸是2的幂次大小,一般是64或者32的2,4,6,8倍。
过滤器无脑选3*3,步长为1,0填充。因为这个可以保留图片的大部分特征
池化一般情况下选2*2
学习率
一个大神的建议是用batch size来除梯度,而学习率保持不变(如果变了batch size的话),这个建议是增大batch size 或者减小的时候的建议,非常有用。
一般来说用test set来检验学习率是最有用的。如果验证集上loss不再降低,可以把学习率除2,再除2直到降低为止。
一般初始学习率选0.1。(一般选1e-3比较有用)
在预训练模型上微调
现在很多图像处理网络都给了参数,这种参数可以进行预训练。
假如我们的数据集很小,而我们用的预训练网络数据集特征与我们的很像,我们只需要在网络后面加几个小层,改变这些参数就可以了,网络参数不变。
假设我们的数据很多,且与预训练的网络很像,那么我们需要用很小的学习率去训练网络一开始的几层就可以了,因为后面几层都已经把特征高度抽象化了。
假设我们的数据很多,与预训练网络不像,那么我们直接训练整个网络,但是学习率很小就可以了。
假设我们的数据很小与预训练也不像,不要用预训练的网络。
激活函数s
按Deep Learning一书中所言,所谓的激活函数就是为神经网络增加非线性性的一个关键而重要的东西。文章对比了Sigmoid
,tanh
,ReLU
,Leaky ReLU
,Parametric ReLu
,以及Randomized ReLU
的区别并给出了对比。
Sigmoid
Sigmoid函数我们都知道,它的好处在于模拟了网络不激活(0)与网络全饱和激活(1)的关系。它的缺陷在于它会导致梯度消失,也就是说杀死了梯度,这就意味着神经网络的参数不能过大,因为过大的参数意味着特别小的梯度,也就是参数一旦大起来就小不了了。
同时,如果我们的输入被限制在[-1,1]之间,这意味着神经网络参数也应该被限制在0附近,但是sigmoid函数并不是一个好的函数.
tanh(x)
tanh函数除了把范围弄到了zero附近以外也没解决梯度饱和的问题。
ReLU
为了解决以上问题,ReLU函数凭空出现了。ReLU的好处是计算方便(没有指数计算,计算量少了好几个量级),同时ReLU不会面临梯度饱和的问题。同时ReLU在SGD方法下收敛得非常非常快。
但是ReLU也有缺陷,它可能会使神经网络的一部分处于”死亡”的状态。比如如果有一个很大的梯度使得神经网络的权重更新很大,最终导致这个神经元对于所有的输入都给出了一个负值,也就是说输出为0了。这个时候流过这个神经元的梯度就永远会变成0形式,也就是说不可逆转地,这个神经元”死去”了。如果我们的学习率设置不当,这个很可能发生。
### Leaky ReLU
为了防止这个事情的发生,出现了leaky relu。它定义为 \(f(x)=\begin{cases} x&\text{if x > 0},\\ \alpha *x&\text{if x<0}. \end{cases} \alpha \leq 0.001\)
PReLU
对于PReLU而言,参数$\alpha$是可以学习的,有梯度的,我们可以直接对它求导学习。
RReLU
对于RReLU而言,每一个数据xi的$\alpha$都是不一样的,随机给出的,而test阶段取它的期望。
作者给出了这几种激活函数在Cifar与NDSB数据集上的测试,大概结论就是Leaky ReLU, PReLU,RReLU更好一些,后两者尤其好,可以无脑用。
Regularization
正则化是为了防止过拟合的。
L2正则化
L2正则化显然是对大权重的一种惩罚
L1正则化
L1正则化一般与L2同时使用,L1正则化迫使参数变得稀疏(比L2有效),一般L1正则化对噪声较大的数据有用,可以过滤数据抓重点。
最大范数正则化
对每一个权重规定一个上界
Dropout
最有效的方法,相当于对神经网络进行了重采样。一般Dropout的p可以设置为0.5。
来自图例的直观
关于Learning Rate,如何判断你当前选取的Learning Rate是一个健康的数字呢?作者分为了4类。
过高的learning rate会让loss直接疯涨上去,过低的learning rate会让loss慢慢跌下去,而中高的learning rate会让loss一开始飞速下降,然后陷入局部极小值。可以通过看图来调试learning rate。
关于loss一般是一个非常震荡的图像。如果说这个图像不震荡,一直向下这说明learning rate比较低,如果发现曲线震荡的上下界,也就是width变大了,那么这说明batch的方差很大,这就需要增大batch size。
如何判断over fitiing:
如果在验证集上的loss(或者说VoE)与训练集上的loss(VOE)相差得越来越大的话,也就是两条曲线的gap越来越大这就说明出现了过拟合。
神经网络的融合
融合好几个网络可以获得更好的结果,这是一个公认的事实。一般来说好的比赛都是通过融合多个神经网络来得到的,而如果我们训练时间有限的话,融合多个神经网络也是一个好的方面。那么如何融合呢?有以下几个办法
-
相同的模型,不同的初始化
采用验证集来获取好的超参数,用这个给定的超参数来进行初始化。
-
选取超参数后,直接把训练过程中的少数几个好的模型来融合为ensemble。也就是说直接选训练阶段的模型做ensemble,这个会导致纳入了非最佳模型。
-
如果训练很花时间,那么可以尝试在每个epoch后选模型的几个检验点(这里没有理解),然后用这些进行ensemble,它的特点是便宜。
-
直接用不同的数据集训练,然后ensemble
作者在挑战ICCV 2015的时候,利用了分别在image of imagenet,Place Database,以及挑战的数据集分别训练了5个模型,然后把5个模型的深层输入作为5个特征,看作多维数据。最后作者融合了 early fusion与late fusion得到了第二名。
数据不均衡
类不均衡问题很重要。类不均衡问题会导致严重的负面影响(对于整体表现来说)。简单地降采样,增采样当然是一个好办法,这里提出的一个解决方案是随机crop[7],或者我们可以采用微调的策略。我们可以把我们的数据集分为2个部分,第一个部分是类别充足的部分,第二个部分是类别不充足的。在每个数据集上类别不均衡问题都不严重。在微调的过程中,我们可以先对那些类别充足的数据集进行微调,然后继续再在不充足的数据集上微调。