深度学习 --- 改善深度神经网络 1

文章目录

    • 1. 如何划分Train/Dev/Test Sets(训练集,开发集,测试集)
    • 2. 如何分析High Bias/High Variance(高偏差,高方差)
      • 2.1 High Bias和High Variance图示
      • 2.2 High Bias和High Variance分析
      • 2.3 High Bias和High Variance处理原则
    • 3.如何解决High Bias和High Variance---Regularization(正则化)
      • 3.1 逻辑回归中的Regularization
      • 3.2 神经网络中的Regularization
      • 3.3 为什么Regularization能够防止overfitting
      • 3.4 Dropout Regularization
      • 3.5 Other Regularization Methods
    • 4. 如何加快训练速度
      • 4.1 训练数据归一化
      • 4.2 避免梯度爆炸和梯度消失(Vanishing/Exploding gradients)


1. 如何划分Train/Dev/Test Sets(训练集,开发集,测试集)

  • 数据集很小时,比如1万或者10万个样本
    机器学习中有很多种划分Train,Dev,Test Sets的方法,在数据集比较小的时候,这些传统的方法同样适用于深度学习。最为常见的分配比例为7:3(Train vs Test)和6:2:2(Train vs Dev vs Test),这在机器学习中被认为是最佳的分配的比例。

  • 数据集很大时,比如100万
    那么此时的Dev和Test完全不需要20%,1%也许就可以了,因为1万个数据也足以评估处模型的性能了。所以在大数据时代,这些比例的分配需要按照实际情况而定。

在大数据时代,还存在的以为问题就是数据分配的不匹配。比如,一个图片分类的模型,训练集可能采用的都是web上面下载的高清的图片,而模型应用的场景可能各式各样,比如很多用户提供的可能是使用手机拍摄的分辨率很低的图片。为此,一条有效的经验法则:是在选取Dev和Test sets时,一定要确保这两个sets里面的样本分配是匹配的。

总之,合理地分配好Train,Dev,Test Set,会使训练迭代得更快,而且还能更高效地测量算法存在的偏差和方差,然后就能更高效的选用适当的方法来改进算法。

2. 如何分析High Bias/High Variance(高偏差,高方差)

2.1 High Bias和High Variance图示

深度学习 --- 改善深度神经网络 1_第1张图片
造成High Bias的原因可能是feature简单,数量少,阶次低等
深度学习 --- 改善深度神经网络 1_第2张图片
造成Hight Variance的原因则可能是feature过于复杂,阶次高。

这两种情况下,模型的泛化能力都比较差。一个好的模型应该达到下面这种‘刚刚好’的状态
深度学习 --- 改善深度神经网络 1_第3张图片

2.2 High Bias和High Variance分析

对于下面表格里面的数据,我们分析一下其原因:

Case 1 Case 2 Case 3 Case 4
Train Error 1% 15% 15% 0.5%
Dev Error 10% 16% 30% 1%
  • Case 1
    模型在Train Set上的拟合非常好,但是在Dev Set上面错误率却比较大,泛化能力差。此为High Variance。
  • Case 2
    模型在Train Set上错误率较高,如果此时人工的错误率为0%,那么说明模型并未把Train Set数据处理的比较好,但是它在Dev Set上的表现和Train Set差不多,处于可以接受的范围。属于High Bias。
  • Case 3
    模型在Train Set上面的错误率高,在Dev Set上更高,说明这是一个非常糟糕的模型。既有Hight Variance,也有High Bias。
    这个比较难理解,举一个图例:
    深度学习 --- 改善深度神经网络 1_第4张图片
  • Case 4
    模型在Train上错误率很低,说明拟合地很好,在Dev Set上的错误率也才1%,说明泛化能力也很好。这是一个好的模型,属于Low Variance,Low Bias。

Bayes Error(贝叶斯误差)
简单来说,在理想情况下的误差也被称为贝叶斯误差。比如人工分类图片的误差为0%,那么贝叶斯误差也接近于0%。比如Case 2中,Bayes error为15%,那么它就不再是一个High Bias的问题了,它应该说是一个非常好的模型。

总结

  • 通过观察训练集的误差,至少可以知道你的算法是否可以很好的拟合训练集数据,然后总结出是否属于高偏差问题。
  • 然后通过观察同一个算法在开发集上的误差为多少,可以知道这个算法是否有高方差问题。这样你就能判断训练集上的算法是否在开发集上同样适用。这会让你意识到方差问题,上述结果都基于贝叶斯误差非常低并且你的训练集和开发集都来自与同一个分布,如果不满足这些假设那么你需要做一个更复杂的分析。

深度学习 --- 改善深度神经网络 1_第5张图片

