【译】关于深度神经网络必须知道的一些技巧(上)

翻译自魏秀参博士的文章:Must Know Tips/Tricks in Deep Neural Networks

| 深度神经网络,特别是卷积神经网络(CNN),使得由许多处理层构成的计算模型能够完成对数据的多层抽象表示。它们已经非常显著地提高了计算机视觉诸多领域的现有水平,如物体识别,物体检测,文本识别等。并且还包括许多其他领域,如药物发现和基因研究。 此外,在计算机视觉领域,目前已有许多优秀的论文发表,而且诞生了不少高质量的CNN开源软件和学习框架。同时也出现了许多不错的CNN教程和手册。然而,关于如何从零开始实现一个出色的深度卷积神经网络,目前可能还是缺少一个较新的、较全面的总结。因此,我们收集并总结了许多DCNNs的实现细节。这里我们将介绍大量关于如何构建和训练神经网络的实现细节,也可以说是_技巧或秘诀_。 —|—

前言

我们假设你已经掌握了基本的深度学习知识,并且我们这里介绍的实现细节(技巧)是关于深度神经网络的,尤指用于图像相关任务的卷积神经网络(CNN),主要包括以下8个部分1)数据扩增2)数据预处理3)网络初始化4)训练过程中的一些技巧和注意事项5)激活函数的选择6)多种正则化方法7)深刻理解训练图8)组合多个网络。 另外,与本文对应的PPT在这里[slide]。如果关于这篇文章和PPT你有任何的疑问,或者发现了错误,或者还有其他重要的、有意思的东西你觉得应该加上,可以随时联系

1.数据扩增

因为深度网络需要使用大量的图片数据进行训练以达到满意的效果,如果原始的训练数据集数量较少,则应该对这些数据做一些扩增(Augmentation)来提高训练效果。其实,数据扩充已经成为了训练深度网络一个必不可少的步骤。

  • 数据扩增有许多方法,目前常用的有水平翻转随机剪裁颜色抖动。而且也可以尝试多种方式组合,比如同时对图像进行旋转和缩放。此外,可以调整一张图像中所有像素的饱和度和明度(饱和度S和明度V是指HSV色彩空间),调整方法具体是:先对S(或V值)进行幂运算,幂值在0.25~4之间,然后乘上一个0.7~1.4的系数,最后再加上一个-0.1~0.1的常数。这种方法同样适用于一个批(batch)大小里面的所有图像。也可以给色相(HSV色彩空间的H分量)加上1个-0.1~0.1的常数。
  • fancy PCA(Krizhevsky等人[1]在2012年训练注明的_Alex-Net_时提出)。Fancy PCA在训练过程中改变了图像RGB通道的值。在实际使用中,首先对训练图像RGB像素值做PCA降维,然后对于每张训练图像的每一个像素点(即

),叠加上:

,其中

分别是第i个特征向量和RGB像素值3x3协方差矩阵的特征值,

是服从高斯分布(均值为0,标准差为0.1)的随机数。每个

对于一张训练图像的所有像素点只初始化一次,直到这张图像再次用于训练。也就是说,当训练模型再次遇到同一张图像时,它会随机产生一个新的

用于数据扩增。在[1]中指出,fancy PCA可以近似地提取出图像中的重要信息,也就是说对色彩饱和度变化以及光照具有不变性。在分类性能上,这种方法在ImageNet 2012比赛中将top1错误降低了1%。

2.数据预处理

现在我们手上已经有了大量的训练数据了,不过可千万别着急!我们需要对这些数据做一下预处理。在这个章节我们将介绍几种预处理的方法。

第一种简单的处理方法就是对数据进行零中心化(zero-center),然后进行归一化(normalize)。使用Python代码表示如下:

>>> X -= np.mean(X, axis = 0) # zero-center

>>> X /= np.std(X, axis = 0) # normalize

其中X是输入数据。另一种方式是对每一个维度的数据进行归一化,使得最小值和最大值分别为- 1和1。如果不同的输入特征具有不同的尺度,但它们对学习算法的影响效果大致相等,这样进行数据预处理才有意义。对于图像而言,像素的相对尺度是差不多相同的(在0~255之间),所以预处理操作也不是十分必须的。

另外一种方法跟第一种方法差不多,叫做PCA白化(PCA Whitening)。首先同样是对数据进行零中心化,然后计算协方差,它展示了数据中的相关性结构:

>>> X -= np.mean(X, axis = 0) # zero-center

>>> cov = np.dot(X.T, X) / X.shape[0] # compute the covariance matrix

之后,把原始数据(已经零中心化)投射(projecting)到特征向量上进行去相关操作:

>>> U,S,V = np.linalg.svd(cov) # compute the SVD factorization of the data covariance matrix

