第二门课:改善深层神经网络:超参数调试、正则化以及优化(第一周)——深度学习的实用层面

1. 训练,验证,测试集

深度学习是一个典型的迭代过程,迭代的效率很关键,创建高质量的训练数据集,验证集和测试集有助于提高循环效率。

  • 三者区别:
    训练集(train set) —— 用于模型拟合的数据样本
    验证集(development set)—— 是模型训练过程中单独留出的样本集,用于调整模型的超参数以及对模型的能力进行初步评估。通常用来在模型迭代训练时,用以验证当前模型泛化能力(准确率,召回率等),以决定是否停止继续训练。
    测试集(test set) —— 用来评估模最终模型的泛化能力。但不能作为调参、选择特征等算法相关的选择的依据。

  • 切分标准:
    小数据量时代,常见做法是三七分,70%验证集,30%测试集;也可以 60%训练,20%验证和20%测试集来划分。大数据时代,数据量可能是百万级别,验证集和测试集占总量的比例会趋于变得更小。

  • 数据来源:
    最好要确保 验证集测试集 的数据来自同一分布,因为要用验证集来评估不同的模型,如果验证集和测试集来自同一个分布就会表现很好。

2. 偏差,方差

在这里插入图片描述
关键数据:
训练集误差、验证集误差(基于人眼辨别错误率 ≈ 0情况下)

在这里插入图片描述
如果人眼辨别的错误率(贝叶斯误差,最优误差)非常高,比如15%。那么上面第二种分类器(训练误差15%,验证误差16%),15%的错误率对训练集来说也是非常合理的,偏差不高,方差也非常低。

解决方案:(TODO)
解决高方差:获得更多的训练样本;尝试减少特征的数量;尝试增加正则化程度 λ λ λ
解决高偏差:尝试获得更多的特征;尝试增加多项式特征;尝试减少正则化程度 λ λ λ

3. 机器学习基础

在这里插入图片描述

4. 正则化

正则化有助于防止过拟合,降低方差。

范数 (norm) 几种范数的简单介绍对于L1和L2正则化的不同解释

  • L1 范数: ∥ X ∥ 1 = ∑ i = 1 n ∣ x i ∣ \|X\|_{1}=\sum_{i=1}^{n}\left|x_{i}\right| X1=i=1nxi 表示非零元素的绝对值之和;

  • L2 范数: ∥ X ∥ 2 = ∑ i = 1 n x i 2 \|X\|_{2}=\sqrt{\sum_{i=1}^{n} x_{i}^{2}} X2=i=1nxi2 表示元素的平方和再开方。

  • 矩阵的L2范数叫做:弗罗贝尼乌斯范数,所有元素的平方和 ∥ W ∥ F 2 \|W\|_{F}^{2} WF2

