本文是深度学习总结系列的第一篇,主要内容是神经网络的基础知识,最初版本翻译自:Feedforward Nets and Conv Nets (lecturer: Dario Garcia)。
本系列更多文章传送门:第二篇 [Deep Learning] 卷积神经网络 CNNs;第三篇 [Deep Learning] 集成学习Ensemble Learning&迁移学习Transfer Learning ;第四篇 [ [Deep Learning] 递归神经网络RNN ](https://www.jianshu.com/p/5c22b41e9f07)。
本文对人工神经网络(Artificial Neural Networks)的基础内容进行介绍,主要内容包括:
- 神经网络发展史
1.1 感知器
1.2 反向传播和梯度下降 - 激活函数
- 常用参数
- 优化方法
- 正则化方法
1. 神经网络发展史 A Bit of History
人工神经网络领域的第一篇论文诞生于1943年,由Warren McCulloch和Walter Pitts发表[1]。在这篇论文中两人试图解释大脑是如何使用神经元这一简单的处理单元来计算高度复杂的行为,并设计了多输入权重的单个神经元模型来模拟人类神经元。
1.1 感知器 Rosenblatt’s Perceptron
1958年,Frank Rosenblatt基于McCulloch和Walter Pitts的神经元理论提出感知器算法[2],感知器是一个将实值输入映射为0/1输出的二元分类器。
-
(其中,w是权重向量,b是偏移常量)
Rosenblatt在 “Mark I Perceptron”[3]中首次实践采用了感知器算法。“Mark I Perceptron”是一个由400个光敏感受器组成的视觉分类器,与512个步进电机相关联,输出8个神经元[3]。它仅仅包含一层可训练的参数,关于这一感知器的更多细节可参考[4][5]。
Rosenblatt在一系列出版物中承认他的感知器存在局限性,与此同时,Minsky和Papert出版了“Perceptrons: an introduction to computational geometry”一书,详细介绍了感知器的局限性 [6]。 Minsky和Papert的工作对公众产生了巨大影响,尽管很少有人真正理解他们研究的本质。 简言之,Minsky和Papert认为对于某些基本问题,例如异或问题,单层网络不能满足需求,然而当时并没有适合多层网络进行训练的算法,因此70年代人工神经网络的资金开始大幅减少直至80年代中期,在人工神经网络几乎被放弃之后,人工智能研究的重点开始转向“专家系统”,虽然这些系统在90年代也将遭遇自己的“人工智能寒冬”。
1.2 反向传播和随机梯度下降 Backpropagation and Stochastic Gradient Descent
1974年,Werbos提出了针对多层神经网络训练的反向传播算法[7]。1985年,Rumelhart,Geoffrey E. Hinton和Williams重新发现该算法[8]并使其获得广泛关注,重新引发了人们对于人工神经网络的研究兴趣,“AI寒冬”时期结束。
要训练多层神经网络,首先从输入开始正向传递直至到达网络的最后一层,然后将神经网络预测的输出标签与标定正确的真实数据标签(the ground truth label)进行比较,并使用损失函数计算误差,通过找到损失函数最小化的最佳梯度(尽管是偏导数)更新网络最末端一层的权重。然后,应用链式规则反向传播,通过将前一层本地计算的梯度与向前传递的梯度相乘,得出那些不直接与输出层相连的隐层的输入值使得损失函数最小化的梯度,如下面的计算图所示。当需要手动推导计算反向传播算法时,简单实用的方法是绘制计算图(computing graph)再代入数值。
权重根据梯度方向进行优化,具体调整的变化值使用梯度下降计算。
目前常用的随机梯度下降(SGD)的“随机”性主要体现在:SGD使用整个数据集的子集(mini-batch SGD)而不是完整的数据集迭代估计优化的最佳方向,因为整个数据集可能非常大,因而是随机的梯度下降并不能保证每一步都是最优方向。除SGD算法外,现在已有更多改进方案可用于计算权重的变化值进行权重优化,我们将在“优化方法”一节中进一步介绍。
对感知器和反向传播算法等神经网络的系统学习有兴趣可进一步阅读其他相关文章资源[9],包括反向传播算法的详细数学解释[10]、以一组数据为例计算反向传播算法各步骤执行结果[11]以及了解反向传播算法背后实现原理对解决梯度消失、死亡ReLU单元和RNN梯度爆炸等问题的帮助[12],关于算法的一步步导数的数学推导解释可参考[13],也可学习Stanford CS231n:Convolutional Neural Networks for Visual Recognition课程的相关内容。
伴随着新的训练方法的出现,ANN的研究重新活跃起来。1989年,Yann LeCun,现任Facebook人工智能研究院院长,使用美国邮政局提供的数据开发了一个数字识别系统[14],首次展示了如何使用人工神经网络解决复杂的实际问题。LeCun的系统包含一层卷积神经元,基于1980年Fukushima提出的用于视觉模式识别的层次神经网络[15],这是目前卷积神经网络的雏形。
2. 激活函数 Activation Functions
人工神经网络的每个神经元使用激活函数来确定多个权重输入对应的输出结果。Rosenblatt的感知器使用最简单的二元函数,如果则激活,输出1,否则不激活。如今我们可以选择其他更复杂的非线性激活函数,非线性激活函数使得神经网络能够对非线性模式进行学习。常用的激活函数包括[16]:
- Sigmoid函数:
- Tanh函数:
- 修正线性单元/整流线性单元(The Rectified Linear Unit):
目前,ReLU是大多数情况下默认使用的激活函数,它使用固定的斜率避免了梯度消失问题 [17],梯度消失的主要问题是当使用Sigmoid和Tanh这类将大范围的输入挤到[0,1]或[-1,1]小范围输出区间的激活函数时,随着神经网络误差的反向传播,前层的权重变化对输出结果的影响越来越小直至梯度为零终止学习。
划分指数级空间 具有足够的表达能力
然而,ReLU单位在训练期间可能“死亡”。例如,流过ReLU神经元的大梯度可能导致权重的更新使得神经元无法在任何数据上激活。如果发生这种情况,那么流经该单元的梯度将从该点开始永远为零。也就是说,ReLU单元在训练期间不可逆转地死亡,可以从数据流中被淘汰。例如,如果学习率设置得太高,可能会发现多达网络中40%的神经元可能“死亡”。通过适当设置学习率可以解决该问题。关于激活函数可进一步学习Stanford CS231n课程的相关内容[18]。神经网络的优化的研究思路可从激活函数优化入手,例如针对手机应用ReLU激活函数时对非饱和区进行优化以大幅提升神经网络性能。
- Leaky ReLU:
Leaky ReLU试图解决dying ReLU问题,当x <0时,函数不是零,而将具有小的负斜率(大约为0.01)。
- Maxout:
ReLU和Leaky ReLU都是这一函数的特例,例如ReLU对应w1,b1=0。
3. 训练参数 Training Parameters
3.1 训练次数(Epochs)和批次大小(Batch Size)
Epoch对应训练集的所有图像都训练被一次的阶段,通常,ANN训练需要许多次,因为每个输入实例将网络参数指引向不同方向,并且网络能够在受到其他实例训练影响后对之前训练过的实例再次训练,从同一示例中不止一次地学习。通常,当epoch次数过多,网络最终将过拟合。过拟合可以通过训练集上的损失降低同时测试集上损失开始上升来识别。
批次大小定义了在单次网络前向和反向传播过程中的输入实例的数量,是网络能够“一起看到”的输入数量。批次大小的范围从1到完整数据集大小。较大的批次大小能够更快地训练,但可能会降低精确度[19]。批次大小太小可以通过损失函数的噪声[20]来识别,即某一批次的损失与下一批次是否显著不同。当批次大小越小时摆动越明显,当批次大小等于数据集大小时噪声损失函数方差最小(除非学习率太高,在这种情况下网络无法收敛)。最常用的批次大小为16和32。
3.2 学习率
- 学习率定义了每一步权重优化时的调整比例。通常,使用完全导数(学习率为1)会导致过度修正,学习率太大可能使得神经元在定义的高维空间内产生大的“跳跃”,从而无法收敛。学习率太小会使朝着最佳权重调整的步幅太小,训练时间过长[21]。较好的选择是从较小的学习速率开始使权重调整走向正确的方向,然后逐渐增大以加快收敛。在训练期间跟踪的首先是loss,因为它在前向传递期间在各个批次上被评估。绘制不同学习率下loss随时间的变化可以帮助我们更好地了解学习率的选择。
3.3 其他参数
还有许多其他参数可能会影响学习过程,包括:
- 权重衰减:每次更新后,权重会乘以一个0到1之间的因子。这是一种正则化的式。
- 权重初始化:训练开始前的初始权重和偏差值bias是训练结果的关键。针对ReLU激活函数的神经元,其权重初始化通常使用随机数并使用来平衡方差[22],而bias通常直接初始化为零。
w = np.random.randn(n) * sqrt(2.0/n)
- 改进优化方法中的其他参数,例如动量
4. 优化方法
一阶方法
梯度下降二阶方法
Hessian 矩阵
牛顿法
用hessian矩阵替代学习率->自适应
但计算量太大->近似算法共轭牛顿法
伪牛顿法
动量:增加动量项能够使得SGD能够跳出局部最小值(local minima)和鞍点(saddle point),加快在鞍点附近梯度缓慢处的前进。此外,增加动量项还能解决使用SGD时的Poor Conditioning:当损失函数在一个方向上改变很快而在另一方向改变很慢,使用普通SGD会出现在变化敏感方向上的锯齿跳动,这种情况在高维下很常见。动量项将先前权重更新的一小部分添加到当前权重更新中。如果两次更新在同一方向则会加快收敛,而更新在不同方向上时则会平滑方差,从而能够尽快结束这种情况下的曲折前进(Zigzagging)。
- 普通SGD(Vanilla update):
(梯度为损失函数下降的方向)- 动量SGD(Momentum update):增加速度值(velocity)初始化为0
(rho表示摩擦friction,通常设为0.9或0.99)
- Nesterov动量:
关于如何优化这些参数的几个技巧,可参考Stanford cs231n超参数优化部分[20]。
适应性学习方法 Adaptative Learning Methods
SGD学习方法对学习率,动量,权量衰减等诸多参数的调参挑战促使了其他自动化调参学习方法的出现。其中,广受欢迎的方法有Adagrad,Adadelta,RMSprop和Adam。关于这些适应性学习方法的详细介绍参见梯度下降的优化[23]。
最早的牛顿法中通过计算Hessian矩阵可以反映坡度的陡缓,但计算量太大,需要使用full batch。
- Adagrad: 记录所有梯度的平方和,使得能够在较缓的维度上除以一个较小值进行加速而在较陡的维度上除以一个较大值从而减速。但由于梯度的平方和越来越大,步幅会越来越小,可能会停在鞍点处无法出来,因而Adagrad只适用于卷积层的学习。
其中eps防止
- RMSprop: RMSprop在Adagrad基础上进行小幅改动,对梯度的平方和进行衰减,衰减率(decay rate)通常设为0.9或0.99。实现了指数移动平均,类似于lstm的遗忘门。
-
Adam: Adam结合了上述两种方法和动量项,最为常用。
5. 正则化方法 Regularization Methods
网络的学习能力由其权重数量和深度定义。深层架构通常有数百万参数(AlexNet有60M参数,VGG16有138M参数),其中大量参数来自全连接层,因为卷积层通过权重共享能够大大减少它们的数量。一个具有4,096个神经元的全连接层加上输入层的4,096个神经元就将包含16M参数(4,096 x 4,096)。具有如此多参数的模型对任何训练数据集都很容易过拟和,因为它具有很强的记忆它的能力。为避免过拟合问题,用于深度架构的正则化方法被提出,常用的正则化方法包括:
- L1 / L2正则化:该方法试图通过对每个权重的平方增加惩罚(将项加入到loss函数中)来避免权重尖峰值的影响。
- Dropout [24]:该方法在训练期间以一定的概率设置部分神经元为0,在全连接层上简单有效。Dropping概率p通常设为0.5,但dropout会导致输出结果随机,因此在测试时,根据概率计算的平均结果我们需要将激活函数乘以dropping概率进行伸缩作为最终结果,或在训练时的dropout mask步骤直接除以dropping概率。
- 批标准化[25]:该方法对每批次输入的均值和方差进行标准化,通常用在全连接层之后。它既可以作为正则化方法,也可以解决与权重初始化相关的问题,同时也可以加速收敛。
- 层标准化[26]:该方法类似于批标准化,但均值和方差是在每层计算的。这对于批标准化不能直接应用的RNN和完全连接层十分有用,但不适用卷积层。它可以比批标准化更快地加速收敛。
- Data Augmentation数据增量:对同一张图片进行随机剪切、伸缩旋转、水平变换、改变亮度对比度、透镜畸变等操作后作为输入数据对网络进行训练。
- Dropconnect:将权重矩阵中的某些值随机设为0,丢弃某些连接。
- Fractional Max Pooling:采用不同的pooling区域并在测试时固定平均。
- Stochastic Depth:在训练深度非常深的网络时随机丢弃某些层,在测试时再恢复全部使用。
批标准化和层标准化、Dropout方法以及数据增量本质都是通过在训练阶段增加某些随机性然后在测试时进行估计将随机性平均化从而实现正则化[27]。
参考文献
-
McCulloch, Warren S., and Walter Pitts. “A logical calculus of the ideas immanent in nervous activity.” The bulletin of mathematical biophysics 5.4 (1943): 115-133. ↩
-
Rosenblatt, Frank. “The perceptron: A probabilistic model for information storage and organization in the brain.” Psychological review 65.6 (1958): 386 ↩
-
Mark I Perceptron Operators’ Manual ↩ ↩
-
Kurzweil, Ray. How to create a mind: The secret of human thought revealed. Penguin, 2013. ↩
-
http://www.andreykurenkov.com/writing/a-brief-history-of-neural-nets-and-deep-learning/ ↩
-
https://en.wikipedia.org/wiki/Perceptrons_(book) ↩
-
Webos, Paul John. “Beyond regression: New tools for prediction and analysis in the behavioral sciences.” Doctoral Dissertation, Applied Mathematics, Harvard University (1974) ↩
-
Rumelhart, David E., Geoffrey E. Hinton, and Ronald J. Williams. Learning internal representations by error propagation. No. ICS-8506. California Univ San Diego La Jolla Inst for Cognitive Science, 1985. ↩
-
http://www.andreykurenkov.com/writing/a-brief-history-of-neural-nets-and-deep-learning/ ↩
-
http://neuralnetworksanddeeplearning.com/chap2.html ↩
-
https://becominghuman.ai/back-propagation-is-very-simple-who-made-it-complicated-97b794c97e5c ↩
-
https://medium.com/@karpathy/yes-you-should-understand-backprop-e2f06eab496b ↩
-
https://medium.com/@erikhallstrm/backpropagation-from-the-beginning-77356edf427d ↩
-
LeCun, Yann, et al. “Backpropagation applied to handwritten zip code recognition.” Neural computation 1.4 (1989): 541-551. ↩
-
Fukushima, Kunihiko. “Neocognitron: A hierarchical neural network capable of visual pattern recognition.” Neural networks 1.2 (1988): 119-130. ↩
-
https://medium.com/the-theory-of-everything/understanding-activation-functions-in-neural-networks-9491262884e0 ↩
-
https://www.quora.com/What-is-the-vanishing-gradient-problem ↩
-
http://cs231n.github.io/neural-networks-1/#actfun ↩
-
https://github.com/fchollet/keras/issues/68 ↩
-
http://cs231n.github.io/neural-networks-3/ ↩ ↩
-
https://www.linkedin.com/pulse/gradient-descent-simple-words-parth-jha ↩
-
https://arxiv.org/abs/1502.01852 ↩
-
http://ruder.io/optimizing-gradient-descent/ ↩
-
Srivastava Nitish, Geoffrey E. Hinton, Alex Krizhevsky, Ilya Sutskever, and Ruslan Salakhutdinov. “Dropout: a simple way to prevent neural networks from overfitting.” Journal of Machine Learning Research 15.1 (2014): 1929-1958. ↩
-
Ioffe, Sergey, and Christian Szegedy. “Batch normalization: Accelerating deep network training by reducing internal covariate shift.” International Conference on Machine Learning. 2015. ↩
-
Ba, Jimmy Lei, Jamie Ryan Kiros, and Geoffrey E. Hinton. “Layer normalization.” arXiv preprint arXiv:1607.06450 (2016). ↩
-
http://cs231n.github.io/neural-networks-2/ ↩