另外,通过学习曲线,也能够很好的分析High Bias和High Variance的问题
深度学习 --- 改善深度神经网络 1_第6张图片
High Bias的学习曲线的特点是,Train Set和Dev Set的错误率都很高,而且两者的错误率比较接近
深度学习 --- 改善深度神经网络 1_第7张图片
High Variance的学习曲线的特点是,Train Set的错误率比较低,而Dev Set的比较高,而且两者的gap比较大

2.3 High Bias和High Variance处理原则

在深度学习中对于High Bias和High Variance的处理原则如下:

  • 首先判断是否为High Bias,如果是,那么可以采用更大的深度神经网络,比如更多的层数,更多的单元数,或者更长的训练时间
  • 然后判断是否为High Variance,如果是,则可以增大训练数据或者采用正规化,比如Dropout,L1/L2正规化

在传统的机器学习中,减少Bias可能引起增加variance,但是这个问题在DNN中可以避免,通过更多的训练数据或者更复杂的神经网络,并辅以正规化,完全可单方消减bias或者variance

3.如何解决High Bias和High Variance—Regularization(正则化)

对于High Bias问题的解决,主要是通过调整网络结构或者训练时间。
对于High Variance的问题,如果获取更多数据的代价太大,我们应该采用Regularization,它能有效地防止过拟合。

3.1 逻辑回归中的Regularization

为什么Regularization能够防止过拟合,请参考机器学习之Regularization
逻辑回归中添加了Regularization的Cost函数为:
J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∣ ∣ w ∣ ∣ 2 J(w,b) = \frac{1}{m}\sum_{i=1}^{m}L(\hat y^(i), y^{(i)}) + \frac{\lambda}{2m}||w||^2 J(w,b)=m1i=1mL(y^(i),y(i))+2mλw2,其中
∣ ∣ w ∣ ∣ 2 = ∑ j = 1 n x w j 2 = w T w ||w||^2 = \sum_{j=1}^{n_x}w_j^2 = w^Tw w2=j=1nxwj2=wTw,即向量w的欧几里得范数的平方,也称为L2正则化。
∣ ∣ w ∣ ∣ = ∑ j = 1 n x ∣ w j ∣ ||w|| = \sum_{j=1}^{n_x}|w_j| w=j=1nxwj,即向量w的欧几里得范数,也称为L1正则化。

L1和L2正则化的差别在于:L1正则化会使得w变得稀疏,即w中有很多的0,因为有一部分0,会占用较少的内存,有些人认为它有助于压缩模型(但效果并不好)。但是在实际应用中,L2使用的更频繁。

注意:在Regularization过程中,并没有对参数b正则化,主要因为b只是单个数字,几乎所有的参数都集中在w中,它实际上起不到太大的作用,所以可以忽略。

3.2 神经网络中的Regularization

