深度学习之模型设计:核心算法与案例实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.4 深度学习优化基础

卷积神经网络有那么多参数,应该如何选择这些参数,又该如何优化它们呢?大量的权重连接值需要通过梯度下降等方法进行迭代调整,有些架构可能因为强大的表征力而产生测试数据过拟合等现象。卷积神经网络不仅要求在训练数据上有良好的表现,同时要求在未知的输入上有理想的泛化效果,如何实现这些效果是我们关注的重点。本节将介绍卷积神经网络中的激活函数、权重初始化方法、常用优化方法、正则化方法等。

2.4.1 激活模型与常用激活函数

深度学习基于人工神经网络的结构,而人工神经网络是模拟生物神经元的。从生物学上说,当人脑的细胞接受刺激产生活动时,首先需要该刺激超过一定的电位阈值,若没有达到阈值,则几乎不会产生活动。不同的刺激产生的输出是不同的,在刺激达到一定值后输出就饱和了。

神经元逐级传递信息,上层神经元的输出作为下层神经元的输入,经过一个非线性激活函数激活处理后继续往下传递,如此循环往复,直到输出层。正是由于这些非线性函数的反复叠加,才使神经网络有足够的非线性拟合能力。选择的激活函数将影响整个深层神经网络的效果。

下面介绍卷积神经网络中的各类激活函数。

1.线性模型与阈值模型

一个复杂的神经网络包含许多网络,其中最基本的单元便是神经元。对一个线性神经元,其输入为x,权重为w,偏置为b,输出为y,则变换关系如下。

因为输出与输入呈现线性关系,该线性神经元只能对非常简单的问题进行建模。如果再增加一层,把y作为中间层,输出为z,并假设这一层的权重为w′,偏置为b′,则输入x与输出z有如下关系。

可以看出,最终的输出zx仍然是线性关系,也就是说,这样堆叠下去,输出与输入永远都是线性关系。人们期望神经网络可以模拟任意的函数,而这不可能用一个线性函数来完成。所以需要在线性神经元输出后添加非线性函数,非线性函数添加得越多,变换就越复杂,模型的表达能力就越强。

最早的非线性映射函数是二值阈值函数,由心理学家Warren Sturgis MuCulloch和数学家Walter Harry Pitts于1943年合作提出。他们基于此搭建了MP模型,其输入与输出都使用了包含0和1的线性阈值神经元,变换关系如下。

如式(2.10)所示,当线性输出大于阈值th时,输出为1;当线性输出小于阈值th时,输出为0。这样的阈值神经元可以实现布尔函数,完成“与”和“或”操作。

x是一个二维的向量,所有权重连接值为1时,二值线性阈值神经元模型如图2.10所示。

b=-0.5,y=fx1+x2-0.5),因为x1x2的输入都是0/1,图2.10所示就是一个逻辑“或”模型,当x1x2等于1时,输出为1;当两者都等于0时,输出为0。

b=-1.5,y=fx1+x2-1.5),因为x1x2的输入都是0/1,图2.10所示就是一个逻辑“与”模型,当x1x2等于1时,输出为1;否则,输出为0。

线性阈值模型是最简单的非线性变换,所以其能实现的功能非常有限,在现今的深度学习模型中几乎不再使用。

2.Sigmoid函数与Tanh函数

大脑神经元的状态仅分为抑制或兴奋,早期常用Sigmoid函数与Tanh函数来描述。

Sigmoid函数的表达式如下。

Sigmoid函数示意如图2.11所示。

图2.10 二值线性阈值神经元模型

图2.11 Sigmoid函数示意

Sigmoid函数是传统的神经网络模型和深度学习模型早期发展时使用频率最高的激活函数,它将输出平滑地映射到0~1,是便于求导的平滑函数,其导数如下。

因为fx)取值为0~1,所以其导数取值也为0~1。Sigmoid函数具有非常好的可解释性,其模拟了一个神经元随着输入不断增加从完全不激活到完全激活的过程,符合生物学上的原理,因此在神经网络模型的早期研究中被广泛使用。不过Sigmoid函数有以下两个非常大的缺陷。

其一是Sigmoid函数的两端是饱和区,饱和区内梯度接近于0,这会带来熟知的梯度消失问题。一旦神经元的初始化或优化进入了饱和区,将难以继续优化。另外,随着网络层数的增加,由于链式法则,连乘的Sigmoid函数导数也会变得越来越小,导致梯度难以回传,这会降低网络的收敛速度,甚至导致网络不能收敛到好的状态。

其二是Sigmoid函数的输出并不以0为中心,总是大于0,而权重参数的梯度与输入有关,这就会造成在反向传播时,一个样本的某个权重的梯度总是同一个符号,这不利于权重的更新。

Tanh函数解决了Sigmoid函数的输出值并不以0为中心的问题,但梯度消失问题和幂运算问题仍然存在。Tanh函数表达式如下。

Tanh函数示意如图2.12所示。

图2.12 Tanh函数示意

3.线性ReLU函数及其改进

2001年,神经科学家Dayan和Abott从生物学角度模拟了脑神经元接收信号更精确的激活模型,该模型在正区间平滑地增加,在负区间没有激活。同年,Attwell等人在研究大脑能量消耗时,发现神经元编码工作方式具有稀疏性和分布性。2003年,Lennie等人估测大脑同时被激活的神经元只有1%~4%,进一步证实了神经元工作的稀疏性。这说明神经元同时只会对输入信号的少部分选择性响应,但Sigmoid函数表示同时有一半的神经元被激活,这不符合要求,因此需要新的具有稀疏性的激活函数来学习相对稀疏的特征。

最早用于模拟上述特征的激活函数是2001年提出的Softplus函数,其表达式如下。

