深度学习调优小技巧

转:https://blog.csdn.net/xinyuski/article/details/84400527

1:优化器。机器学习训练的目的在于更新参数,优化目标函数,常见优化器有SGD,Adagrad,Adadelta,Adam,Adamax,Nadam。其中SGD和Adam优化器是最为常用的两种优化器,SGD根据每个batch的数据计算一次局部的估计,最小化代价函数。

学习速率决定了每次步进的大小,因此我们需要选择一个合适的学习速率进行调优。学习速率太大会导致不收敛,速率太小收敛速度慢。因此SGD通常训练时间更长,但是在好的初始化和学习率调度方案的情况下,结果更可靠。

Adam优化器结合了Adagrad善于处理稀疏梯度和RMSprop善于处理非平稳目标的优点,能够自动调整学习速率,收敛速度更快,在复杂网络中表现更优。

https://hanspub.org/journal/PaperInformation.aspx?paperID=27016

(这篇综述是对优化器和调节学习率的方法)

2:学习率(learning rate)

学习率的设置应该随着迭代次数的增加而减小,每迭代完指定次epoch也就是对整个数据过一遍,然后对学习率进行变化,这样能够保证每个样本得到公平的对待。学习速率的设置第一次可以设置大一点的学习率加快收敛,后续慢慢调整;也可以采用动态变化学习速率的方式(比如,每一轮乘以一个衰减系数或者根据损失的变化动态调整学习速率)。

3:dropout。数据第一次跑模型的时候可以不加dropout,后期调优的时候dropout用于防止过拟合有比较明显的效果,特别是数据量相对较小的时候。

4:权重初始化(weight initialization)

深度学习中权重初始化对模型收敛速度和模型质量有着重要的影响。参数在刚开始不能全都初始化为0,因为如果所有的参数都是0,那么所有神经元的输出都将是相同的,在反向传播时同一层内所有的神经元的行为也都一致。

5:训练轮数。模型收敛即可停止迭代,一般可采用验证集作为停止迭代的条件。如果连续几轮模型损失都没有相应减少,则停止迭代。

6:正则化。为了防止过拟合,可通过加入l1、l2正则化。从公式可以看出,加入l1正则化的目的是为了加强权值的稀疏性,让更多值接近于零。而l2正则化则是为了减小每次权重的调整幅度,避免模型训练过程中出现较大抖动。

避免过拟合的方法之一是增加训练数据数量,或者减小网络的规模。但是往往大型的网络比小型网络有更大的潜力。在使用固定的网络和固定的训练数据进行网络训练时,为了避免过拟合,提高模型的泛化能力,可以采用正则化的方法。

如上图所示,随着训练过程的进行,模型复杂度增加,在训练数据上错误逐渐减小,但是在验证集上的错误率反而逐渐增大,这是因为模型出现了过拟合的现象,对训练集外的数据准确率较低。

L2  regularization(权重衰减)
L2正则化是在代价函数后面加上一个正则化项:

C0是原始的代价函数,后面一项为L2正则化项,即所有参数w的平方和除以训练集的样本大小n。λ是正则项系数,权衡正则项和原始代价函数C0的比重,1/2是为了求导方便。

推导过程:

先求导:

可以发现L2正则化项对b的更新没有影响,但是对w的更新有影响:

在不使用L2正则化时,w前的系数为1,现在w前面系数为 1−ηλ/n ,因为η、λ、n都是正的,所以 1−ηλ/n小于1,它的效果是减小w,这也就是权重衰减(weight decay)的由来。当然考虑到后面的导数项,w最终的值可能增大也可能减小。

另外,需要提一下,对于基于mini-batch的随机梯度下降,w和b更新的公式跟上面给出的有点不同:

对比上面w的更新公式,可以发现后面那一项变了,变成所有导数加和,乘以η再除以m,m是一个mini-batch中样本的个数。

更小的权值w,从某种意义上说,表示网络的复杂度更低,对数据的拟合刚刚好(这个法则也叫做奥卡姆剃刀)。

过拟合的时候,拟合函数的系数往往非常大。过拟合,就是拟合函数需要顾忌每一个点,最终形成的拟合函数波动很大。在某些很小的区间里,函数值的变化很剧烈。这就意味着函数在某些小区间里的导数值(绝对值)非常大,由于自变量值可大可小,所以只有系数足够大,才能保证导数值很大。而正则化是通过约束参数的范数使其不要太大,所以可以在一定程度上减少过拟合情况。

L1 regularization
在原始的代价函数后面加上一个L1正则化项,即所有权重w的绝对值的和,乘以λ/n.

求导:


上式中sgn(w)表示w的符号。那么权重w的更新规则为:

比原始的更新规则多出了η * λ * sgn(w)/n这一项。当w为正时,更新后的w变小。当w为负时,更新后的w变大——因此它的效果就是让w往0靠,使网络中的权重尽可能为0,也就相当于减小了网络复杂度,防止过拟合。
 

