训练深度神经网络的必知技巧,你知道哪些?互联网+

雷锋网 2017-06-26 17:33
分享到:
导读

数据增广、图像预处理、网络初始化、训练过程中的技巧、激活函数的选择、不同正则化方法、来自于数据的洞察、集成多个深度网络的方法等,零均值化   标准化   2.1.1 为什么要零均值化   数据有过大的均值可能导致参数的梯度过大,  2.1.2 为什么要归一化   归一化是为了让不同维度的数据具有相同的分布。

本文将主要介绍 8 种深度神经网络实现细节的技巧或tricks,包括:数据增广、图像预处理、网络初始化、训练过程中的技巧、激活函数的选择、不同正则化方法、来自于数据的洞察、集成多个深度网络的方法等。 1. 数据增广在不改变图像类别的情况下,增加数据量

  本文将主要介绍 8 种深度神经网络实现细节的技巧或tricks,包括:数据增广、图像预处理、网络初始化、训练过程中的技巧、激活函数的选择、不同正则化方法、来自于数据的洞察、集成多个深度网络的方法等。

  1. 数据增广在不改变图像类别的情况下,增加数据量,能提高模型的泛化能力。

  自然图像的数据增广方式包括很多,如常用的水平翻转(horizontally fliPPing),一定程度的位移或者裁剪和颜色抖动(color jittering)。此外还可以尝试多种操作的组合, 例如同时做旋转和随机尺度变换,此外还可以把每个patch中所有像素在HSV颜色空间中的饱和度和明度提升0.25-4次幂方,乘以0.7-1.4之间的一个因子,再加一个-0.1-0.1之间的值。同样你可以在色调通道(H)对每张图片或patch的所有像素增加一个-0.1~0.1之间的值。

  2. 预处理2.1 最简单的预处理方法:零均值化

  标准化

  2.1.1 为什么要零均值化

  数据有过大的均值可能导致参数的梯度过大,如果有后续的处理,可能要求数据零均值,比如PCA。零均值化并没有消除像素之间的相对差异,人们对图像信息的摄取通常来自于像素之间的相对色差,而不是像素值的高低。

  2.1.2 为什么要归一化

  归一化是为了让不同维度的数据具有相同的分布。假如二维数据(X1,X2)两个维度都服从均值为零的正态分布,但是X1方差为100,X2方差为1。那么对(X1,X2)进行随机采样在二维坐标系中绘制的图像,应该是狭长的椭圆形。

  对这些数据做特征提取会用到以下形式的表达式:

  S = w1*x1 + w2*x2 + b;

  那么参数W1,W2的梯度为:

  dS / dw1 = x1 ; dS / dw2 = x2

  由于x1与x2在分布规模上的巨大差异,w1与w2的导数也会差异巨大。此时绘制目标函数(不是S)的曲面图,就像一个深邃的峡谷,沿着峡谷方向变化的是w2,坡度很小;在峡谷垂直方向变化的是w1,坡度非常陡峭,如图1,而我们期望的目标函数是图2这样的。

  目标函数是非常难以优化的,因为w1和w2的梯度差异太大,所以在两个维度上需要不同的迭代方案。但在实际操作中,为了方便,我们通常为所有维度设置相同的步长,随着迭代的进行,步长的缩减在不同维度也是同步的。这就要求w不同纬度的分布规模大致相同,而这一切都始于数据的归一化。

  2.1.3 实现代码

  X-=numpy.mean(X,axis=0) # 即X的每一列都减去该列的均值

  注:对于灰度图像,零均值化也可以减去整张图片的均值:X-=numpy.mean(X)

  X/=numpy.std(X,axis=0) # 数据归一化。

  X是输入数据,(图片数目X图片维度)。另一种标准化(normalize)方式是标准化每个维度,保证每个维度的最大值和最小值是-1和1。这种预处理的方式只在输入的各个特征的尺度或者单位不同时才有意义。以图片像素作为输入为例子,所有像素值尺度都在0-255这个尺度之间,所以没必要严格的执行这种预处理操作。在自然图像上进行训练时,可以不进行归一化操作,因为理论上图像任一部分的统计性质都应该和其他部分相同,图像的这种特性被称作平稳性(stationarity)

  2.2 白化(Whitening)白化相当于在零均值化和归一化操作之间插入一个旋转操作,将数据投影到主轴上。一张图片经过白化后,可以认为每个像素之间是统计独立的。然而白化很少在卷积神经网络中使用,可能原因是图像信息本来就是依靠像素之间的相对差异来体现的,白化让像素间去相关,让这种差异变得不确定,损失了信息。

  首先将数据零均值化,再计算协方差矩阵(convariance MATrix)来观察数据中的相关结构。

  X-=np.mean(X,axis=0)

  cov=np.dot(X.T,X)/X.shape[0] #计算协方差矩阵

  然后做去相关操作,即通过将原始数据(零均值化后的数据)投影到特征基空间(eiGEnBAsis)。

  U,S,V=np.linalg.svd(cov) #计算数据协方差矩阵的奇异值分解(SVDfactorization)

  Xrot=np.dot(X,U) #对数据去相关

  最后一步变换是白化,即把特征基空间的数据除以每个维度的特征值来标准化尺度。

  Xwhite=Xrot/np.sqrt(S+1e-5) #除以奇异值的平方根,注意到这里加了个1e-5是为了防止分母是0的情况。

  PCA白化的一个缺点是会增加数据中的噪声,因为它把输入数据的所有维度都延伸到相同的大小,这些维度中就包含噪音维度(往往表现为不相关的且方差较小)。这种缺点在实际操作中可以通过把1e-5增大到一个更大的值来引入更强的平滑。

  3. 初始化3.1 不要将参数全部初始化为零几乎所有的CNN网络都是堆成结构,将参数零初始化会导致流过网络的数据也是对称的(都是零),并且没有办法在不受扰动的情况下打破这种数据对称,从而导致网络无法学习。

  参数零初始化时,无论输入是什么,中间神经元的激活值都是相同的(任意一个神经元的激活值a=f(WTX),当权重W是零向量时,WTX也是零向量,因此经过激活函数后激活值都相同),反向传播过程中计算的梯度也是相同,每个权重参数的更新因此也是相同的,网络因此失去了不对称性。

  3.2 用小的随机数初始化初始化参数应该非常接近于零(但不全等于零),来打破网络的对称性。初始参数应该是随机且独立的来保证每个参数更新过程是不同的。给每个参数随机赋予一个接近零的值:

  W=0.01*numpy.Random.randn(D,H)

  randn方法生成一个零均值,方差为1的正态分布的随机数,同样也可以换用数值较小的均匀分布来产生初始化参数,但在实践中两种方法最终结果差别不大

  3.3 方差归一化用随机初始化方法来初始化参数会导致输出S的方差随输入数量(X或W向量的维度)增加而变大。

  独立随机变量和的方差具有以下性质:

  Var(A+B+C)=Var(A)+ Var(B)+ Var(C)

  S = w1*x1 + w2*x2 +…+wi*xi+ b

  S是多个随机变量的加权和,假设W各维度之间相互独立,随着数据维度增长,S的方差将会线性积累,由于数据的维度随任务的不同,是不可控的,所以我们希望将S的方差做归一化,这只需要对W做处理就可以了:

  W=numpy.random.randn(n)/sqrt(n) #n是数据维度

  上面操作是正确的推导过程:

  令 n*Var(W) = 1,就得到std(W) = 1 / sqrt(n)。

  注意:现在更多的论文中在实际中都在用ReLUs函数,针对ReLUs推荐:

  w=numpy.random.randn(n)*sqrt(2.0/n)

数据 维度 参数 操作 图像
分享到:

1.TMT观察网遵循行业规范,任何转载的稿件都会明确标注作者和来源;
2.TMT观察网的原创文章,请转载时务必注明文章作者和"来源:TMT观察网",不尊重原创的行为TMT观察网或将追究责任;
3.作者投稿可能会经TMT观察网编辑修改或补充。


观点约架