Xavier Glorot等人在论文Deep Sparse Rectifier Neural Networks[7]中指出,使用线性整流单元(ReLU函数)作为激活函数比使用Sigmoid函数、Tanh函数作为激活函数更好,其表达式如下。

ReLU函数示意如图2.13所示。

ReLU函数本质是一个取最大值函数,其非全区间可导,但在计算过程中可以取近似梯度。当x>0时,梯度为1;否则,梯度为0。

ReLU在正区间内解决了梯度消失问题,在使用时只需要判断输入是否大于0,所以其计算速度非常快,收敛速度远快于Sigmoid函数和Tanh函数。

但是ReLU函数的输出存在Dead ReLU问题,即某些神经元可能永远不会参与计算,导致其相应的参数无法被更新。参数初始化及学习速率太大都可能使网络进入这种状态,解决方法是采用Xavier等初始化方法,以及避免将学习速率设置太大,或者使用AdaGrad等自动调节学习速率的算法。

那么在零点处的导数不连续是否会影响优化呢?研究者比较了Softplus函数和ReLU函数,发现ReLU函数表现更好,从而可知导数的不连续并不影响性能,只要正区间导数可以传递。

研究者针对ReLU函数提出了许多的改进方法,如Leaky ReLU、ELU、SELU等。

Leaky ReLU函数表达式如下。

其函数示意如图2.14所示。

图2.13 ReLU函数示意

图2.14 Leaky ReLU函数示意

Leaky ReLU函数的提出是为了解决Dead ReLU问题,其将ReLU函数的前半段设为0.01x而非0。从理论上来讲,Leaky ReLU函数有ReLU函数的所有优点,并且不会有Dead ReLU问题,但实际操作并没有完全证明Leaky ReLU函数总是好于ReLU函数。

如果将x<0一侧的函数取非线性函数,则可以得到指数线性函数(ELU函数),其表达式如下。

ELU函数由Djork等人提出,能够使神经元的平均激活均值趋于0,对噪声具有较高的鲁棒性。但是其由于需要计算指数,计算量较大。

自归一化神经网络(Self-Normalizing Neural Networks)中提出,只需要把激活函数换成SELU函数,就能使输入在经过一定层数之后变成固定的分布。SELU函数表达式为SELU(x=λ·ELU(x)。

如果将Leaky ReLU中的0.01设置为一个可以学习的参数α,就得到了PreLU函数。相比之下,PreLU函数增加了少量的参数量,如果每个通道都单独激活,则增加的参数量等于通道数。研究人员发现,学习到的α在网络的浅层,尤其是在第一层卷积中会比较大,而到了深层就比较小。这也可以理解为网络的浅层学习到了类似于Gabor的浅层特征,更大的α可以提取到更加稠密的特征,而随着网络深度的增加,特征变得更加稀疏。

如果让α参数在训练中是随机的,就得到了RReLU函数,通常α从一个均匀的分布中随机抽取,这可以看作一个正则项,用于增强网络的泛化能力。

GELUs函数则通过输入的幅度而不是ReLU的门控机制来进行激活,它可以起到随机正则化的效果,其函数表达式如下。

式中,Φ(x)是一个伯努利分布。GELUs在x值比较小时对输入进行随机恒等变化或0映射,一个建议的映射如下。

4.Maxout函数

Maxout函数就是最大值函数,它从多个输入中取最大值,其求导非常简单,只在最大值的一路有梯度。

Maxout函数可以看作在深度学习网络中加入一层激活函数层,其包含一个参数k。这一层相比ReLU函数,Sigmoid函数等的特殊之处在于增加了k个神经元,并输出最大的激活值。

Maxout函数的拟合能力非常强,可以拟合任意的凸函数。Maxout函数具有ReLU函数的所有优点,线性、不饱和性,同时没有ReLU函数的缺点。实验结果表明,Maxout函数与Dropout组合使用可以发挥比较好的效果。

5.Softmax函数

Softmax函数可视为Sigmoid函数的泛化形式,其本质是将一个K维的任意实数向量压缩(映射)成另一个K维的实数向量,向量中的每个元素取值都位于0和1之间。该函数一般用于多分类神经网络输出。

Softmax函数表达式如下。

6.激活函数的自动搜索

研究人员一直在搜索更好的激活函数,Swish函数[8]就是由网络自动搜索出来的激活函数,其表达式如下。

式中,β是一个常数或可训练的参数。Swish函数具备无上界有下界、平滑、非单调的特性。研究表明,Swish函数在深层模型上的效果优于ReLU函数。如果β=1,Swish函数就是在增强学习中常用的SiLU函数。

除了Swish函数,还有其他通过搜索得到的激活函数,如式(2.23)所示。

随着基于搜索的方法渐渐成为主流,未来依旧可能会出现更好的激活函数。

7.激活函数的研究方向[9]

对激活函数的研究,未来集中在以下几个方向。

(1)对ReLU函数负区域进行改进。

(2)研究不同激活策略对不同的网络层、不同的通道使用的影响。

(3)使用各类学习方法来对简单函数的组合进行探索。

虽然有许多新的比ReLU函数更好的激活函数出现,但ReLU函数仍然是最通用的。

2.4.2 参数初始化方法

为了让神经网络在训练过程中学习到有用的信息,参数梯度应该保持非零。在全连接神经网络中,参数初始化应该满足以下两个条件:①各层激活值不会出现饱和现象;②各层激活值不为0。常用的参数初始化方法如下。

1.初始化为0

如果神经元的权重被初始化为0,在第一次更新时,除了输出,所有的中间层的节点的值都为零。一般神经网络拥有对称的结构,那么在进行第一次误差反向传播时,更新后的网络参数相同,在下一次更新时,相同的网络参数提取不到有用的特征。即使是对于非对称的网络结构,这样的随机参数也不利于接下来的优化,因此,一般只在训练SLP/逻辑回归模型时才使用0来初始化所有参数。

2.生成小的随机数

将参数初始化为小的随机数,可以从均值为0、标准差为1的高斯分布中取样,即np.random.randn(n)。

一般而言,参数的初始值不能取得太小,因为较小的参数在反向传播时会导致过小的梯度产生,且对于深层网络而言,会产生梯度弥散问题,降低参数的收敛速度;而参数的初始值过大不仅会造成振荡,也会使Sigmoid函数等进入梯度饱和区,在实验结果中确实发现了这样的现象。另外,随机初始化方法的方差与该层的神经元有关,导致网络不稳定。

3.标准初始化

如果能够保持神经网络每层的权重方差与层数无关,会更加有利于优化。假如输入和权重都是零均值,则有如下关系。

如果希望输入x和输出y具有相同的方差,则需要满足nVar(w)=1。其中,n为每个神经元的输入数量;w应该用n的平方根进行归一化。所以标准初始化方法的权重参数从的均匀分布中生成。

均匀分布XUab)的概率密度函数为