加上正则化的损失函数:
L 1 正 则 化 : J ( ω , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∥ ω ∥ 1 L 2 正 则 化 : J ( ω , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∥ ω ∥ 2 2 \begin{aligned} \mathrm{L}1正则化: J(\omega,b)=\frac{1}{m} \sum_{i=1}^{m} \mathcal{L}\left(\hat{y}^{(i)},y^{(i)}\right)+\frac{\lambda}{2 m}\|\omega\|_{1} \\ \mathrm{L}2正则化: J(\omega,b)=\frac{1}{m} \sum_{i=1}^{m} \mathcal{L}\left(\hat{y}^{(i)},y^{(i)}\right)+\frac{\lambda}{2 m}\|\omega\|_{2}^{2} \end{aligned} L1J(ωb)=m1i=1mL(y^(i)y(i))+2mλω1L2J(ωb)=m1i=1mL(y^(i)y(i))+2mλω22

L1正则化 & L2正则化的特征:

  • L1 正则,权重 w \mathrm{w} w 最终变得稀疏,多数变成 0;
  • L2 正则,使得权重衰减。

对于在神经网络W矩阵中进行参数更新操作: W [ l ] : = ( 1 − α λ m ) ∗ W [ l ] − α (  梯度  ) W^{[l]}:=\left(1-\frac{\alpha \lambda}{m}\right) * W^{[l]}-\alpha(\text { 梯度 }) W[l]:=(1mαλ)W[l]α( 梯度 ),权重不但减少了,还乘以了小于1的系数进行衰减。

5. 为什么正则化预防过拟合

J ( ω , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) + λ 2 m ∥ ω ∥ 2 2 J(\omega,b)=\frac{1}{m} \sum_{i=1}^{m} \mathcal{L}\left(\hat{y}^{(i)},y^{(i)}\right)+\frac{\lambda}{2 m}\|\omega\|_{2}^{2} J(ωb)=m1i=1mL(y^(i)y(i))+2mλω22
λ \lambda λ 设置的很大的时候,最终 W W W 会变得很接近于 0,神经网络中的很多单元的作用变得很小,整个网络越来越接近逻辑回归。
在这里插入图片描述
λ 增大时,整个神经网络会计算离线性函数近的值,这个线性函数非常简单,不是复杂的高度非线性函数,不会发生过拟合

L2 正则化是训练深度学习模型时最常用的一种方法。

6. dropout(随机失活)正则化

在这里插入图片描述
以上是一个样本的过程,其他样本也是同样的过程。

实施 dropout 举例: 最常用的方法——inverted dropout (反向随机失活),用一个三层网络举例,注意:下面的a3和d3对应网络中所有的神经单元,实际实现过程中需要一层一层来实现。

  • 定义向量 d , d 3 d,d3 dd3 表示一个三层的 dropout 向量。它是一个概率矩阵,对应每个样本和每个隐藏单元。 d 3 = d3= d3= np. random. rand (a3. shape [ 0 ] [0] [0] , a3. shape [ 1 ] ) [1]) [1])
    定义 keep-prob(表示保留某个隐藏单元的概率) ,概率为 1 - keep_prob 的元素对应为 0 ,概率为 keep_prob 的元素对应为 1 ;
  • 获取激活函数 a 3 a3 a3 a 3 = n p . m u l t i p l y ( a 3 ,   d 3 ) a3=\mathrm{np}. \mathrm{multiply}(\mathrm{a} 3,\mathrm{~d} 3) a3=np.multiply(a3, d3),使得 d 3 d3 d3 中为 0 的元素把 a 3 a3 a3 对应元素归零;
  • 向外扩展 a 3 a3 a3 a 3 a3 a3 /= keep_prob。

反向随机失活 (inverted dropout) 方法通过除以 keep-prob,确保 a [ 3 ] a^{[3]} a[3] 的输出期望值不会被改变。原因如下:虽然dropout忽略了某些隐藏层神经元,例如系数是0.8,则保留80%的神经元,则神经元输出A整体期望也为原来的80%。但是inverted dropout的放缩操作,即对A除以80%。一缩一放过程,相当于输出期望没有改变。

7. 理解 dropout

  • 其功能类似于 L2 正则化;
  • 对于参数集多的层,可以使用较低的 keep-prob 值(不同的层,可以使用不同的值),缺点是:需要交叉验证更多的参数;

注意:

  1. dropout 一大缺点就是:代价函数不再被明确定义,每次迭代,都会随机移除一些节点,想检查梯度下降的性能,实际上是很难进行复查的。

  2. 在实际操作中,可以先关闭dropout,将keep-prob 设置为 1,确保 J 函数单调递减, 然后再尝试使用dropout。

8. 其他正则化

  • 数据扩增,假如是图片数据,扩增数据代价高,我们可以:

水平翻转;随意剪裁旋转放大(这种方式扩增数据,进而正则化数据集,减少过拟合成本很低)
在这里插入图片描述
对于数字识别图片,我们可以进行旋转,扭曲来扩增数据集
在这里插入图片描述

  • early stopping
    在这里插入图片描述
      在验证集误差变坏的时候,提早停止训练

early stopping 缺点:不能同时处理 过拟合代价函数不够小 的问题

  • 提早停止,可能代价函数 J 不够小
  • 不提早结束,可能会过拟合

如果不使用 early stopping ,使用 L2 正则化的话,这样训练时间可能很长,参数搜索空间大,计算代价很高。

early stopping 优点:只运行一次梯度下降,可以找出 w 的较小值,中间值,较大值,无需尝试 L2 正则化超参数 λ \lambda λ的很多值。

