激活函数、防止过拟合方法、加速训练方法、数据增强

前言

关于深度学习,看了许久,但是一直没有找个时间把相关知识点总结下来,今天特意督促自己写下所学内容,如有错误,还望指出。

关于深度学习主要介绍以下几点:激活函数、防止过拟合方法、加速训练的方法

激活函数

深度学习中的激活函数主要有sigmoid、tanh、ReLu、Maxout函数等。激活函数的主要作用是提供网络的非线性建模能力。如果没有激活函数,那么该网络仅能够表达线性映射,此时即便有再多的隐藏层,其整个网络跟单层神经网络也是等价的。因此也可以认为,只有加入了激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。 一般来说激活函数应该具备以下性质:

可微性: 当优化方法是基于梯度的时候,这个性质是必须的。 
单调性: 当激活函数是单调的时候,单层网络能够保证是凸函数。 
输出值的范围: 当激活函数输出值是 有限 的时候,基于梯度的优化方法会更加 稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是 无限 的时候,模型的训练会更加高效,不过在这种情况小,一般需要更小的learning rate

从目前来看,常见的激活函数多是分段线性和具有指数形状的非线性函数

1.Sigmoid

这里写图片描述 

f(x)=11+e−xf(x)=11+e−x

sigmoid 是使用范围最广的一类激活函数,具有指数函数形状,它在物理意义上最为接近生物神经元。此外,0~1 的输出还可以被表示作概率,或用于输入的归一化,代表性的如Sigmoid交叉熵损失函数。然而,sigmoid也有其自身的缺陷,最明显的就是饱和性。从上图可以看到,其两侧导数逐渐趋近于0 。在后向传递过程中,一旦输入落入饱和区, 梯度值就会变得接近于0,导致了向底层传递的梯度也变得非常小,这会导致训练网络时变得非常慢。此时,网络参数很难得到有效训练。这种现象被称为梯度消失。一般来说, sigmoid 网络在 5 层之内就会产生梯度消失现象此外,sigmoid函数的输出均大于0,使得输出不是0均值,这称为偏移现象,这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。如今,已经很少有人采用sigmoid函数作为激活函数,很大一部分原因是它的梯度消失这一缺点!!!

2.Tanh 

这里写图片描述

tanh(x)=sinh(x)cosh(x)tanh(x)=sinh(x)cosh(x)


其中:

sinh(x)=ex−e−x2sinh(x)=ex−e−x2

cosh(x)=ex+e−x2cosh(x)=ex+e−x2


tanh也是一种非常常见的激活函数,输出值范围为-1~1。与sigmoid相比,它的输出均值是0,使得其收敛速度要比sigmoid快,减少迭代次数。然而,从图中可以看出,tanh一样具有饱和性,仍然会造成梯度消失。

3.ReLu、Leaky-ReLu、Randomized Leaky-ReLu 

这里写图片描述

从上图不难看出,ReLU函数其实是分段线性函数,把所有的负值都变为0,而正值不变,这种操作被成为单侧抑制。可别小看这个简单的操作,正因为有了这单侧抑制,才使得神经网络中的神经元也具有了稀疏激活性。尤其体现在深度神经网络模型(如CNN)中,当模型增加N层之后,理论上ReLU神经元的激活率将降低2的N次方倍。这里或许有童鞋会问:ReLU的函数图像为什么一定要长这样?反过来,或者朝下延伸行不行?其实还真不一定要长这样。只要能起到单侧抑制的作用,无论是镜面翻转还是180度翻转,最终神经元的输出也只是相当于加上了一个常数项系数,并不影响模型的训练结果。之所以这样定,或许是为了契合生物学角度,便于我们理解吧。那么问题来了:这种稀疏性有何作用?换句话说,我们为什么需要让神经元稀疏?不妨举栗子来说明。当看名侦探柯南的时候,我们可以根据故事情节进行思考和推理,这时用到的是我们的大脑左半球;而当看蒙面唱将时,我们可以跟着歌手一起哼唱,这时用到的则是我们的右半球。左半球侧重理性思维,而右半球侧重感性思维。也就是说,当我们在进行运算或者欣赏时,都会有一部分神经元处于激活或是抑制状态,可以说是各司其职。再比如,生病了去医院看病,检查报告里面上百项指标,但跟病情相关的通常只有那么几个。与之类似,当训练一个深度分类模型的时候,和目标相关特征往往也就那么几个,因此通过ReLU实现稀疏后的模型能够更好地挖掘相关特征,拟合训练数据。

此外相比于其它激活函数来说,ReLU有以下优势:对于线性函数而言,ReLU的表达能力更强,尤其体现在深度网络中;而对于非线性函数而言,ReLU由于非负区间的梯度为常数,因此不存在梯度消失问题,使得模型的收敛速度维持在一个稳定状态。这里稍微描述一下什么是梯度消失问题:当梯度小于1时,预测值与真实值之间的误差每传播一层会衰减一次,如果在深层模型中使用sigmoid作为激活函数,这种现象尤为明显,将导致模型收敛停滞不前。