其期望等于,方差等于的均匀分布使得nVar(w)=1/3,这与网络的层数无关,因此对Sigmoid函数,其自变量始终落在有梯度的范围。

4.Xavier初始化

理想的初始化应该使各层的激活值和状态梯度的方差在传播过程中保持一致,不然若更新后的激活值方差发生改变,将造成数据的不稳定。

Xavier初始化有以下关于激活函数的假设(称为Glorot激活函数假设)[10]

(1)每层激活的方差应该保持不变,即在正向传播时,每层的激活值的方差保持不变;在反向传播时,每层的梯度值的方差保持不变。

(2)激活函数对称,每层的输入均值都是0。

Xavier初始化取值为

这个区间是根据以下公式得到的,即[-bb]的均匀分布的方差为

式中,nini+1表示输入和输出维度,此时激活值的方差和层数无关,反向传播梯度值的方差和层数无关。

虽然Xavier初始化通常与ReLU函数共同使用,但因为它是针对Tanh函数提出的,所以对于ReLU函数并不友好。网络越深,各层输入的方差就越小,网络越难训练。

5.MSRA初始化

何凯明等人提出了与Xavier初始化非常类似的MSRA初始化方法,该方法主要是基于ReLU函数提出的,其是一个均值为0、方差为(2/输入神经元的个数)的高斯分布,如式(2.28)所示。

6.初始化方法的使用

为了获得更好的初始化,通常有以下方法。

(1)使用已经训练好的模型无疑是最好的初始化方法,这样能够在训练之初迅速学习到有效的参数。

(2)选择更好的激活函数,让初始化尽量不影响梯度的传递。ReLU系列的激活函数可以实现这种效果,而且MSRA初始化方法也可以与ReLU系列的激活函数配合使用,因此两者的搭配成为当前的主流。

(3)归一化,让每层输入和输出的分布比较一致,从而降低学习难度。

此外,还有研究者分别针对零点平滑的激活函数和零点不平滑的激活函数提出了统一的初始化方法框架[11],读者可以自行关注后续研究进展。

2.4.3 归一化方法

为取得较理想的输出结果,一般希望机器学习中输入模型的数据能满足独立同分布的假设条件。但是对于神经网络而言,层级的网络结构使底层的参数更新对高层的输入分布产生很大的影响,故很难满足该假设条件。对此,研究者在神经网络中引入了归一化(Normalization)方法,实际上是通过采取不同的变换方式使各层的输入数据近似满足独立同分布假设条件,并将各层输出限制在一定的范围。

1.什么是Normalization

Normalization是统计学中的一个概念,被称为归一化或规范化。它并不是一个完全定义好的数学操作(如加、减、乘、除),通常是指将数据进行偏移和尺度缩放,是数据预处理中非常常见的操作,如将不同度量单位进行归一化以便进行后续的分析。

简单来说,归一化是指将数据约束到固定的分布范围,如常见的8位数字图像,其像素值分布在0~255,或者在用浮点数表达时分布在0~1。

在数字图像处理领域,有一个很常见的线性对比度拉伸操作。

式中,xminxmax分别是灰度最小值和最大值,这个操作可以将图像的像素归一化到0~1,通常可以增强前背景的对比效果。

更加复杂的归一化,可能是将某个分布归一化到另一个分布,如直方图均衡。直方图均衡通过图像的灰度值分布,即通过图像直方图来对图像进行对比度调整,可以增强局部的对比度。

假设rk表示第k级灰度,nk表示图像中第k级灰度所对应的像素个数,n表示图像像素总数,首先计算归一化后的直方图,得到式(2.30)。

