神经网络优化算法:Dropout、梯度消失/爆炸、Adam优化算法,一篇就够了!

本文深入探讨了神经网络训练中的优化问题,包括 Dropout 作为正则化手段防止过拟合,梯度消失/梯度爆炸现象及其解决方案,以及详细的优化算法介绍,如 SGD、动量法、AdaGrad、RMSProp、AdaDelta 和 Adam 算法。此外,还讨论了训练样本少时的处理方法和提升模型稳定性的策略。
摘要由CSDN通过智能技术生成

1. 训练误差和泛化误差

机器学习模型在训练数据集和测试数据集上的表现。如果你改变过实验中的模型结构或者超参数,你也许发现了:当模型在训练数据集上更准确时,它在测试数据集上却不⼀定更准确。这是为什么呢?

因为存在着训练误差和泛化误差:

  • **训练误差:**模型在训练数据集上表现出的误差。
  • **泛化误差:**模型在任意⼀个测试数据样本上表现出的误差的期望,并常常通过测试数据集上的误差来近似。

训练误差的期望小于或等于泛化误差。也就是说,⼀般情况下,由训练数据集学到的模型参数会使模型在训练数据集上的表现优于或等于在测试数据集上的表现。由于⽆法从训练误差估计泛化误差,⼀味地降低训练误差并不意味着泛化误差⼀定会降低。

机器学习模型应关注降低泛化误差。

2. 该如何选择模型

在机器学习中,通常需要评估若⼲候选模型的表现并从中选择模型。这⼀过程称为模型选择(model selection)。可供选择的候选模型可以是有着不同超参数的同类模型。以多层感知机为例,我们可以选择隐藏层的个数,以及每个隐藏层中隐藏单元个数和激活函数。为了得到有效的模型,我们通常要在模型选择上下⼀番功夫。

2.1 验证数据集

从严格意义上讲,测试集只能在所有超参数和模型参数选定后使⽤⼀次。不可以使⽤测试数据选择模型,如调参。由于⽆法从训练误差估计泛化误差,因此也不应只依赖训练数据选择模型。鉴于此,我们可以预留⼀部分在训练数据集和测试数据集以外的数据来进⾏模型选择。这部分数据被称为验证数据集,简称验证集(validation set)。例如,我们可以从给定的训练集中随机选取⼀小部分作为验证集,而将剩余部分作为真正的训练集。

可以通过预留这样的验证集来进行模型选择,判断验证集在模型中的表现能力。

2.2 K 折交叉验证

由于验证数据集不参与模型训练,当训练数据不够⽤时,预留⼤量的验证数据显得太奢侈。⼀种改善的⽅法是K折交叉验证(K-fold cross-validation)。在K折交叉验证中,我们把原始训练数据集分割成K个不重合的⼦数据集,然后我们做K次模型训练和验证。每⼀次,我们使⽤⼀个⼦数据集验证模型,并使⽤其他K − 1个⼦数据集来训练模型。在这K次训练和验证中,每次⽤来验证模型的⼦数据集都不同。最后,我们对这K次训练误差和验证误差分别求平均。

3. ⽋拟合和过拟合

  • **欠拟合:**模型⽆法得到较低的训练误差。
  • **过拟合:**是模型的训练误差远小于它在测试数据集上的误差。

给定训练数据集,

  • 如果模型的复杂度过低,很容易出现⽋拟合;
  • 如果模型复杂度过⾼,很容易出现过拟合。

应对⽋拟合和过拟合的⼀个办法是针对数据集选择合适复杂度的模型。

训练数据集⼤⼩

影响⽋拟合和过拟合的另⼀个重要因素是训练数据集的⼤小。⼀般来说,如果训练数据集中样本数过少,特别是⽐模型参数数量(按元素计)更少时,过拟合更容易发⽣。此外,泛化误差不会随训练数据集⾥样本数量增加而增⼤。因此,在计算资源允许的范围之内,我们通常希望训练数据集⼤⼀些,特别是在模型复杂度较⾼时,例如层数较多的深度学习模型。

正则化

应对过拟合问题的常⽤⽅法:权重衰减(weight decay),权重衰减等价于L2范数正则化(regularization)。正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常⽤⼿段。