7:预训练pre-training)

预训练模型(pre-trained model)是前人为了解决某个问题所创造出来的问题。在解决新的问题时,不需要从零开始训练一个新模型,可以从类似问题中训练过的模型入手,在原有模型的基础上进行微调继续训练。该方法不仅在时间上或者准确率上都有较好的效果。对需要训练的语料进行预训练可以加快训练速度,并且对于模型最终的效果会有少量的提升,常用的预训练工具有word2vec和glove。

8:激活函数。常用的激活函数为sigmoid、tanh、relu、leaky relu、elu。采用sigmoid激活函数计算量较大,而且sigmoid饱和区变换缓慢,求导趋近于0,导致梯度消失。sigmoid函数的输出值恒大于0,这会导致模型训练的收敛速度变慢。

tanh它解决了zero-centered的输出问题,然而,gradient vanishing(梯度消失)的问题和幂运算的问题仍然存在。

relu从公式上可以看出,解决了gradient vanishing问题并且计算简单更容易优化,但是某些神经元可能永远不会被激活,导致相应的参数永远不能被更新(Dead ReLU Problem);leaky relu有relu的所有优点,外加不会有Dead ReLU问题,但是在实际操作当中,并没有完全证明leaky relu总是好于relu。

elu也是为解决relu存在的问题而提出,elu有relu的基本所有优点,但计算量稍大,并且没有完全证明elu总是好于relu。

激活函数的主要作用是提供网络的非线性建模能力。如果没有激活函数,那么不管网络有多少层都仅能够表达线性映射。激活函数应具有如下性质:

1、可微性:当优化方法是基于梯度的时候,这个性质是必须的;

2、单调性:当激活函数是单调函数的时候,单层网络能够保证是凸函数;

3、输出值的范围:当激活函数输出值是有限的时候,基于梯度的优化方法会更加稳定。

常见的激活函数介绍:

sigmoid函数


sigmoid缺陷是有明显的饱和性,从上图可以看出,其两侧的导数逐渐趋近于0.在反向传播的过程中,sigmoid向下传导的梯度包含导数因子,一旦输入落入饱和区,导数会接近于0,导致梯度在传递过程中越来越小,因此网络很难得到有效地训练,这种现象被称为梯度消失。

tanh


tanh激活函数输出的均值为0,收敛速度比sigmoid快,从而减少了迭代次数,训练更快。但是从图中可以看出,tanh激活函数同样有饱和性,从而噪声梯度消失。

ReLU


ReLU的全称是Rectified Linear Units。当x<0时,ReLU硬饱和;当x>0时,不存在饱和的问题。ReLU能够保持在x>0时梯度不衰减,从而缓解了梯度消失的问题。

但是随着训练的推进,部分输入会落入硬饱和区,导致对应权重无法更新。这种现象被称为“神经元死亡”。与sigmoid类似,ReLU的输出均值也大于0,偏移现象和 神经元死亡会共同影响网络的收敛性。

Leaky-ReLU
针对在x<0的硬饱和问题,对ReLU做出相应的改进:

ELU


融合了sigmoid和ReLU,左侧具有软饱和性,右侧无饱和性。右侧线性部分使得ELU能够缓解梯度消失,而左侧软饱能够让ELU对输入变化或噪声更鲁棒。ELU的输出均值接近于零,所以收敛速度更快。在 ImageNet上,不加 Batch Normalization 30 层以上的 ReLU 网络会无法收敛,PReLU网络在MSRA的Fan-in (caffe )初始化下会发散,而 ELU 网络在Fan-in/Fan-out下都能收敛。
 

9:特征学习函数。常用的特征学习函数有cnn、rnn、lstm、gru。cnn注重词位置上的特征,而具有时序关系的词采用rnn、lstm、gru抽取特征会更有效。gru是简化版的lstm,具有更少的参数,训练速度更快。但是对于足够的训练数据,为了追求更好的性能可以采用lstm模型。

10:特征抽取。max-pooling、avg-pooling是深度学习中最常用的特征抽取方式。max-pooling是抽取最大的信息向量,然而当存在多个有用的信息向量时,这样的操作会丢失大量有用的信息。

avg-pooling是对所有信息向量求平均,当仅仅部分向量相关而大部分向量无关时,会导致有用信息向量被噪声淹没。针对这样的情况,在有多个有用向量的情形下尽量在最终的代表向量中保留这些有用的向量信息,又想在只有一个显著相关向量的情形下直接提取该向量做代表向量,避免其被噪声淹没。那么解决方案只有:加权平均,即Attention。

11:每轮训练数据乱序。每轮数据迭代保持不同的顺序,避免模型每轮都对相同的数据进行计算。

12:batch_size选择。对于小数据量的模型,可以全量训练,这样能更准确的朝着极值所在的方向更新。但是对于大数据,全量训练将会导致内存溢出,因此需要选择一个较小的batch_size。