对于8位的图像,L=256,此时p(rk表示灰度级为rk的像素所占总像素的比例。对一幅正常曝光的自然图像,其直方图应该尽可能覆盖所有灰度级甚至具有相对均匀的分布,但在很多情况下,因为曝光过度或欠曝,不可能具有均匀分布。直方图均衡化正是让一个分布从随机分布变换到[0,1]均匀分布的变换,它的变换步骤如下。

(1)计算累积概率分布,cdp(rk表示灰度为0~rk的像素的概率,可知它是单调递增的,cdp(L-1)=1。

(2)创建一个均匀分布,将累计概率分布转换到图像的像素值范围,变换关系为

式中,round表示取整操作,因为cdp(rk)∈(0,1),所以T(rk)∈(0,255)。

(3)反向映射,变换后新的像素灰度值y与原始的像素灰度值x的变换关系为

可以看出,经过变换后,原始的灰度会被映射到(0,255),而且是一个均匀分布。在很多时候,直方图均衡可以用于增强局部的对比度而不影响整体的对比度,当图像对比度较低时很有用。

上述这两种常见的归一化方法,都是数字图像处理领域非常常用的,虽然在深度学习中不再人工设计这样的变换来增强数据的辨识度,但在网络内部实际上会进行功能类似的操作以实现特征的学习。

零均值归一化也是一个常见的归一化方法,称为标准化方法,它用每个变量值与其平均值之差除以该变量的标准差,如式(2.34)所示,经过处理后的数据符合均值为0、标准差为1的标准正态分布。

机器学习中的很多问题都基于正态分布的假设,这是更加常用的归一化方法。

2.Batch Normalization

一般采用批梯度下降法对深度学习模型进行优化,这种方法把数据分为若干组,按组来更新参数,一组中的数据共同决定了本次梯度的方向,从而减少了下降时的随机性。另外,因为批的样本数与整个数据集相比小了很多,这种方法的计算量也下降了很多。

Batch Normalization(BN)[12]中的Batch指批量数据,即每次优化时的样本数目,通常BN层用在卷积层后,用于重新调整数据分布。

假设神经网络某层一个Batch的输入为X=[x1x2,…,xn],其中xi代表一个样本,n为Batch的大小。首先,求得Mini-batch中元素的均值:

接下来,求取Mini-batch的方差:

这样就可以对每个元素进行归一化,如式(2.37)所示,其中ε是防止分母为0的一个常数。

最后进行尺度缩放和偏移操作,这样可以变换回原始的分布,实现恒等变换。恒等变换可以补偿网络的非线性表达能力损失,因为经过标准化之后,偏移量丢失了。具体的表达如式(2.38),其中,yi就是网络的最终输出。

从某种意义上来说,γβ代表的其实是输入数据分布的方差和偏移。对于没有BN层的网络,这两个值与前一层网络带来的非线性性质有关,而经过变换后,其就与前一层无关了,变成了当前层的一个学习参数,这更有利于优化且不会降低网络的能力。

CNN的各个特征维度之间,即通道之间是分别进行BN计算的。如果输出的Blob大小为(NCHW),那么在每层归一化就是基于N×H×W个数值进行求平均及方差的操作。

BN带来了两个好处:①减轻了对初始值的依赖;②训练更快,可以使用更高的学习速率。

尽管BN层实践效果非常好,但有一定的缺陷。BN依赖Batch的大小,当Batch值很小时,计算的均值和方差不稳定。研究表明,当使用ResNet系列模型在ImageNet数据集上训练时,当Batch从16降到8时,其开始有非常明显的性能下降,在训练过程中计算的均值和方差不准确,而在测试时使用的就是在训练过程中保持下来的均值和方差,这个特性导致BN不适合以下的几种场景。

(1)Batch非常小。可以是训练资源有限无法应用较大的Batch的场景,也可以是在线学习等使用单例进行模型参数更新的场景。

(2)RNN。因为它是一个动态的网络结构,同一个Batch中训练实例有长有短,导致每个时间步长必须维持各自的统计量,这使BN不能正确使用。在RNN中,对BN进行改进也非常困难。

另外,对于某些像素级的图片生成任务,如GAN图片生成和风格化,也会受Batch值的影响,不过BN层的应用也有利于这类模型的收敛。

BN用每个Batch的均值和方差来代替整体训练集的均值和方差,这要求Batch必须从各类中均匀采样,当Batch值较小时很难满足这一要求。针对BN依赖Batch的这个问题,BN的提出者对其进行了改进,即增加了一个仿射变换,提出了Batch Renormalization[13],它在用每个Batch的均值和方差来代替整体训练集的均值和方差之后,再通过一个线性变换来逼近数据的真实分布,具体变换如下。

式中,参数rd就是仿射变换参数,它们本身是通过式(2.40)进行计算的。

式中,σμ都是通过滑动平均的方法进行更新的:

所以rd是一个与样本有关的参数,当通过这样的变换进行学习时,这两个参数在训练时并不参与学习。在实际使用时,先使用BN将网络训练到一个相对稳定的移动平均值,再使用Batch Renormalization进行训练。

3.BN的变种

BN虽然应用广泛,但在实际应用时,需要计算并保存该层神经网络Batch的均值和方差等信息。其对于一个深度固定的神经网络(如DNN、CNN)非常适用,但对于深度不固定的RNN而言,在不同的时态下需要保存不同的静态特征,导致存在一个特殊序列比其他序列长很多,这样训练时计算会很麻烦。

BN各个通道之间是独立进行计算的,如果抛弃对Batch的依赖,也就是让每个样本在它的所有通道中进行Normalization,就得到了Layer Normalization(LN)。与BN仅针对单个通道不同,LN考虑神经网络中一层的信息,其计算该层输入的均值和方差作为规范化标准,对该层的所有输入进行同一个规范化操作,且不受Mini-batch的均值和方差的影响,可用于Mini-batch较小时的场景、动态网络结构和RNN。此外,由于无须保存Mini-batch的均值和方差,其节省了存储空间。LN中同一层神经元输入拥有相同的均值和方差,不同的输入样本有不同的均值和方差。

如果输出的Blob大小为(NCHW),那么在每一层进行LN就是基于C×H×W个数值进行求平均及方差的操作。因为根据不同的通道进行了归一化,所以对于相似度相差较大的特征,LN会降低模型的表示能力,在此情况下,选择BN方法更优。

LN将同一个网络层的所有神经元作为统计范围,Instance Normalization(IN)则将CNN中同一卷积层中的每个通道作为自己的统计范围。假如一个网络层的通道数为1,则两者是等价的。

如果输出的Blob大小为(NCHW),那么在每一层进行的IN就是基于H×W个数值进行求平均及方差的操作。对于风格化类的图像应用,IN通常能取得更好的结果。

Group Normalization(GN)[14]是LN和IN的中间体,它将通道进行分组,然后在每个组内做归一化。

如果输出的Blob大小为(NCHW),将通道分为G个组,那么GN就是基于G×H×W个数值进行求平均及方差的操作。

除了以上方法,还有通用版本Generalized Batch Normalization、对硬件更加友好的L1-Norm Batch Normalization等,读者可自行学习。

BN等方法属于特征规范化,而Weight Normalization则将参数进行规范化,即其将权重向量分解为权重大小和方向两部分,不依赖输入数据的分布,故可应用于Mini-batch较小的情景及动态网络结构。

4.归一化方法的自动搜索

在每个网络层中都使用同样的归一化,这是最优的配置吗?显然不是,因为在实际应用中,每个问题都有它最合适的归一化操作。例如,对于RNN等时序模型,有时同一个Batch内部的训练实例长度不一(句子长度不同),在不同的时态下需要保存不同的统计量,此时无法正确使用BN,只能使用LN;对于图像生成及风格迁移类应用,使用IN更加合适;对于Batch比较小的情况下,GN是一个替换的方案。

Switchable Normalization[15]研究的便是如何让不同的网络层学习到最适合该层的归一化机制,方法是在包含各类归一化方法的池中进行选择,然后用精度进行比较择优,最终在任务中自适应地学习出最佳配置,从而使模型对批处理大小更加不敏感。具体结果是,当批处理越小时,BN越不稳定,其对应权重系数越小,IN和LN的权重系数则越大;反之,BN的权重系数越大。

5.归一化有效性问题

归一化机制及其在深度学习中的有效性至今仍然是一个非常开放的问题,相关的理论研究一直都有,目前有以下几个主要观点。

(1)BN调整了数据的分布,不考虑激活函数,它让每一层的输出归一化到了均值为0、方差为1的分布,这保证了梯度的有效性,缓解了Internal Covariate Shift(ICS)问题。

(2)文献[16]指出,BN有效是因为使用BN层之后可以使用更大的学习速率,从而跳出不好的局部极值,增强泛化能力,作者做了大量的实验来验证这个观点。

(3)文献[17]的研究认为,BN有效的根本原因不在于调整了分布,因为即使是在BN层后模拟出存在Internal Covariate Shift(ICS)特性的数据,也仍然可以取得好的结果。其指出,BN有效的根本原因是平滑了损失平面,如同Z-score标准化对孤立点的分布进行更平滑的调整。

总之,归一化是非常有效的数据预处理和提高深度学习模型泛化能力的策略,值得读者思考。

2.4.4 池化

1.池化方法

池化是深度学习模型抽象信息的保证,平均池化和最大池化是使用最广泛的两种池化方法,我们在前面对其进行过介绍,就不再赘述。Mixed Pooling[18]则在平均池化和最大池化中进行随机选择,可提供一定的正则化能力。Stochastic Pooling[19]也属于一种正则化操作,其对特征图中的元素按照概率值大小随机选择,元素被选中的概率与其数值大小正相关。

以上几种方法都是手动设计池化的方案,基于数据驱动的池化方案也在研究中,针对不同的任务可以学习出最合适的方案。

2.池化机制的理解

我们希望在任务中,目标位置在较小的移动后仍然能得到相同的结果,而池化正好具备这样的特性,因为池化不断地抽象了区域的特征而不关心位置,所以在一定程度上增加了平移不变性。

尽管池化的原理表明它是可以增强平移不变性的,但研究表明,实际上非常深的网络对图像中目标的变化很敏感。DeepMind等最新的研究[20]表明,池化方法本身并没有起到太大的作用,使用不同的池化方法和带步长的卷积,最终能取得同样的效果,而其中真正有用的是数据增强操作。

2.4.5 最优化方法

最优化方法是深度学习中一个非常重要的话题,最常见的情形是利用目标函数的导数通过多次迭代来求解无约束最优化问题。

深度学习模型的优化是一个非凸优化问题,这与凸优化问题有很大的不同。对于凸优化问题来说,任何局部最优解即全局最优解,用贪婪算法或梯度下降法都能收敛到全局最优解。而非凸优化问题则可能存在无数个局部最优点,有极大值也有极小值。

除了极大值、极小值,还有一类值,即“鞍点”。简单来说,它就是在某一些方向梯度下降,而在另一些方向梯度上升的点,该点附近的曲面形状似马鞍。对于深度学习模型的优化来说,鞍点比局部极大值点或极小值点带来的问题更加严重。

目前常用的优化方法分为一阶和二阶两类,一阶方法只需要求解一阶导数,包括随机梯度下降(Stochastic Gradient Descent,SGD)法及其各类变种,二阶方法则需要求解二阶导数,包括牛顿法等。

随机梯度下降法有许多变种,如Adam、RMSProp、AdaGrad等,这些算法都需要预先设置学习率。学习率决定了在一个小批量(Mini-batch)中权重在梯度方向的移动步长,能够直接影响模型收敛到局部最小值(也就是达到最好的精度)的速度。如果学习率很低,训练过程会更加细致,结果会更加可靠,但优化过程会耗费较长的时间,因为逼近损失函数最小值的每个步长都很小。如果学习率过高,训练可能发散,不会收敛,权重的改变量可能非常大,使得优化在最小值附近振荡。

一般来说,学习率太小,网络很可能会陷入局部最优。学习率越大,神经网络的学习速度越快,但如果太大,超过了极值,损失就会停止下降,在某一位置反复振荡。也就是说,当选择了一个合适的学习率时,不仅可以在更短的时间内训练好模型,还可以节省各种损耗。一般而言,当已经设定好学习率并训练模型时,只有让学习率随时间的推移下降,模型才能最终收敛。

下面详细介绍深度学习中常用的优化方法。

1.梯度下降法与动量法

梯度下降法是最广泛使用的优化方法,其在目标函数是凸函数时可以得到全局解。

我们知道,对于一个函数fx),记f′x)为它的梯度,对于足够小的εfx-εsign(f′x)))是小于fx)的,所以从x的反方向进行搜索,就能够减小fx),而且这个方向还是减小f(x)最快的方向,这就是所谓的梯度下降法,也被称为最速下降法。

