数据集很小时,比如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,会使训练迭代得更快,而且还能更高效地测量算法存在的偏差和方差,然后就能更高效的选用适当的方法来改进算法。
造成High Bias的原因可能是feature简单,数量少,阶次低等
造成Hight Variance的原因则可能是feature过于复杂,阶次高。
这两种情况下,模型的泛化能力都比较差。一个好的模型应该达到下面这种‘刚刚好’的状态
对于下面表格里面的数据,我们分析一下其原因:
Case 1 | Case 2 | Case 3 | Case 4 | |
Train Error | 1% | 15% | 15% | 0.5% |
Dev Error | 10% | 16% | 30% | 1% |
Bayes Error(贝叶斯误差)
简单来说,在理想情况下的误差也被称为贝叶斯误差。比如人工分类图片的误差为0%,那么贝叶斯误差也接近于0%。比如Case 2中,Bayes error为15%,那么它就不再是一个High Bias的问题了,它应该说是一个非常好的模型。
总结
另外,通过学习曲线,也能够很好的分析High Bias和High Variance的问题
High Bias的学习曲线的特点是,Train Set和Dev Set的错误率都很高,而且两者的错误率比较接近
High Variance的学习曲线的特点是,Train Set的错误率比较低,而Dev Set的比较高,而且两者的gap比较大
在深度学习中对于High Bias和High Variance的处理原则如下:
在传统的机器学习中,减少Bias可能引起增加variance,但是这个问题在DNN中可以避免,通过更多的训练数据或者更复杂的神经网络,并辅以正规化,完全可单方消减bias或者variance
对于High Bias问题的解决,主要是通过调整网络结构或者训练时间。
对于High Variance的问题,如果获取更多数据的代价太大,我们应该采用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)=m1∑i=1mL(y^(i),y(i))+2mλ∣∣w∣∣2,其中
∣ ∣ w ∣ ∣ 2 = ∑ j = 1 n x w j 2 = w T w ||w||^2 = \sum_{j=1}^{n_x}w_j^2 = w^Tw ∣∣w∣∣2=∑j=1nxwj2=wTw,即向量w的欧几里得范数的平方,也称为L2正则化。
∣ ∣ w ∣ ∣ = ∑ j = 1 n x ∣ w j ∣ ||w|| = \sum_{j=1}^{n_x}|w_j| ∣∣w∣∣=∑j=1nx∣wj∣,即向量w的欧几里得范数,也称为L1正则化。
L1和L2正则化的差别在于:L1正则化会使得w变得稀疏,即w中有很多的0,因为有一部分0,会占用较少的内存,有些人认为它有助于压缩模型(但效果并不好)。但是在实际应用中,L2使用的更频繁。
注意:在Regularization过程中,并没有对参数b正则化,主要因为b只是单个数字,几乎所有的参数都集中在w中,它实际上起不到太大的作用,所以可以忽略。
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])=m1∑i=1mL(y^(i),y(i))+2mλ∑l=1L∣∣W[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=1l∑j=1l−1(Wij[l])2,因为在神经网络中W为一个 n [ l ] n^{[l]} n[l] x n [ l − 1 ] n^{[l-1]} n[l−1]的矩阵,所以这里的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(权重衰减)
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])=m1∑i=1mL(y^(i),y(i))+2mλ∑l=1L∣∣W[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[l−1]+b[l]也会变小趋于0,那么 a [ l ] a^{[l]} a[l]也将趋于线性。这就意味着整个神经网络都是趋于线性的,由此很好的避免了过拟合问题
除了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,如下图所示:
由此可以简化神经网络结构,达到防止过拟合的目的。
以下为Inverted Dropout的实现原理:
以上图第3层为例,设置保留率keep.prop = 0.8,即删除率为0.2
按照保留率生成矩阵d3,通过下面的方法可以使得d3 80%的元素为1或者True,20%的元素为0或者False
d3 = np.random.rand(a3.shape[0], a3.shape[1]) < keep.prop
执行Dropout
a3 = np.multiply(a3, d3) # a3 = a3 * d3
矩阵相乘后,a3中20%的单元被赋值为0,达到了删除的目的
补偿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)
注意:
上面已经讲过,对于过拟合问题,是可以通过增大样本数量解决的,但是如果收集新样本代价比较大时,Data augmentation的方法同样可以达到增大样本数量的目的。它是基于现有的样本,产生新的样本。该方法常见于计算机视觉领域,比如图片分类,可以基于原样本图片进行旋转,裁剪,扭曲,色变等方式增加样本量。
另外一种防止过拟合的方法:Early Stopping,它是通过绘制Train Set和Dev Set的 J J J和迭代次数的曲线图,然后在Dev Error升高前停止训练,从而避免过拟合。但这种方法的缺点就是把最小化 J J J和防止过拟合并在一起解决,可能导致2个方面都不能达到最有的状态。本着同一时刻只解决一件事情的原则,更好的正则化方法还是L2。
归一化分为两个步骤:
计算步骤如下:
σ 2 = 1 m ∑ i = 1 m ( x ( i ) ) 2 \sigma ^2 = \frac{1}{m}\sum_{i=1}^{m}(x^{(i)})^2 σ2=m1∑i=1m(x(i))2
x ( i ) = x ( i ) σ 2 x^{(i)} = \frac{x^{(i)}}{\sigma ^ 2} x(i)=σ2x(i)
如果未进行归一化,那么就需要更小的 a l p h a alpha alpha,然后经过很多次迭代和振荡才能到达 J J J的最小值。
如果进行了归一化,那么就可以使用较大的 α \alpha α,梯度下降快,经过很少次的迭代和较少的振荡便可以找到最小值。
上图是2D的示意图,对于多维也是一样的,只不过无法用图来表示。
总之,建议对于输入的训练集数据都要经过归一化处理,同时归一化也要应用在开发集和测试集上面。
当训练层数非常多的神经网络时经常会遇到的问题就是梯度的爆炸和消失。它的意思是当你在训练一个深度神经网络的时候损失函数的导数或者说斜率有时会变得非常大或者非常小甚至是呈指数级减小,这使训练变得很困难。所以,另外一个加快训练速度的方法就是避免梯度爆炸或者梯度下降。
为什么会发生梯度爆炸或者梯度消失,可以参考梯度爆炸和梯度消失
一种解决梯度爆炸的方法是梯度裁剪(Gradient Clipping):
首先假设某层的梯度组成的向量g,然后计算出g的范数 ∣ ∣ g ∣ ∣ 2 = ∑ i = 1 n g i 2 ||g||_2 = \sqrt{\sum_{i=1}^{n}g_i^2} ∣∣g∣∣2=∑i=1ngi2
然后设定一个阈值C,如果 ∣ ∣ g ∣ ∣ 2 > c ||g||_2 > c ∣∣g∣∣2>c时, g = c ∣ ∣ g ∣ ∣ 2 g g = \frac{c}{||g||_2}g g=∣∣g∣∣2cg,否则不裁剪。
即 g = m i n ( c ∣ ∣ g ∣ ∣ 2 , 1 ) g g = min(\frac{c}{||g||_2}, 1)g g=min(∣∣g∣∣2c,1)g
梯度消失的问题在深度学习中更加常见,比如如果激活函数是sigmoid或者tanh,那么当z越大或者越小时,a的变化越小导致梯度变化非常小,进而学习数量严重变慢。解决该问题的方法是选择ReLU激活函数。
对于缓解梯度爆炸和梯度消失,还有其他改进方法,比如选择合适的初始化参数的方法,batch normalization等,将在下一讲介绍,谢谢!