>>> Xrot = np.dot(X, U) # decorrelate the data

最后一步就是白化操作,将上一个步骤得到的结果除以特征值:

>>> Xwhite = Xrot / np.sqrt(S + 1e-5) # divide by the eigenvalues (which are square roots of the singular values)

这里加上1e-5(一个很小的常量)是为了防止除0。这一步变换有个缺点是它会极度放大数据中的噪声,因为输入数据的所有维度(包括方差很小的不相关维度,绝大部分是噪声)变成了同等大小。可以通过增大平滑参数来减小噪声影响 (比如把1e-5再增大一点)。

值得注意的是,这里提到预处理操作是为了介绍的完整性。在卷积神经网络中,一般不采用预处理操作。但是零中心化和归一化还是十分必要的。

3.网络初始化

现在数据已经准备好了。但是在开始训练网络之前,必须对网络的参数进行初始化。

全零初始化

对数据进行适当的归一化后,理想的情况是希望权值(weights)初始化约为一半正数一半负数。一个听起来蛮合理的方案就是将权值全部初始化为0,因为从期望上来讲,0是最佳猜测。但事实上证明这样做是错误的,因为如果每个神经元具有同样的输出,那么在反向传播 (back- propagation)时就会计算得到同样的梯度值,参数的更新也就完全一样。换句话说,若权值初始化时都为同样的值,那么网络的各个神经元之间就缺少了不对称性。

随机初始化为较小的值

权值初始化为接近于0的值,但不完全等于0。每个权值都随机初始化为非常接近于0的值,这样就打破了网络的对称性(symmetry breaking)。在训练的开始阶段,所有神经元都是随机且唯一的,然后它们将进行不同的更新,成为整个网络不同的一部分。这种初始化方式很简单:

,其中

是均值为0,标准差为1的高斯分布。也可以使用服从均匀分布的较小值,但实际训练中发现其对最终训练结果的影响要小一些。

校正方差

上述随机初始化权值的方法存在一个问题,随着输入数据的增加,输出的方差也会增加。可以用随机初始化权值除以输入数据大小的开方,使得每个神经元输出的方差变为1,如下所示:

>>> w = np.random.randn(n) / sqrt(n) # calibrating the variances with 1/sqrt(n)

其中“randn”是产生高斯分布的函数,“n”表示输入数据的大小。这样使得网络中所有神经元在训练开始的时候具有大致相同的输出分布,实验也证明这会提高收敛速度。详细的推导过程可见PPT的18~23页,要说明的是,这个推导并没有考虑ReLU(修正线性单元,见第5章节)的影响。

推荐方法

上述校正方差的方法并未考虑ReLU的影响。最近He等人[4]提出了一种专为ReLU设计的初始化权值方法,得出的结论是:网络中神经元的方差应为

>>> w = np.random.randn(n) * sqrt(2.0/n) # current recommendation

[4]中的讨论,这也是当前推荐在实际中使用的方法。

4.训练过程

现在所有的准备工作都做好了,让我们开始训练网络吧!

  • 卷积核和池化的大小。训练过程中,输入图像的大小最好为2的幂,比如32(CIFAR-10),64,244(通常在ImageNet中使用),384或者512。另外采用较小的卷积核(比如3x3)和较小的滑动步长(比如1)并进行补0操作(zeros-padding)是比较重要的,这样不仅能够减少参数的个数,而且能够提高整个网络的准确率。同时,上面提到的3x3卷积核大小和滑动步长为1的组合用例,能够使得输入图像/输出特征保持大小一致(比如(32-3+2*1)/1+1=32)。对于池化层,池化大小通常为2x2。
  • 学习速率。如Ilya Sutskever在其博客[2]中所述,他建议将梯度值除以mini批大小(mini-batch size)。因此,如果在训练过程中改变了批大小,就不必要一直改变学习速率(LR)。为了得到一个合适的LR,可以使用验证集。通常,在训练开始的时候采用的LR为0.1。在实际训练过程中,若发现当前使用的LR在验证集上损失(loss)不再下降,可以尝试将LR除以2(或者5),再继续进行训练,会有惊喜发生。
  • 预训练模型调优(fine-tune)。目前,许多预训练好的模型被一些著名的研究团队公布,如Caffe Model ZooVGG Group。得益于这些预训练模型良好的泛化能力,可以直接拿来使用到自己的应用中。为了进一步提高这些模型在自己的训练集上的分类效果,一个简单有效的方法便是在自己数据集上对这些预训练模型进行调优(fine-tuning)。如下表所示,两个重要的因素:新数据集的大小,以及它与原始数据集之间的相似度。不同的情况应采用不同的调优策略。举例说明,比如你的数据集与预训练模型采用的训练数据集非常相似,在此情况下,若自己的数据集较小,只要在预训练模型最顶层输出特征上再训练一个线性分类器即可;若自己的数据集较大,可以使用一个较小的学习速率对预训练模型的最后几个顶层进行调优。如果自己的数据集与预训练模型采用的训练数据集相差较大但拥有足够多的数据,在这种情况下则需要对网络的多个层进行调优,同样也要使用较小的学习速率。还有一种情况是,自己的数据集不仅较小,而且与原始数据集相差较大,那这个就比较麻烦了。因为数据集较小,所以最好只训练一个线性分类器;因为数据差异很大,所以只对网络的最后几个顶层调优并不是很好的方案,因为这几个层包含了更多数据相关(dataset-specific)的特征。针对此种情况,在网络较为靠前的特征层就使用SVM分类器可能是相对而言较好的方案。