梯度下降法在越接近目标值的时候,需要的步长越小,前进越慢,否则就会越过最优点。通常在机器学习优化任务中,有两种常用的梯度下降法,分别是随机梯度下降法和批量梯度下降法。

所谓批量梯度下降(Batch Gradient Descent)法,就是使用所有的训练样本计算梯度,用这种方法,梯度计算稳定,可以求得全局最优解,但计算非常慢,往往因为资源问题不可能实现。

所谓随机梯度下降(Stochastic Gradient Descent)法,就是每次只取一个样本进行梯度的计算,它的问题是梯度计算相对不稳定,容易振荡,不过整体上还是趋近于全局最优解的,所以最终的结果往往是在全局最优解附近。

通常我们训练时会进行折中,即从训练集中取一部分样本进行迭代,这就是常说的Mini-batch训练。

为解决随机梯度下降有时会很慢的问题,Polyak在1964年提出了动量项(Momentum)方法(动量法)。为了表示动量,首先引入一个新的变量v(velocity),v是之前梯度计算量的累加,但每回合都有一定的衰减。

动量法的思想是将历史步长更新向量的一个分量γ增加到当前的更新向量中,其具体实现为在每次迭代过程中,计算梯度和误差,更新速度v和参数θ

式中,vn表示之前所有步骤累积的动量和。加入动量项更新与普通SGD法效果对比如图2.15所示。图中幅值较小较集中的前进线为SGD法+动量法的计算方向,幅值较大的为普通SGD法的计算方向。可以看到,幅值较大,前进线大幅度徘徊着向最低点前进,优化效率较低,过程振荡。对SGD法+动量法,由于动量积攒了历史的梯度,如果前一时刻的梯度与当前的梯度方向几乎相反,则因为受前一时刻的影响,当前时刻的梯度幅度会减小;反之,则会加强。