4. 丢弃法(Dropout)

除了上面提到的权重衰减以外,深度学习模型常常使⽤丢弃法(dropout)来应对过拟合问题。丢弃法有⼀些不同的变体。本节中提到的丢弃法特指倒置丢弃法(inverted dropout)。

回忆⼀下,“多层感知机”描述了⼀个单隐藏层的多层感知机。其中输⼊个数为4,隐藏单元个数为5,且隐藏单元hi(i = 1, . . . , 5)的计算表达式为:

h i = ϕ ( x 1 w 1 i + x 2 w 2 i + x 3 w 3 i + x 4 w 4 i + b i ) h_i=\phi(x_1w_{1i}+x_2w_{2i}+x_3w_{3i}+x_4w_{4i}+b_i) hi=ϕ(x1w1i+x2w2i+x3w3i+x4w4i+bi)

这⾥ϕ是激活函数,x1, . . . , x4是输⼊,隐藏单元i的权重参数为w1i, . . . , w4i,偏差参数为bi。当对该隐藏层使⽤丢弃法时,该层的隐藏单元将有⼀定概率被丢弃掉。设丢弃概率为p,那么有p的概率hi会被清零,有1 − p的概率hi会除以1 − p做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量ξi为0和1的概率分别为p和1 − p。使⽤丢弃法时我们计算新的隐藏单元 h i ′ h_i^{′} hi

h i ′ = ξ i 1 − p h_i^{′}=\frac{\xi_i}{1-p} hi=1pξi

由于E(ξi) = 1 − p,因此:

E ( h i ′ ) = E ( ξ i ) 1 − p h i = h i E(h_i^{′})=\frac{E(\xi_i)}{1-p}h_i=h_i E(hi)=1pE(ξi)hi=hi

**即丢弃法不改变其输⼊的期望值。**让我们对隐藏层使⽤丢弃法,⼀种可能的结果如下图所⽰,其中h2和h5被清零。这时输出值的计算不再依赖h2和h5,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即h1, . . . , h5都有可能被清零,输出层的计算⽆法过度依赖h1, . . . , h5中的任⼀个,从而在训练模型时起到正则化的作⽤,并可以⽤来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,⼀般不使⽤丢弃法。

5. 梯度消失/梯度爆炸(Vanishing / Exploding gradients)

训练神经网络,尤其是深度神经所面临的一个问题就是梯度消失或梯度爆炸,也就是你训练神经网络的时候,导数或坡度有时会变得非常大,或者非常小,甚至于以指数方式变小,这加大了训练的难度。

本质上,梯度消失和爆炸是一种情况。在深层网络中,由于网络过深,如果初始得到的梯度过小,或者传播途中在某一层上过小,则在之后的层上得到的梯度会越来越小,即产生了梯度消失。梯度爆炸也是同样的。一般地,不合理的初始化以及激活函数,如sigmoid等,都会导致梯度过大或者过小,从而引起消失/爆炸。