| 在自己的数据集上调优(fine-tune)预训练模型。不同情况下采用不同的调优策略。对于数据集,_Caltech- 101_与_ImageNet_比较相似,都是关于物体的数据集;而_Place Database_就与_ImageNet_不同,它是关于场景的数据集。 —|—

5.激活函数

激活函数(activation function)是深度网络几个重要特点之一,它使得网络具有非线性表达能力。这里将介绍几种常用的激活函数,然后提出一些使用建议。

| 图片来自Stanford CS231n —|—

Sigmoid

| sigmoid非线性函数:

它将实数“压扁”在0~1之间,正无穷趋向于1,负无穷趋向于0。sigmoid函数过去经常被使用,因为它很好地模拟了神经元的激活状态:从根本不被激活(0)到完全被激活(1)。 —|—

在实际使用中,已经很少采用sigmoid函数,因为它有两个主要的缺点:

  1. _sigmoid函数容易饱和梯度,并终止梯度传递。_sigmoid函数有个不太好的特性,就是当神经元的激活值饱和在0或1的“小尾巴”处时(见sigmoid函数图),这些区域的梯度值为0。在反向传播的过程中,这个(局部)梯度将会与整个损失函数关于该门单元(gate)输出的梯度相乘。因此,如果局部梯度的值非常小,它会“杀死”梯度,这样几乎就没有信号通过神经元传到权值并传到数据了。此外,为了防止梯度饱和,在初始化权值的时候需要特别注意。比如,若初始化权值过大,那么大多数神经元将会饱和,导致网络几乎失去学习能力。
  2. _sigmoid函数的输出不是零中心化的(zero-centered)。_这个特性也是不合需要的,因为网络中较后层的神经元将会收到非零中心化的数据。这将会影响梯度下降的过程,因为如果某个神经元的数据数据总是正数(如

中每个

),那么权值

的梯度在反向传播的过程中,要么全部为正数,要么全部为负数(具体依整个表达式

的梯度而定)。这样在权值梯度更新的时候就会出现“Z字形”锯齿。然而,当一个批大小(batch)里面数据的梯度叠加起来以后,一定程度上会缓解这个问题,因为一个批大小里面的梯度值有正有负。因此,这个缺点相比于上面的饱和梯度问题来说,只是个小麻烦,没有那么严重。

tanh(x)

| tanh非线性函数将实数“压扁”在[-1,1]之间,和sigmoid函数一样,它也存在饱和梯度的问题,但不同的是它的输出是零中心化的。因此,在实际使用中,tanh非线性函数比sigmoid非线性函数要用得多一些。 —|—

Rectified Linear Unit

| 修正线性单元(Rectified Linear Unit,ReLU)近年来非常受欢迎。其函数公式:

—|—

ReLU有以下优缺点:

  1. 优点)相比于sigmoid/tanh包含复杂的运算(如指数运算),ReLU只需要对矩阵进行简单的阈值计算(与0比较)得到。此外,ReLU没有饱和梯度的问题。
  2. 优点)与sigmoid/tanh相比,ReLU极大加速了梯度下降的收敛过程([1]中指出有加速6倍之多)。可以认为这是得益于ReLU线性、非饱和的特点。
  3. 缺点)不过,ReLU在训练过程中比较脆弱并且可能“死掉”。举例来说,当一个很大的梯度值经过ReLU神经元,可能当权值更新后,神经元将再也无法被其他任何数据激活。若这种情况发生,那么从此所有经过这个神经元的梯度都将变成0。也就是说,这个ReLU单元将在训练过程中不可逆转地死亡,因为它减少了数据的多样性。如果学习速率设置过高,可能会发现网络中40%的神经元都会死掉(即对于整个训练集,这些神经元都不会被激活)。通过设置合适的学习速率,可以降低这种情况发生的概率。

马上会更新《【译】关于深度神经网络必须知道的一些技巧(下)》,请稍等下。