图2.15 基于动量项的SGD示意

形象地看,动量法就像我们从山上推下一个球,球在滚落过程中累积动量,速度越来越快,直到达到终极速度。在梯度更新过程中,可对在梯度点处具有相同方向的维度,增大其动量项,而对在梯度点处改变方向的维度,减小其动量项。

Nesterov加速梯度下降(Nesterov Accelerated Gradient,NAG)法是动量法的一个变种,同样是一阶优化算法,但在梯度评估方面有所不同。NAG法能给动量项一个预知的能力,并且收敛速度更快。其更新算法如下。

我们利用动量项γvn更新参数θ,通过计算(θ-γvn)得到参数未来位置的一个近似值。计算关于参数未来的近似位置的梯度,而不是计算关于当前参数θ的梯度,这样NAG法可以高效求解。

我们可以将其做以下形象的描述:当球滚落时,其一般是盲目地沿着某个斜率方向下落的,结果并不一定令人满意,于是我们希望有一个较为智能的球,它能够自己判断下落的方向,这样在途中遇到斜率上升时,能够减速。该思想对于提升RNN性能有重要的意义。

2.AdaGrad、Adadelta与RMSProp算法

上述方法中对所有参数使用了同一个更新速率,但同一个更新速率不一定适合所有参数。例如,有的参数可能已经到了仅需要微调的阶段,而有些参数由于对应样本少等原因,还需要较大幅度的调整。AdaGrad算法[21]就是针对这一问题提出的,其自适应地为各个参数分配不同的学习率。其计算公式如下。

式中,gt是当前的梯度;η是初始学习率;是一个比较小的数,用来保证分母非0。该算法的含义是,对于每个参数,随着其更新的总距离增大,其学习率也随之变慢。前期gt较小时,正则化项较大,能够放大梯度;后期gt较大时,正则化项较小,能够约束梯度,因此,该算法适合处理稀疏梯度。但该算法同样依赖人工设置一个全局学习率η,如果这个值设置过大,会使正则化项过于敏感,对梯度的调节过大。

AdaGrad算法存在以下问题:其学习率是单调递减的,训练后期学习率非常小,而且其需要手工设置一个全局的初始学习率。

Adadelta算法[22]的出现可较好地解决上述问题,其本质是对AdaGrad算法的扩展,其同样是对学习率进行自适应约束,但在计算时进行了简化。AdaGrad算法会累加之前所有的梯度平方,而Adadelta算法只累加固定大小的项,并且仅存储这些项近似计算对应的平均值。其计算公式如下。

Adadelta算法不依赖全局学习率,训练初、中期加速效果理想,训练后期反复在局部最小值附近抖动。

RMSProp算法可以算作Adadelta算法的一个特例,依然依赖全局学习率。RMSProp算法效果位于AdaGrad算法和Adadelta算法之间,适合处理非平稳目标,适用于RNN的优化。

3.Adam算法及其改进

Adam(Adaptive Moment Estimation)算法[23]本质上是带有动量项的RMSProp算法,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。其计算公式如下。

式中,mtnt分别是对梯度的一阶矩估计和二阶矩估计,即对期望E|gt|、的估计;是对mtnt的校正,近似为对期望的无偏估计。由计算公式可知,Adam算法可以根据梯度进行动态调整,从而对学习率有动态约束。

Adam算法的优点主要在于经过偏置校正后,每次迭代学习率都有一个确定的范围,使得参数比较平稳,对内存需求较小,适用于大多数非凸优化问题,尤其适合处理大数据集和高维空间问题。

Adamax算法是Adam算法的一种变形,其对学习率的上限提供了一个更简单的范围,计算公式如下。

