本文是UPC Deep Learning Course总结翻译系列的第一篇,主要课程内容是前馈神经网络。讲义原文参考:Feedforward Nets and Conv Nets (lecturer: Dario Garcia)。
本文对人工神经网络(Artificial Neural Networks)的主要内容进行简要介绍,感兴趣部分可根据参考论文进行详细学习。
人工神经网络领域的第一篇论文诞生于1943年,由Warren McCulloch和Walter Pitts发表1。在这篇论文中两人试图解释大脑是如何使用神经元这一简单的处理单元来计算高度复杂的行为,并设计了多输入权重的单个神经元模型来模拟人类神经元。
1958年,Frank Rosenblatt基于McCulloch和Walter Pitts的神经元理论提出感知器算法2,感知器是一个将实值输入映射为0/1输出的二元分类器。
f(x)={1 if w⋅x+b>00 otherwise f ( x ) = { 1 i f w ⋅ x + b > 0 0 o t h e r w i s e
(其中,w是权重向量,b是偏移常量)
Rosenblatt在 “Mark I Perceptron”3中首次实践采用了感知器算法。“Mark I Perceptron”是一个由400个光敏感受器组成的视觉分类器,与512个步进电机相关联,输出8个神经元4。它仅仅包含一层可训练的参数,关于这一感知器的更多细节可参考56。
Rosenblatt在一系列出版物中承认他的感知器存在局限性,与此同时,Minsky和Papert出版了“Perceptrons: an introduction to computational geometry”一书,详细介绍了感知器的局限性7。 Minsky和Papert的工作对公众产生了巨大影响,尽管很少有人真正理解他们研究的本质。 简言之,Minsky和Papert认为对于某些基本问题,例如异或问题,单层网络不能满足需求,然而当时并没有适合多层网络进行训练的算法,因此70年代人工神经网络的资金开始大幅减少直至80年代中期,在人工神经网络几乎被放弃之后,人工智能研究的重点开始转向“专家系统”,虽然这些系统在90年代也将遭遇自己的“人工智能寒冬”。
1974年,Werbos提出了针对多层神经网络训练的反向传播算法8。1985年,Rumelhart,Geoffrey E. Hinton和Williams重新发现该算法9并使其获得广泛关注,重新引发了人们对于人工神经网络的研究兴趣,“AI寒冬”时期结束。
要训练多层神经网络,首先从输入开始正向传递直至到达网络的最后一层,然后将神经网络预测的输出标签与标定正确的真实数据标签(the ground truth label)进行比较,并使用损失函数计算误差,通过找到损失函数最小化的最佳梯度(尽管是偏导数)更新网络最末端一层的权重。然后,应用链式规则反向传播,通过将前一层本地计算的梯度与向前传递的梯度相乘,得出那些不直接与输出层相连的隐层的输入值使得损失函数最小化的梯度,如下面的计算图所示。当需要手动推导计算反向传播算法时,简单实用的方法是绘制计算图(computing graph)再代入数值。
权重根据梯度方向进行优化,具体调整的变化值通常使用随机梯度下降(SGD)算法进行计算。 SGD使用整个数据集的子集(mini-batch SGD)而不是完整的数据集迭代估计优化的最佳方向,因为整个数据集可能非常大,因而是随机的梯度下降并不能保证每一步都是最优方向。除SGD算法外,还有其他替代方案可用于计算权重的变化值进行权重优化,我们将在“适应性学习方法”一节中进行介绍。
对感知器和反向传播算法等神经网络的系统学习有兴趣可进一步阅读其他相关文章资源10,包括反向传播算法的详细数学解释11、以一组数据为例计算反向传播算法各步骤执行结果12以及了解反向传播算法背后实现原理对解决梯度消失、死亡ReLU单元和RNN梯度爆炸等问题的帮助13,关于算法的一步步导数的数学推导解释可参考14,也可学习Stanford CS231n:Convolutional Neural Networks for Visual Recognition课程的相关内容。
伴随着新的训练方法的出现,ANN的研究重新活跃起来。1989年,Yann LeCun,现任Facebook人工智能研究院院长,使用美国邮政局提供的数据开发了一个数字识别系统15,首次展示了如何使用人工神经网络解决复杂的实际问题。LeCun的系统包含一层卷积神经元,基于1980年Fukushima提出的用于视觉模式识别的层次神经网络16,这是目前卷积神经网络的雏形。
人工神经网络的每个神经元使用激活函数来确定多个权重输入对应的输出结果。Rosenblatt的感知器使用最简单的二元函数,如果 w⋅x+b>0 w ⋅ x + b > 0 则激活,输出1,否则不激活。如今我们可以选择其他更复杂的非线性激活函数,非线性激活函数使得神经网络能够对非线性模式进行学习。常用的激活函数包括17:
- Sigmoid函数: f(x)=11+e−x f ( x ) = 1 1 + e − x
- 修正线性单元/整流线性单元(The Rectified Linear Unit): f(x)=max(0,x) f ( x ) = m a x ( 0 , x )
目前,ReLU是大多数情况下默认使用的激活函数,它使用固定的斜率避免了梯度消失问题18,梯度消失的主要问题是当使用Sigmoid和Tanh这类将大范围的输入挤到[0,1]或[-1,1]小范围输出区间的激活函数时,随着神经网络误差的反向传播,前层的权重变化对输出结果的影响越来越小直至梯度为零终止学习。
然而,ReLU单位在训练期间可能“死亡”。例如,流过ReLU神经元的大梯度可能导致权重的更新使得神经元无法在任何数据上激活。如果发生这种情况,那么流经该单元的梯度将从该点开始永远为零。也就是说,ReLU单元在训练期间不可逆转地死亡,可以从数据流中被淘汰。例如,如果学习率设置得太高,可能会发现多达网络中40%的神经元可能“死亡”。通过适当设置学习率可以解决该问题。关于激活函数可进一步学习Stanford CS231n课程的相关内容19。神经网络的优化的研究思路可从激活函数优化入手,例如针对手机应用ReLU激活函数时对非饱和区进行优化以大幅提升神经网络性能。
- Leaky ReLU: f(x)=max(0.1x,x) f ( x ) = m a x ( 0.1 x , x )
Leaky ReLU试图解决dying ReLU问题,当x <0时,函数不是零,而将具有小的负斜率(大约为0.01)。
训练次数(Epochs)和批次大小(Batch Size)
Epoch对应训练集的所有图像都训练被一次的阶段,通常,ANN训练需要许多次,因为每个输入实例将网络参数指引向不同方向,并且网络能够在受到其他实例训练影响后对之前训练过的实例再次训练,从同一示例中不止一次地学习。通常,当epoch次数过多,网络最终将过拟合。过拟合可以通过训练集上的损失降低同时测试集上损失开始上升来识别。
批次大小定义了在单次网络前向和反向传播过程中的输入实例的数量,是网络能够“一起看到”的输入数量。批次大小的范围从1到完整数据集大小。较大的批次大小能够更快地训练,但可能会降低精确度20。批次大小太小可以通过损失函数的噪声21来识别,即某一批次的损失与下一批次是否显著不同。当批次大小越小时摆动越明显,当批次大小等于数据集大小时噪声损失函数方差最小(除非学习率太高,在这种情况下网络无法收敛)。最常用的批次大小为16和32。
w = np.random.randn(n) * sqrt(2.0/n)
- 普通SGD(Vanilla update):
xt+1=xt+learningrate∗dx x t + 1 = x t + l e a r n i n g r a t e ∗ d x
(梯度为损失函数下降的方向)- 动量SGD(Momentum update):增加速度值(velocity)初始化为0
vt+1=rho∗vt+dx v t + 1 = r h o ∗ v t + d x
(rho表示摩擦friction,通常设为0.9或0.99)
xt+1=xt+learningrate∗vt+1 x t + 1 = x t + l e a r n i n g r a t e ∗ v t + 1- Nesterov动量:
xhead=xt+rho∗vt x h e a d = x t + r h o ∗ v t
vt+1=rho∗vt+dxhead v t + 1 = r h o ∗ v t + d x h e a d
xt+1=xt+vt+1 x t + 1 = x t + v t + 1
关于如何优化这些参数的几个技巧,可参考Stanford cs231n超参数优化部分24。
SGD学习方法对学习率,动量,权量衰减等诸多参数的调参挑战促使了其他自动化调参学习方法的出现。其中,广受欢迎的方法有Adagrad,Adadelta,RMSprop和Adam。关于这些适应性学习方法的详细介绍参见梯度下降的优化内容25。
- Adagrad: 记录所有梯度的平方和,使得能够在较缓的维度上除以一个较小值进行加速而在较陡的维度上除以一个较大值从而减速。但由于梯度的平方和越来越大,步幅会越来越小,可能会停在鞍点处无法出来,因而Adagrad只适用于卷积层的学习。
gradSquared+=dx∗dx g r a d S q u a r e d + = d x ∗ d x
xt+1=xt+learningrate∗dx/(np.sqrt(gradSquared)+eps) x t + 1 = x t + l e a r n i n g r a t e ∗ d x / ( n p . s q r t ( g r a d S q u a r e d ) + e p s )
- RMSprop: RMSprop在Adagrad基础上进行小幅改动,对梯度的平方和进行衰减,衰减率(decay rate)通常设为0.9或0.99。
gradSquared=decayrate∗gradSquared+(1−decayrate)∗dx∗dx g r a d S q u a r e d = d e c a y r a t e ∗ g r a d S q u a r e d + ( 1 − d e c a y r a t e ) ∗ d x ∗ d x
xt+1=xt+learningrate∗dx/(np.sqrt(gradSquared)+eps) x t + 1 = x t + l e a r n i n g r a t e ∗ d x / ( n p . s q r t ( g r a d S q u a r e d ) + e p s )
- Adam: Adam结合了上述两种方法和动量项,最为常用。
网络的学习能力由其权重数量和深度定义。深层架构通常有数百万参数(AlexNet有60M参数,VGG16有138M参数),其中大量参数来自全连接层,因为卷积层通过权重共享能够大大减少它们的数量。一个具有4,096个神经元的全连接层加上输入层的4,096个神经元就将包含16M参数(4,096 x 4,096)。具有如此多参数的模型对任何训练数据集都很容易过拟和,因为它具有很强的记忆它的能力。为避免过拟合问题,用于深度架构的正则化方法被提出,常用的正则化方法包括:
- L1 / L2正则化:该方法试图通过对每个权重的平方增加惩罚(将 12λw2 1 2 λ w 2 项加入到loss函数中)来避免权重尖峰值的影响。
批标准化和层标准化、Dropout方法以及数据增量本质都是通过在训练阶段增加某些随机性然后在测试时进行估计将随机性平均化从而实现正则化29。
参考文献