这里写图片描述

除了ReLu函数,还有Leaky-ReLu函数,如上图中间所示: 

f(x)={αxxx<0x≥0f(x)={αxx<0xx≥0


其中α为一个非常小的常数。

Randomized Leaky-ReLu函数如上面最右图所示: 

f(x)={αxxx<0x≥0f(x)={αxx<0xx≥0


不同于Leaky-ReLu,这里的α是一个变量,需要通过神经网络进行学习得出!

4.softplus函数 
softplus函数和ReLU形状类似,如下图所示,其中f(x)表达式为: 

f(x)=log(1+ex)f(x)=log(1+ex) 

这里写图片描述

5.maxout函数

这里写图片描述

更多内容可以参考神经网络之激活函数

防止过拟合

防止过拟合方法主要有增加训练数据、DropOut、Batch Normalization、L1/L2正则化。

1.增加训练数据

这是解决过拟合最有效的方法,只要给足够多的数据,让模型「看见」尽可能多的「例外情况」,这样它就会不断修正自己,从而得到更好的结果。

如何获取更多数据???可以有以下几个方法: 
从数据源头获取更多数据:这个是容易想到的,例如物体分类,我就再多拍几张照片好了;但是,在很多情况下,大幅增加数据本身就不容易;另外,我们不清楚获取多少数据才算够; 根据当前数据集估计数据分布参数,使用该分布产生更多数据:这个一般不用,因为估计分布参数的过程也会代入抽样误差。 数据增强(Data Augmentation):通过一定规则扩充数据。如在物体分类问题里,物体在图像中的位置、姿态、尺度,整体图片明暗度等都不会影响分类结果。我们就可以通过图像平移、翻转、缩放、切割等手段将数据库成倍扩充;

  • 图像的裁剪
  • 图像的翻转
  • 图像的缩放
  • 图像的像素值的改变(通常对图像的RGB通道上的像素值增加或减少一定值来实现)

这里写图片描述 

这里写图片描述

2.DropOut

Dropout可以看做是一种模型平均,所谓模型平均,顾名思义,就是把来自不同模型的估计或者预测通过一定的权重平均起来,在一些文献中也称为模型组合,它一般包括组合估计和组合预测。Dropout中哪里体现了“不同模型”;这个奥秘就是我们随机选择忽略隐层节点,在每个批次的训练过程中,由于每次随机忽略的隐层节点都不同,这样就使每次训练的网络都是不一样的,每次训练都可以单做一个“新”的模型;此外,隐含节点都是以一定概率随机出现,因此不能保证每2个隐含节点每次都同时出现,这样权值的更新不再依赖于有固定关系隐含节点的共同作用,阻止了某些特征仅仅在其它特定特征下才有效果的情况。这样dropout过程就是一个非常有效的神经网络模型平均方法,通过训练大量的不同的网络,来平均预测概率。不同的模型在不同的训练集上训练(每个批次的训练数据都是随机选择),最后在每个模型用相同的权重来“融合”,介个有点类似boosting算法。

这里写图片描述

3.Batch Normalization

开始讲解算法前,先来思考一个问题:我们知道在神经网络训练开始前,都要对输入数据做一个归一化处理,那么具体为什么需要归一化呢?归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。 对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。 我们知道网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。Paper所提出的算法,就是要解决在训练过程中,中间层数据分布发生改变的情况,于是就有了Batch Normalization,这个牛逼算法的诞生。

就像激活函数层、卷积层、全连接层、池化层一样,BN(Batch Normalization)也属于网络的一层。在前面我们提到网络除了输出层外,其它层因为低层网络在训练的时候更新了参数,而引起后面层输入数据分布的变化。这个时候我们可能就会想,如果在每一层输入的时候,再加个预处理操作那该有多好啊,比如网络第三层输入数据X3(X3表示网络第三层的输入数据)把它归一化至:均值0、方差为1,然后再输入第三层计算,这样我们就可以解决前面所提到的“Internal Covariate Shift”的问题了。

而事实上,paper的算法本质原理就是这样:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理,然后再进入网络的下一层。不过文献归一化层,可不像我们想象的那么简单,它是一个可学习、有参数的网络层。既然说到数据预处理,下面就先来复习一下最强的预处理方法:白化。

说到神经网络输入数据预处理,最好的算法莫过于白化预处理。然而白化计算量太大了,很不划算,还有就是白化不是处处可微的,所以在深度学习中,其实很少用到白化。经过白化预处理后,数据满足条件: 
a、特征之间的相关性降低,这个就相当于pca; 
b、数据均值、标准差归一化,也就是使得每一维特征均值为0,标准差为1。如果数据特征维数比较大,要进行PCA,也就是实现白化的第1个要求,是需要计算特征向量,计算量非常大,于是为了简化计算,作者忽略了第1个要求,仅仅使用了下面的公式进行预处理,也就是近似白化预处理: 

x^(k)=x(k)−E[x(k)]Var[x(k)]√x^(k)=x(k)−E[x(k)]Var[x(k)]

经过前面简单介绍,这个时候可能我们会想当然的以为:好像很简单的样子,不就是在网络中间层数据做一个归一化处理嘛,这么简单的想法,为什么之前没人用呢?然而其实实现起来并不是那么简单的。其实如果是仅仅使用上面的归一化公式,对网络某一层A的输出数据做归一化,然后送入网络下一层B,这样是会影响到本层网络A所学习到的特征的。打个比方,比如我网络中间某一层学习到特征数据本身就分布在S型激活函数的两侧,你强制把它给我归一化处理、标准差也限制在了1,把数据变换成分布于s函数的中间部分,这样就相当于我这一层网络所学习到的特征分布被你搞坏了,这可怎么办?于是文献使出了一招惊天地泣鬼神的招式:变换重构,引入了可学习参数γ、β,这就是算法关键之处: 

y(k)=γ(k)x^(k)+β(k)y(k)=γ(k)x^(k)+β(k)

每一个神经元xk都会有一对这样的参数γ、β。这样其实当: 

γ(k)=Var[x(k)]−−−−−−−√γ(k)=Var[x(k)]

β(k)=E[x(k)]β(k)=E[x(k)]

是可以恢复出原始的某一层所学到的特征的。因此我们引入了这个可学习重构参数γ、β,让我们的网络可以学习恢复出原始网络所要学习的特征分布。

4.L1、L2正则化

相同点:都用于避免过拟合 
不同点:L1可以让一部分特征的系数缩小到0,从而间接实现特征选择,也就是说L1会使一部分权重变为0,所以L1适用于特征之间有关联的情况。L2让所有特征的系数都缩小,但是不会减为0,它会使优化求解稳定快速,所以L2适用于特征之间没有关联的情况。

加速训练

加速训练的方法主要有动量、Nesterov 动量、自适应学习率(AdaGrad、RMSProp、Adam、学习率衰减)、Batch Normalization等。

1.动量

SGD方法的一个缺点是,其更新方向完全依赖于当前的batch,因而其更新十分不稳定。解决这一问题的一个简单的做法便是引入momentum。momentum即动量,它模拟的是物体运动时的惯性,即更新的时候在一定程度上保留之前更新的方向,同时利用当前batch的梯度微调最终的更新方向。这样一来,可以在一定程度上增加稳定性,从而学习地更快,并且还有一定摆脱局部最优的能力: 

这里写图片描述

2.Nesterov动量 
Nesterov动量中,梯度计算在施加当前速度之后。因此,Nesterov动量可以解释为往标准动量方法中添加了一个校正因子。 

这里写图片描述

3.自适应学习率

3.1 AdaGrad 
AdaGrad独立地适应所有模型参数的学习率,缩放每个参数反比于其所有梯度历史平方值总和的平方根。 

这里写图片描述

在凸优化中,AdaGrad算法具有一些令人满意的理论性质。然而,经验上对于训练深度神经网络模型而言,从训练开始时积累梯度平方会导致有效学习率过早和过量减小。

3.2 AdaDelta 
AdaGrad主要存在三个问题: 
1.其学习率是单调递减的,训练后期学习率非常小 
2.其需要手工设置一个全局的初始学习率 
3.更新θ时,左右两边的单位不同一

我们令每一个时刻的r随之时间按照ρ指数衰减,这样就相当于仅使用离当前时刻比较近的g信息,不会使得r增加过快,分母过大而导致参数更新减缓。 

这里写图片描述

3.3 RMSProp 
RMSProp算法修改AdaGrad以在非凸设定下效果更好,改变梯度累积为指数加权的移动平均。AdaGrad旨在应用于凸问题时快速收敛。AdaGrad根据平方梯度的整个历史收缩学习率,可能使得学习率在达到这样的凸结构前就变得太小了。RMSprop使用指数衰减平均来丢弃遥远过去的历史,使其在找到凸结构后快速收敛,就像一个初始化于该碗装结构的AdaGrad算法实例。 相比于AdaGrad,使用移动平均引入了一个新的超参数ρ,用来控制移动平均的长度范围。

这里写图片描述

这里写图片描述

3.4 Adam 
派生自短语”adaptive moments” Adam被看作结合RMSProp和具有一些重要区别的动量的变种。首先,Adam中动量直接并入梯度一阶矩(指数加权)的估计。其次,Adam包括偏置修正,修泽和那个从原点初始化的一阶矩(动量项)和(非中心的)二阶矩的估计。RMSProp也采用了(非中心的)二阶矩估计,然而缺失了修正因子。因此,RMSProp二阶矩估计可能在训练初期有很高的偏置。 
Adam通常被认为对超参数的选择相当鲁棒,尽管学习率有时需要遵从建议的默认参数0.001。

这里写图片描述

4.Batch Normalization

5.Group Normalization

猜你喜欢

转载自blog.csdn.net/kwame211/article/details/81304451