J ( w [ l ] , b [ l ] ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∑ l = 1 L ∣ ∣ W [ l ] ∣ ∣ F 2 J(w^{[l]},b^{[l]}) = \frac{1}{m}\sum_{i=1}^{m}L(\hat y^(i), y^{(i)}) + \frac{\lambda}{2m}\sum_{l=1}^{L}||W^{[l]}||_F^2 J(w[l],b[l])=m1i=1mL(y^(i),y(i))+2mλl=1LW[l]F2,其中
∣ ∣ W [ l ] ∣ ∣ F 2 = ∑ i = 1 l ∑ j = 1 l − 1 ( W i j [ l ] ) 2 ||W^{[l]}||_F^2 = \sum_{i=1}^{l}\sum_{j=1}^{l-1}(W_{ij}^{[l]})^2 W[l]F2=i=1lj=1l1(Wij[l])2,因为在神经网络中W为一个 n [ l ] n^{[l]} n[l] x n [ l − 1 ] n^{[l-1]} n[l1]的矩阵,所以这里的Regularization需要计算每一层W矩阵的元素平方和。

注意:在这里 ∣ ∣ W [ l ] ∣ ∣ F 2 ∣ ∣ ||W^{[l]}||_F^2|| W[l]F2被称为Frobenius norm而不是L2 norm。

由于 J J J多添加了一项Regularization,那么它对于反向传播会有什么影响呢?如下:
d W [ l ] = [ f r o m b a c k p r o p ] + λ m W [ l ] dW^{[l]} = [from backprop] + \frac{\lambda}{m}W^{[l]} dW[l]=[frombackprop]+mλW[l]
W [ l ] : = W [ l ] − α d W [ l ] = ( 1 − α λ m ) W [ l ] − α [ f r o m b a c k p r o p ] W^{[l]} := W^{[l]} - \alpha dW^{[l]} = (1 - \alpha\frac{\lambda}{m})W^{[l]} - \alpha [from backprop] W[l]:=W[l]αdW[l]=(1αmλ)W[l]α[frombackprop]

和没有Regularization时相比, W [ l ] W^{[l]} W[l]比之前更小了,因此该L2正则化也被称为weight decay(权重衰减)

3.3 为什么Regularization能够防止overfitting

深度学习 --- 改善深度神经网络 1_第8张图片

J ( w [ l ] , b [ l ] ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∑ l = 1 L ∣ ∣ W [ l ] ∣ ∣ F 2 J(w^{[l]},b^{[l]}) = \frac{1}{m}\sum_{i=1}^{m}L(\hat y^(i), y^{(i)}) + \frac{\lambda}{2m}\sum_{l=1}^{L}||W^{[l]}||_F^2 J(w[l],b[l])=m1i=1mL(y^(i),y(i))+2mλl=1LW[l]F2

以上述的神经网络为例,当 λ → ∞ ⇒ W [ l ] → 0 \lambda \to \infty \Rightarrow W^{[l]}\to 0 λW[l]0,那么这就意味着神经网络中很多的隐藏单元都将处于disabled状态,那么这将使得神经网络变得非常非常简单,趋于一个简单的线性逻辑回归模型,避免了过拟合的问题。

还可以从另一个方面来解释,如下图的激活函数 a = t a n h ( z ) a = tanh(z) a=tanh(z)所示:当z趋于0时,a是趋于线性的,当z趋于正负无穷大时,a是非线性的。

λ ↑ \lambda \uparrow λ时, W [ l ] ↓ W^{[l]} \downarrow W[l] z = W [ l ] a [ l − 1 ] + b [ l ] z = W^{[l]}a^{[l-1]} + b^{[l]} z=W[l]a[l1]+b[l]也会变小趋于0,那么 a [ l ] a^{[l]} a[l]也将趋于线性。这就意味着整个神经网络都是趋于线性的,由此很好的避免了过拟合问题
深度学习 --- 改善深度神经网络 1_第9张图片

3.4 Dropout Regularization

除了L2正则化,Dropout是在神经网络中另一个非常强大的正则化方法。
该方法即在每一层以一定的概率随机删除掉神经元,所谓的删除实际上是将 a [ l ] a^{[l]} a[l]层中被删除的神经元位置的 a i [ l ] a_{i}^{[l]} ai[l]赋值为0, a i [ l ] = 0 a_{i}^{[l]} = 0 ai[l]=0,如下图所示:

深度学习 --- 改善深度神经网络 1_第10张图片

由此可以简化神经网络结构,达到防止过拟合的目的。

以下为Inverted Dropout的实现原理:

  1. 以上图第3层为例,设置保留率keep.prop = 0.8,即删除率为0.2

  2. 按照保留率生成矩阵d3,通过下面的方法可以使得d3 80%的元素为1或者True,20%的元素为0或者False

     d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep.prop
    
  3. 执行Dropout

     a3 = np.multiply(a3, d3)    # a3 = a3 * d3
    

    矩阵相乘后,a3中20%的单元被赋值为0,达到了删除的目的

  4. 补偿a3的值

     a3 /= keep.prop
    

    Z [ 4 ] = W [ 4 ] a [ 3 ] + b [ 4 ] Z^{[4]} = W^{[4]}a^{[3]} + b^{[4]} Z[4]=W[4]a[3]+b[4]中,由于 a [ 3 ] a^{[3]} a[3]有20%的元素被置为0,为了不改变 a [ 3 ] a^{[3]} a[3]的整体输出期望值,所以要采用上述的方式提供大约20%的校正值

Inverted Dropout是最常用的dropout方法,由于是随机的删除,所以每一轮的训练中,丢弃的单元是不同的。

上面只描述了前向传播过程中的Dropout,其实在反向传播过程中也需要同样的操作,将a3换成da3即可

    da3 = np.multiply(da3, d3)

注意:

  • Dropout只应用在训练过程中,在测试时不会使用
  • 不同的层可以配置不同的保留率。如果某一层的参数很多,可以通过设置较小的保留率防止过拟合。Dropout也可以用于输入层,但很少使用,一般保存率为1或者0.9
  • Dropout多用于计算机视觉领域,其他领域用的比较少,除非确定发生了过拟合时
  • Dropout的一个缺点就是很难确定Cost function是否定义好,因为 J J J曲线会随机振动。因此,在这个时候通常先关闭Dropout,确保 J J J单调递减后再打开

3.5 Other Regularization Methods

上面已经讲过,对于过拟合问题,是可以通过增大样本数量解决的,但是如果收集新样本代价比较大时,Data augmentation的方法同样可以达到增大样本数量的目的。它是基于现有的样本,产生新的样本。该方法常见于计算机视觉领域,比如图片分类,可以基于原样本图片进行旋转,裁剪,扭曲,色变等方式增加样本量。

另外一种防止过拟合的方法:Early Stopping,它是通过绘制Train Set和Dev Set的 J J J和迭代次数的曲线图,然后在Dev Error升高前停止训练,从而避免过拟合。但这种方法的缺点就是把最小化 J J J和防止过拟合并在一起解决,可能导致2个方面都不能达到最有的状态。本着同一时刻只解决一件事情的原则,更好的正则化方法还是L2。

4. 如何加快训练速度

4.1 训练数据归一化

归一化分为两个步骤:

  • 均值归零(zero mean),目的是使各个样本的平均值为零。操作步骤如下:
    μ = 1 m ∑ i = 1 m x ( i ) \mu = \frac{1}{m}\sum_{i=1}^{m}x^{(i)} μ=m1i=1mx(i)
    x ( i ) = x ( i ) − μ x^{(i)} = x^{(i)} - \mu x(i)=x(i)μ

意思就是将训练集进行平移 直到它的均值变为零,如下图所示:
深度学习 --- 改善深度神经网络 1_第11张图片

深度学习 --- 改善深度神经网络 1_第12张图片

  • 方差归一化(feature scaling),目的是使各个feature的值能够落在[0,1]或者[-1,1]之间,这样可以加快梯度下降的速度,快速最小化 J J J。如上图所示,横轴方向的feature比例大于纵轴方向,那么feature scaling的目的就是要让他们的比例在同样的范围内,达到下图的要求:

深度学习 --- 改善深度神经网络 1_第13张图片

计算步骤如下:
σ 2 = 1 m ∑ i = 1 m ( x ( i ) ) 2 \sigma ^2 = \frac{1}{m}\sum_{i=1}^{m}(x^{(i)})^2 σ2=m1i=1m(x(i))2
x ( i ) = x ( i ) σ 2 x^{(i)} = \frac{x^{(i)}}{\sigma ^ 2} x(i)=σ2x(i)

未归一化:
深度学习 --- 改善深度神经网络 1_第14张图片

深度学习 --- 改善深度神经网络 1_第15张图片

归一化:
深度学习 --- 改善深度神经网络 1_第16张图片

深度学习 --- 改善深度神经网络 1_第17张图片

如果未进行归一化,那么就需要更小的 a l p h a alpha alpha,然后经过很多次迭代和振荡才能到达 J J J的最小值。
如果进行了归一化,那么就可以使用较大的 α \alpha α,梯度下降快,经过很少次的迭代和较少的振荡便可以找到最小值。
上图是2D的示意图,对于多维也是一样的,只不过无法用图来表示。
总之,建议对于输入的训练集数据都要经过归一化处理,同时归一化也要应用在开发集和测试集上面。

4.2 避免梯度爆炸和梯度消失(Vanishing/Exploding gradients)

当训练层数非常多的神经网络时经常会遇到的问题就是梯度的爆炸和消失。它的意思是当你在训练一个深度神经网络的时候损失函数的导数或者说斜率有时会变得非常大或者非常小甚至是呈指数级减小,这使训练变得很困难。所以,另外一个加快训练速度的方法就是避免梯度爆炸或者梯度下降。

为什么会发生梯度爆炸或者梯度消失,可以参考梯度爆炸和梯度消失

一种解决梯度爆炸的方法是梯度裁剪(Gradient Clipping):

  • 首先假设某层的梯度组成的向量g,然后计算出g的范数 ∣ ∣ g ∣ ∣ 2 = ∑ i = 1 n g i 2 ||g||_2 = \sqrt{\sum_{i=1}^{n}g_i^2} g2=i=1ngi2

  • 然后设定一个阈值C,如果 ∣ ∣ g ∣ ∣ 2 > c ||g||_2 > c g2>c时, g = c ∣ ∣ g ∣ ∣ 2 g g = \frac{c}{||g||_2}g g=g2cg,否则不裁剪。
    g = m i n ( c ∣ ∣ g ∣ ∣ 2 , 1 ) g g = min(\frac{c}{||g||_2}, 1)g g=min(g2c,1)g

梯度消失的问题在深度学习中更加常见,比如如果激活函数是sigmoid或者tanh,那么当z越大或者越小时,a的变化越小导致梯度变化非常小,进而学习数量严重变慢。解决该问题的方法是选择ReLU激活函数。

对于缓解梯度爆炸和梯度消失,还有其他改进方法,比如选择合适的初始化参数的方法,batch normalization等,将在下一讲介绍,谢谢!

你可能感兴趣的:(深度学习)