参考文献&链接

  1. A. Krizhevsky, I. Sutskever, and G. E. Hinton. ImageNet Classification with Deep Convolutional Neural Networks. In NIPS, 2012
  2. A Brief Overview of Deep Learning, which is a guest post by Ilya Sutskever.
  3. CS231n: Convolutional Neural Networks for Visual Recognition of Stanford University, held by Prof. Fei-Fei Li and Andrej Karpathy.
  4. K. He, X. Zhang, S. Ren, and J. Sun. Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification. In ICCV, 2015.
  5. B. Xu, N. Wang, T. Chen, and M. Li. Empirical Evaluation of Rectified Activations in Convolution Network. In ICML Deep Learning Workshop, 2015.
  6. N. Srivastava, G. E. Hinton, A. Krizhevsky, I. Sutskever, and R. Salakhutdinov. Dropout: A Simple Way to Prevent Neural Networks from Overfitting. JMLR, 15(Jun):1929−1958, 2014.
  7. X.-S. Wei, B.-B. Gao, and J. Wu. Deep Spatial Pyramid Ensemble for Cultural Event Recognition. In ICCV ChaLearn Looking at People Workshop, 2015.
  8. Z.-H. Zhou. Ensemble Methods: Foundations and Algorithms. Boca Raton, FL: Chapman & HallCRC/, 2012. (ISBN 978-1-439-830031)
  9. M. Mohammadi, and S. Das. S-NN: Stacked Neural Networks. Project in Stanford CS231n Winter Quarter, 2015.
  10. P. Hensman, and D. Masko. The Impact of Imbalanced Training Data for Convolutional Neural Networks. Degree Project in Computer Science, DD143X, 2015.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习算法与Python学习

深度学习优化入门:Momentum、RMSProp 和 Adam

虽然局部极小值和鞍点会阻碍我们的训练,但病态曲率会减慢训练的速度,以至于从事机器学习的人可能会认为搜索已经收敛到一个次优的极小值。让我们深入了解什么是病态曲率。...

770
来自专栏SIGAI学习与实践平台

人脸检测算法综述

人脸检测是目前所有目标检测子方向中被研究的最充分的问题之一,它在安防监控,人证比对,人机交互,社交和娱乐等方面有很强的应用价值,也是整个人脸识别算法的第一步。在...

1181
来自专栏数据科学与人工智能

【陆勤阅读】贝叶斯、概率分布与机器学习

一. 简单的说贝叶斯定理: 贝叶斯定理用数学的方法来解释生活中大家都知道的常识 形式最简单的定理往往是最好的定理,比如说中心极限定理,这样的定理往往会成为某一个...

2216
来自专栏PPV课数据科学社区

贝叶斯、概率分布与机器学习

一. 简单的说贝叶斯定理: 贝叶斯定理用数学的方法来解释生活中大家都知道的常识 形式最简单的定理往往是最好的定理,比如说中心极限定理,这样的定理往往会成为某一个...

32010
来自专栏机器之心

学界 | 新型池化层sort_pool2d实现更快更好的收敛:表现优于最大池化层(附代码实现)

选自Hackernoon 作者:Sahil Singla 机器之心编译 参与:黄小天、路雪 近日,Sahil Singla 在 Medium 上发表了一篇题为《...

35712
来自专栏人工智能头条

一文详解计算机视觉的广泛应用:网络压缩、视觉问答、可视化、风格迁移等

1744
来自专栏ATYUN订阅号

【技术】动手实现会写数字的神经网络—半监督学习和生成式对抗网络介绍

在1889年,梵高画了这个美丽的艺术品:星月夜。如今,我的GAN模型只使用20%的标签数据,学会了画MNIST数字!它是怎么实现的?让我们动手做做看。 ? 半监...

47810
来自专栏目标检测和深度学习

计算机视觉必读:目标跟踪、网络压缩、图像分类、人脸识别等

新智元专栏 作者:张皓(南京大学) 【新智元导读】深度学习目前已成为发展最快、最令人兴奋的机器学习领域之一。本文以计算机视觉的重要概念为线索,介绍深度学...

40911
来自专栏机器之心

盘点 | 对比图像分类五大方法:KNN、SVM、BPNN、CNN和迁移学习

选自Medium 机器之心编译 参与:蒋思源、黄小天、吴攀 图像分类是人工智能领域的基本研究主题之一,研究者也已经开发了大量用于图像分类的算法。近日,Shiyu...

5908
来自专栏AI研习社

博客 | 基于深度学习的目标检测算法综述(二)

目标检测(Object Detection)是计算机视觉领域的基本任务之一,学术界已有将近二十年的研究历史。近些年随着深度学习技术的火热发展,目标检测算法也从基...

2304

扫码关注云+社区