解决方案

  1. 预训练加微调

    其基本思想是每次训练一层隐节点,训练时将上一层隐节点的输出作为输入,而本层隐节点的输出作为下一层隐节点的输入,此过程就是逐层“预训练”(pre-training);在预训练完成后,再对整个网络进行“微调”(fine-tunning)。

    此方法有一定的好处,但是目前应用的不是很多了。

  2. 梯度剪切、正则

    梯度剪切这个方案主要是针对梯度爆炸提出的,其思想是设置一个梯度剪切阈值,然后更新梯度的时候,如果梯度超过这个阈值,那么就将其强制限制在这个范围之内。这可以防止梯度爆炸。

    另外一种解决梯度爆炸的手段是采用权重正则化(weithts regularization)比较常见的是L1和L2正则。

  3. ReLu、leakReLu等激活函数

    ReLu:其函数的导数在正数部分是恒等于1,这样在深层网络中,在激活函数部分就不存在导致梯度过大或者过小的问题,缓解了梯度消失或者爆炸。同时也方便计算。当然,其也存在存在一些缺点,例如过滤到了负数部分,导致部分信息的丢失,输出的数据分布不在以0为中心,改变了数据分布。

    leakrelu:就是为了解决relu的0区间带来的影响,其数学表达为:leakrelu=max(k*x,0)其中k是leak系数,一般选择0.01或者0.02,或者通过学习而来。

  4. Batch Normalization

    Batch Normalization是深度学习发展以来提出的最重要的成果之一了,目前已经被广泛的应用到了各大网络中,具有加速网络收敛速度,提升训练稳定性的效果,Batch Normalization本质上是解决反向传播过程中的梯度问题。Batch Normalization,简称BN,即批规范化,通过规范化操作将输出信号x规范化到均值为0,方差为1保证网络的稳定性。

    • 有一些从 0 到 1 而不是从 1 到 1000 的特征值,通过归一化所有的输入特征值?,以获得类似范围的值,可以加速学习。所以 Batch 归一化起的作用的原因,直观的一点就是,它在做类似的工作,但不仅仅对于这里的输入值,还有隐藏单元的值。
    • 它可以使权重比你的网络更滞后或更深层,比如,第 10 层的权重更能经受得住变化。
  5. 残差结构

    残差的方式,能使得深层的网络梯度通过跳级连接路径直接返回到浅层部分,使得网络无论多深都能将梯度进行有效的回传。

  6. LSTM

    LSTM全称是长短期记忆网络(long-short term memory networks),是不那么容易发生梯度消失的,主要原因在于LSTM内部复杂的“门”(gates)。在计算时,将过程中的梯度进行了抵消。

6. 随机梯度下降法(SGD)

6.1 mini-batch梯度下降

你可以把训练集分割为小一点的子集训练,这些子集被取名为 mini-batch,假设每一个子集中只有 1000 个样本,那么把其中的? (1)到? (1000)取出来,将其称为第一个子训练集,也叫做 mini-batch,然后你再取出接下来的 1000 个样本,从? (1001)到? (2000),然后再取 1000个样本,以此类推。

在训练集上运行 mini-batch 梯度下降法,你运行 for t=1……5000,因为我们有5000个各有 1000 个样本的组,在 for 循环里你要做得基本就是对? {?}和? {?}执行一步梯度下降法。

  • batch_size=1,就是SGD。
  • batch_size=n,就是mini-batch
  • batch_size=m,就是batch

其中1<n<m,m表示整个训练集大小。

优缺点:

  • batch:相对噪声低些,幅度也大一些,你可以继续找最小值。
  • SGD:大部分时候你向着全局最小值靠近,有时候你会远离最小值,因为那个样本恰好给你指的方向不对,因此随机梯度下降法是有很多噪声的,平均来看,它最终会靠近最小值,不过有时候也会方向错误,因为随机梯度下降法永远不会收敛,而是会一直在最小值附近波动。一次性只处理了一个训练样本,这样效率过于低下。
  • mini-batch:实践中最好选择不大不小的 mini-batch,得到了大量向量化,效率高,收敛快。

首先,如果训练集较小,直接使用 batch 梯度下降法,这里的少是说小于 2000 个样本。一般的 mini-batch 大小为 64 到 512,考虑到电脑内存设置和使用的方式,如果 mini-batch 大小是 2 的?次方,代码会运行地快一些。

6.2 调节 Batch_Size 对训练效果影响到底如何?

  1. Batch_Size 太小,模型表现效果极其糟糕(error飙升)。
  2. 随着 Batch_Size 增大,处理相同数据量的速度越快。
  3. 随着 Batch_Size 增大,达到相同精度所需要的 epoch 数量越来越多。
  4. 由于上述两种因素的矛盾, Batch_Size 增大到某个时候,达到时间上的最优。
  5. 由于最终收敛精度会陷入不同的局部极值,因此 Batch_Size 增大到某些时候,达到最终收敛精度上的最优。

7. 优化算法

7.1 动量法

在每次迭代中,梯度下降根据⾃变量当前位置,沿着当前位置的梯度更新⾃变量。然而,如果⾃变量的
迭代⽅向仅仅取决于⾃变量当前位置,这可能会带来⼀些问题。

让我们考虑⼀个输⼊和输出分别为⼆维向量x = [x1, x2]⊤和标量的⽬标函数

  • 11
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值