Nadam算法类似于带有Nesterov动量项的Adam算法,对学习率有更强的约束,同时对梯度的更新也有更直接的影响。一般而言,在使用带动量项的RMSProp算法或Adam算法的情况下,大多可以使用Nadam算法取得更好的效果。

研究人员观察到,Adam系列方法之所以不能收敛到好的结果,是因为在优化算法中广泛使用的指数衰减方法会使得梯度的记忆时间太短。

在深度学习中,每个Mini-batch对结果的优化贡献是不一样的,有的产生的梯度特别有效,但也一视同仁地被时间所遗忘。基于此,ICLR2018最佳论文提出了AMSgrad算法[24],它使用过去平方梯度的最大值来更新参数。

相关研究表明,Adam算法的二阶矩平滑系数ν对收敛结果有影响,如果较低,动量衰减太大,模型容易不收敛;反之,模型的收敛容易不稳定。Adafactor[25]通过给μv本身增加一个衰减来缓解该问题。

Adam算法迭代到后期时,学习率不稳定,可能过大或过小,Adebound算法[26]通过设置上下界来约束学习率的大小,从而对Adam算法进行改进。

4.牛顿法、拟牛顿法与共轭梯度法

梯度下降法是基于一阶梯度进行优化的方法,牛顿法则是基于二阶梯度进行优化的方法,通常有更快的收敛速度。牛顿法利用局部一阶和二阶的偏导信息,推测整个函数的形状,进而求得近似函数的全局最小值,然后将当前最小值设定成近似函数的最小值。

不过牛顿法作为一种迭代算法,每步都需要求解目标函数的Hessian矩阵的逆矩阵,计算比较复杂。当Hesseian矩阵不可逆时,牛顿法不可计算;当问题规模比较大时,牛顿法计算量很大。

拟牛顿法用正定矩阵来近似Hessian矩阵的逆,不需要二阶导数的信息,简化了运算的复杂度。

共轭梯度法是一种通过迭代下降的共轭方向来避免Hessian矩阵求逆计算的方法,感兴趣的读者可以自行阅读更多的资料。

2.4.6 学习率策略

学习率是优化时非常重要的一个因子,在训练过程中,学习率通常都会发生变化,越是在训练后期,学习率通常会变得越小,有助于收敛的稳定。

下面对常见的学习率策略进行详细介绍。

1.Fixed

Fixed即固定学习率策略,这是最简单的一种配置,只需要一个全局的学习率参数,并在整个优化过程中保持不变。这是不常使用的策略,因为随着向全局最优点逼近,学习率应该越来越小,这样才能避免不跳过最优点。

2.Step

Step是指按照固定步长对学习率进行调整,如图2.16所示,学习率每经过10000次迭代后降低为原来的0.1倍。

图2.16 Step学习率策略示意

Step属于非连续型的变换,策略简单,而且效果通常较好。

3.Multistep

Multistep是非均匀步长降低策略,需要指定每次降低学习率的间隔。如图2.17所示,初始学习率为0.01,经过在迭代次数为10000、30000、60000次的3次调整后,学习率变为原来的0.1。

4.Exp

Exp是一种指数变化策略。令基准学习率为Baselr,新学习率为Newbr,则更新方法如下。

可知,这是连续变化的,学习率的衰减是指数级的,γ越大则衰减越慢。Caffe框架中直接使用了训练迭代次数iter作为指数,因为iter通常都是非常大的值,所以学习率衰减非常快。Exp是很常见的一种学习率策略,图2.18所示为不同γ值的Exp学习率曲线。

图2.17 Multistep学习率策略示意

图2.18 不同γ值的Exp学习率曲线

5.Inv

Inv是一种指数变换策略,令基准学习率为Baselr,新学习率为Newlr,则更新方法如下。

参数γ控制曲线下降的速率,而参数power控制曲线在饱和状态下学习率达到的最低值。当初始学习率为0.01,γ=0.01,power分别为0.25和0.75时采用Inv策略所得的学习率变化如图2.19所示。

6.Poly

Poly是一种指数变换策略,令基准学习率为Baselr,新学习率为Newlr,当前迭代次数为iter,最大迭代次数为maxiter,则更新方法如下。

图2.19 Inv学习率策略示意

参数power控制曲线的形状,当power=1时,学习率曲线为一条直线;当power<1时,学习率曲线是凸的,且下降速率由慢到快;当power>1时,学习率曲线是凹的,且下降速率由快到慢,如图2.20所示。

图2.20 Poly学习率策略示意

7.Sigmoid策略

Sigmoid策略是一种学习率曲线形状为Sigmoid函数的策略,令基准学习率为Baselr,新学习率为Newlr,当前迭代次数为iter,学习率变更拐点为stepsize,则更新方法如下。

参数γ控制曲线的变化速率,图2.21展示了不同γ值下的学习率变化曲线。

除了以上学习率策略,还有一些较新的学习率策略,如Warmup,读者可以自行了解。

图2.21 Sigmoid学习率策略示意

2.4.7 正则化方法

在深度学习模型中,模型参数量巨大会导致产生过拟合。在理想情况下,设计的模型不仅要在训练数据上表现好,并且能在新输入的数据上有较好的泛化效果,也就是具有良好的泛化能力。相应地,测试集的误差也被称为泛化误差。

1.过拟合和欠拟合

在机器学习中,泛化能力的好坏最直观的表现就是模型的过拟合(Overfitting)与欠拟合(Underfitting)。过拟合和欠拟合用于描述模型在训练过程中的两种状态,一般来说,训练曲线如图2.22所示。

图2.22 模型性能和误差曲线

训练刚开始时,模型还在学习过程中,训练集和测试集的性能都比较差,这时模型还没有学习到知识,处于欠拟合状态,曲线落在欠拟合区域;随着训练的进行,训练集和测试集的误差都下降。随着进一步训练,模型在训练集上表现得越来越好,终于在突破一个点之后,训练集的误差下降,测试集的误差上升,这时就进入了过拟合区域。