如果这时选择batch_size为1,则此时为在线学习,每次修正方向为各自样本的梯度方向修正,难以达到收敛。batch_size增大,处理相同数据量的时间减少,但是达到相同精度的轮数增多。实际中可以逐步增大batch_size,随着batch_size增大,模型达到收敛,并且训练时间最为合适

二、深度学习中的其他技巧

1.梯度消失/梯度爆炸的解决方案
首先,梯度消失与梯度爆炸的根本原因是基于bp的反向传播算法 

且上述的反向传播错误小于1/4 


总的来说就是,更新w和b的时候,更新的步长与learningrate成正比,当所处的层数越浅,每层的w的值和反向传播错误的值乘的愈多,导致w和b更新的步长收到很大影响,最终导致梯度爆炸或者梯度消失。这时候深度网络并不能比浅层网络性能好。后面基层学习情况好,而浅层网络则学不到东西。sigmoid网络中存在指数级的梯度消失。 
策略大概有以下几种。 
每层网络以不同的学习率进行学习 
更换激活函数 
使用relu激活函数,简化计算,且解决梯度消失问题,并且一部分神经元输出为0,可以使网络具有稀疏性,减少参数的依存关系,缓解过拟合的发生。 
使用batch normolization 
训练网络前需要对数据做归一化处理。用处在于:神经网络本质是学习数据分布,如果寻来你数据与测试数据分布不同,网络的泛化能力将降低,且在每一批训练数据不同的情况下,网络的训练速度会降低。 
batch normolization可以解决梯度消失问题,使得不同层不同scale的权重变化整体步调更一致,也可以加快训练速度。放在每一层网络的非线性映射前,即放在激活函数之前。

局部最优解怎么办
模拟退火 
加入momentum项

momentum是梯度下降法中一种常用的加速技术。对于一般的SGD,其表达式为x \leftarrow  x-\alpha \ast dx,x沿负梯度方向下降。而带momentum项的SGD则写生如下形式:
v=\beta \ast v -a\ast dx\\
x \leftarrow  x+v
其中\beta即momentum系数,通俗的理解上面式子就是,如果上一次的momentum(即v)与这一次的负梯度方向是相同的,那这次下降的幅度就会加大,所以这样做能够达到加速收敛的过程。

不收敛怎么回事,怎么解决
数据太少 
learningrate过大 
可能导致从一开始就不收敛,每一层的w都很大,或者跑着跑着loss突然变得很大(一般是因为网络的前面使用relu作为激活函数而最后一层使用softmax作为分类的函数导致) 
网络结构不好 
更换其他的最优化算法 
我做试验的时候遇到过一次,adam不收敛,用最简单的sgd收敛了。。具体原因不详 
对参数做归一化 
就是将输入归一化到均值为0方差为1然后使用BN等 
初始化 
改一种初始化的方案

过拟合
增加训练集的数据量 
图像的话可以平移反转加噪声 
使用relu激活函数 
dropout 
每次迭代训练随机选取一部分节点进行训练和权重更新,另一部分权重保持不变。在测试时,使用mean network网络获得输出。 
正则化 
也是为了简化网络,加入l2范数 
提前终止训练

怎样提升效果?/或许有欠拟合
增加特征数量 
本来输入只有坐标位置,欠拟合后再增加一个颜色特征 
减少正则化项的参数

参数初始化的研究
http://m.blog.csdn.net/shwan_ma/article/details/76257967

最优化方法
http://www.cnblogs.com/wuxiangli/p/7258510.html
 

2.卷积神经网络CNN中的技巧
CNN中将一个大尺寸的卷积核分解成多层的小尺寸的卷积核或者分解成多层的一维卷积,这样能够减少参数并增加非线性。

CNN中的网络设计应该逐渐减少图像尺寸,同时增加通道数,让空间信息转化为高阶抽象的特征信息。

3.数据扩充(Data Augmentation)
数据扩充,又名数据增强。其目的是在缺少海量数据时,为了保证模型的有效训练,从原始数据中生成更多的数据出来。

数据扩充方法包括:

1、翻转包括水平翻转、垂直翻转、水平垂直翻转。

2、旋转是常取的角度为-30、-15、15、30度等。

3、尺度变换是指将图像分辨率变为原图的0.8、1.1、1.2倍等,生成新图。

4、抠取包括随机抠取和监督式抠取。随机抠取在原图的随机位置抠取图像块作为新图像;监督式抠取只抠取含有明显语义信息的图像块。

5、色彩抖动是对原有的像素值分布进行轻微扰动,即加入轻微的噪声作为新图像。

6、Fancy PCA对所有训练数据的像素值进行主成分分析,根据得到的特征值和特征向量计算一组随机值,作为扰动加入到原来像素值中。
 

猜你喜欢

转载自blog.csdn.net/qq_38358305/article/details/86492966
今日推荐