9. 归一化输入

归一化输入,可以加速训练。它一般需要两个以下步骤:

  • 零均值化(所有的数据减去均值)
  • 归一化方差 (所有数据除以方差)

注意 μ , σ 2 \mu,\sigma^{2} μσ2 是由训练集得到,然后用于其他所有数据集。
在这里插入图片描述

10. 梯度消失 / 梯度爆炸

在这里插入图片描述
在非常深的神经网络中,权重只要不等于 1,激活函数将会呈指数级递增或者递减,导致训练难度上升,尤其是梯度与 L 相差指数级,梯度下降算法的步长会非常非常小,学习时间很长。

11. 神经网络权重初始化

上面讲到了梯度消失/爆炸,如何缓解这个问题?
在这里插入图片描述
为了预防 z z z 的值 过大或过小, n n n 越大时,你希望 w i w_i wi 越小,因为 z z z w i w_i wi x i x_i xi的和,合理的方法是 w i = 1 / n , n w_{i}=1 / n,\mathrm{n} wi=1/nn 是输入特征数量。 w [ l ] = n p w^{[l]}=n p w[l]=np.random.randn ( ( ( shape ) ∗ n p . sqrt ⁡ ( 1 n [ l − 1 ] ) , n [ l − 1 ] ) * np.\operatorname{sqrt} \left(\frac{1}{n^{[l-1]}}\right),n^{[l-1]} )np.sqrt(n[l1]1)n[l1] 是给第 l l l 层输入的特征数量。

  • 如果使用 ReLu激活函数 (最常用),则 ∗ n p . s q r t ( 2 n [ l − 1 ] ) * np.sqrt\left(\frac{2}{ n^{[l-1]}}\right) np.sqrt(n[l1]2),称为Xavier初始化
  • 如果使用 tanh 激活函数,则 ∗ 1 n [ l − 1 ] * \sqrt{\frac{1}{n^{[l-1]}}} n[l1]1 ,或者 ∗ 2 n [ l − 1 ] + n [ l ] * \sqrt{\frac{2}{n^{[l-1]}+n^{[l]}}} n[l1]+n[l]2

这样设置的权重矩阵既不会增长过快,也不会太快下降到 0,从而训练出一个权重或梯度不会增长或消失过快的深度网络,这也是一个加快训练速度的技巧

12. 梯度的数值逼近

在反向传播时,有个测试叫做梯度检验。即计算误差时,我们需要使用双边误差,不使用单边误差,因为前者更准确。
f ′ ( θ ) = f ( θ + ε ) − f ( θ − ε ) 2 ε \left.f^{\prime}( \theta\right)=\frac{f(\theta+\varepsilon)-f(\theta-\varepsilon)}{2 \varepsilon} f(θ)=2εf(θ+ε)f(θε)

13. 梯度检验

梯度检验帮助我们发现反向传播中的 bug。
在这里插入图片描述

将所有 W W W矩阵转换成向量之后,做连接运算,得到一个巨型向量 θ \theta θ,该向量表示为参数 θ \theta θ,代价函数 J J J是所有 W W W b b b的函数,现在你得到了一个 θ \theta θ的代价函数 J J J(即 J ( θ ) J(\theta) J(θ))。

接着,同样可以把 d W [ 1 ] dW^{[1]} dW[1] d b [ 1 ] db^{[1]} db[1]…… d W [ l ] dW^{[l]} dW[l] d b [ l ] db^{[l]} db[l]转换成一个新的向量,用它们来初始化大向量 d θ d\theta dθ,并且它与 θ \theta θ具有相同维度。
在这里插入图片描述

14. 梯度检验的注意事项

  1. 不要在训练中使用梯度检验,它只用于调试
  2. 如果算法的梯度检验失败,要检查所有项,检查每一项,并试着找出bug;
  3. 如果使用了正则化,计算梯度的时候也要包括正则项;
  4. 梯度检验不能与dropout 同时使用,可以关闭dropout,进行梯度检验,检验正确了,再打开dropout。

猜你喜欢

转载自blog.csdn.net/qq_42859149/article/details/119295859