如果数据集很小或模型太大,就会出现过拟合现象,有很多方法可以减轻模型的过拟合程度,如正则化和数据扩增。

Regularization即正则化,它的目标是让经验风险和模型复杂度同时较小。正则化是深度学习中非常重要且能有效减小泛化误差的技术,它以增大训练集误差为代价来减小泛化误差。如果训练集误差很小,可能出现过拟合的情况,一个能够最小化泛化误差的模型都需要一定程度的正则化。

添加了正则化后的优化目标如下。

式中,V是损失函数,它表示当输入xi预测输出为f(xi,而真实标签为yi时,应该给出多大的惩罚。

式(2.62)中的λRf)就是正则项,它约束了模型的表达能力。其中,f是模型;Rf)是一个与模型复杂度相关的函数,随着复杂度的增加而单调递增。

模型的表达能力跟模型大小(参数量)和参数的具体分布有关系,式(2.62)所表达的只是狭义上的参数正则化,广义上的正则化方法众多。

根据具体的使用策略不同,有直接提供正则化约束的参数正则化方法,如L1/L2正则化;也有通过工程上的技巧来实现更低泛化误差的方法,如训练提前停止(Early Stopping)和模型集成(Essemable),它们统称为经验正则化;还有不直接提供约束的隐式正则化方法,如数据增强等。

2.提前停止

在模型训练过程中,经常会出现随着不断迭代,训练误差不断减小,但验证误差先减小后开始增大的情况。提前停止是指在验证误差不再减小后,提前结束训练,而不是一直等待直至验证误差达到最小值。该方法不需要改变原有损失函数,简单且执行效率高,但需要一个额外的空间来存储一份参数。在确定训练迭代次数后,有两种策略来充分利用训练数据:一是将全部训练数据一起训练固定的迭代次数;二是迭代训练流程,直到训练误差小于提前停止策略设置的验证误差。

3.模型集成

模型集成化方法(Model Ensemble Methods)是一种通用的减小泛化误差的方法,其通过合并多个模型的结果来得到更好的性能。对于这些模型,可以使用不同的网络结构、不同的初始化方法、不同的数据集来训练模型,也可以在测试时使用不同的测试图片进行预测,得到多个模型的结果后将其进行平均或采用其他表决方案。

Dropout[27]被认为是集成了大量深层神经网络的集成方法,在2014年提出后被广泛使用。Dropout在训练过程中随机地丢弃一部分输入,此时丢弃部分对应的参数不会更新。所谓的丢弃,其实就是让激活函数的输出为0。

对于一个有n个节点的神经网络,有了Dropout后其就可以看作2n个模型的集合。根据丢弃比例的不同,在测试时Dropout会给输出乘以相应的系数。例如,某一层在训练时只保留50%的权重,在测试时需要用到所有参数,就给该层的权重乘以0.5。

关于Dropout的有效性,从结构上来说,它消除或减弱了神经元节点间的联合,降低了网络对单个神经元的依赖,从而增强了泛化能力。最新的神经科学的研究发现,虽然某些神经元确实很重要,它们会选择性激活特定输入,如只对输入猫图特别敏感,对其他输入则完全不敏感,但删除这类神经元仍然不影响网络识别到猫,这表明Dropout即使删除一些非常重要的神经元也没有关系。

因为Dropout降低了模型的性能,所以对于原本需要容量为N的网络才能解决的问题,现在需要的容量为N/pp就是保留该节点的概率,这个概率通常为0.5~0.9,p=1就是普通的网络。另外,因为Dropout相当于增加了噪声,造成了梯度的损失,所以需要使用更大的学习率和动量项。

Dropout的一个变种是DropConnect,与Dropout直接把神经元的值设置为0不同,DropConnect将连接参数权重设置为0,比Dropout更加灵活,可视为Dropout的一般化形式。从模型集成的角度来看,Dropout是2n个模型的集成,而DropConnect则是更多模型的集成,因为权重连接的数目比节点数本身更多,所以DropConnect模型集成能力更强。

DropConnect和Dropout都可以获得有限的泛化性能,在模型中均引入了稀疏性,不同之处在于DropConnect引入的是权重的稀疏而不是层的输出向量的稀疏。

除此之外,Maxout激活函数选择最大的输入作为激活输出、随机池化中随机选择神经元等方法都可以认为是模型集成的策略,也被验证能提升网络的性能[28]

4.参数惩罚

通过对模型参数添加惩罚参数来限制模型能力,也是常用的正则化策略,其通过在损失函数的基础上添加范数约束来实现:

在通常情况下,深度学习中只对权重参数ω添加约束,对偏置项不加约束,主要原因是偏置项一般需要较少的数据就能精确拟合,如果添加约束常常会导致欠拟合。

L2范数约束是常用的方法,它也是我们熟知的权重衰减:

L1范数约束也是常用的方法:

L1范数约束相对于L2范数约束能够产生更加稀疏的模型,且在参数ω比较小的情况下会直接缩减至0,可以起到特征选择的作用,也称为LASSO问题。如果从概率角度进行分析,范数约束相当于对参数添加先验分布,其中L2范数约束相当于假定参数服从高斯先验分布,L1范数约束相当于假定参数服从拉普拉斯分布。

5.训练样本扩充

以上4种方法都是显式的规整化方法,而实际上防止过拟合最有效的方法是增加训练样本,这是隐式的规整化方法。训练集合越大,过拟合概率越小。数据集合扩充是一个省时、有效的方法,在不同领域扩充方法不同:在图像领域,常用的方法是将图片进行旋转、缩放等;在语音识别领域则是对输入数据添加随机噪声;在自然语言问题中的常用思路则是进行近义词替换。