面向初学者的人工智能学习笔记-计算机视觉—深度学习训练技巧

发表时间:2024-04-18 13:40

随着神经网络变得越来越深入,其训练过程变得越来越具有挑战性。一个主要问题是所谓的梯度消失或梯度爆炸。 这篇文章很好地介绍了这些问题。

为了使深度网络的训练更加有效,可以使用一些技术。

将值保持在合理的区间内

为了使数值计算更加稳定,我们希望确保神经网络中的所有值都在合理的范围内,通常为 [-1..1] [0..1]。这不是一个非常严格的要求,但浮点计算的本质是不同量级的值无法精确地一起操作。例如,如果我们将 10-10 1010 加起来,我们很可能会得到 1010,因为较小的值会被“转换”为与较大的值相同的阶数,因此尾数会丢失。

大多数激活函数在 [-1..1] 附近具有非线性,因此将所有输入数据缩放到 [-1..1] [0..1] 区间是有意义的。

初始权重初始化

理想情况下,我们希望这些值在经过网络层后处于相同的范围内。因此,以保持值分布的方式初始化权重是很重要的。

正态分布 N(0,1) 不是一个好主意,因为如果我们有 n 个输入,则输出的标准差将为 n,并且值可能会跳出 [0..1] 区间。

经常使用以下初始化方式:

  • 均匀分布 —— uniform
  • N(0,1/n) —— gaussian
  • N(0,1/n_in) 保证对于均值为零且标准差为 1 的输入,将保持相同的均值/标准差
  • N(0,2/(n_in+n_out)) -- 所谓的 Xavier 初始化 (glorot),它有助于在前向和后向传播期间将信号保持在范围内


批量归一化

即使进行了适当的权重初始化,权重在训练过程中也可能变得任意大或小,并且它们将使信号超出适当的范围。我们可以通过使用一种归一化技术来恢复信号。虽然有几种(权重归一化、层归一化),但最常用的是批量归一化。

批量归一化的想法是考虑小批量中的所有值,并根据这些值执行归一化(即减去平均值并除以标准差)。它被实现为一个网络层,在应用权重之后但在激活函数之前进行归一化。因此,我们可能会看到更高的最终准确性和更快的训练。

Dropout

Dropout 是一种有趣的技术,它在训练过程中删除一定比例的随机神经元。它还被实现为具有一个参数的层(要删除的神经元的百分比,通常为 10%-50%),在训练过程中,它将输入向量的随机元素归零,然后将其传递到下一层。

这听起来像是一个奇怪的想法,但可以在 Dropout.ipynb 中看到 dropout 对训练 MNIST 数字分类器的影响。它加快了训练速度,使我们能够在更少的训练周期内获得更高的准确率。

这种影响可以用几种方式来解释:

  • 它可以被认为是模型的随机冲击因素,它从局部最小值中进行优化
  • 它可以被认为是隐式模型平均,因为我们可以说在 dropout 期间我们正在训练略有不同的模型


有人说,与清醒的人相比,当醉酒的人试图学习某些东西时,他第二天早上会记得更好,因为大脑中的一些神经元出现故障,试图更好地适应并理解其含义。我们从未测试过自己这是真的还是假的。

防止过度拟合

深度学习非常重要的方面之一就是能够防止过度拟合。虽然使用非常强大的神经网络模型可能很诱人,但我们应该始终平衡模型参数的数量与训练样本的数量。

有几种方法可以防止过拟合:

  • 早期停止——持续监控验证集上的错误,并在验证错误开始增加时停止训练。
  • 显式权重衰减/正则化——为权重绝对值较高的损失函数添加额外的惩罚,这可以防止模型获得非常不稳定的结果
  • 模型平均——训练多个模型,然后对结果进行平均。这有助于最小化方差。
  • Dropout(隐式模型平均)


优化器/训练算法

训练的另一个重要方面是选择好的训练算法。虽然经典梯度下降是一个合理的选择,但它有时可能太慢,或导致其他问题。

在深度学习中,我们使用随机梯度下降(SGD),这是一种应用于小批量的梯度下降,从训练集中随机选择。使用以下公式调整权重:

wt+1 = wt - η∇ℒ

动量

在动量 SGD 中,我们保留了之前步骤的一部分梯度。这类似于当我们以惯性运动到某处时,受到不同方向的一拳,我们的轨迹不会立即改变,而是保留原来运动的某些部分。这里我们引入另一个向量 v 来表示速度:

vt+1 = γ vt - η∇ℒ

wt+1 = wt+vt+1

这里参数 γ 表示我们考虑惯性的程度:γ=0 对应于经典 SGD;γ=1 是纯运动方程。

Adam, Adagrad

由于在每一层中,我们将信号乘以某个矩阵 Wi,根据 ||Wi||,梯度可以减小并接近 0,也可以无限地上升。这是梯度爆炸/消失问题的本质。

该问题的解决方案之一是在方程中仅使用梯度方向,而忽略绝对值,即

wt+1 = wt - η(∇ℒ/||∇ℒ||),其中 ||∇ℒ|| = √∑(∇ℒ)2

该算法称为 Adagrad。其他使用相同思想的算法:RMSPropAdam

对于许多应用程序来说,Adam 被认为是一种非常高效的算法,因此,如果您不确定使用哪一种算法,请使用 Adam

梯度裁剪

梯度裁剪是上述想法的延伸。当 ||∇ℒ|| ≤ θ,权重优化时考虑原始梯度,当||∇ℒ||> θ - 我们将梯度除以它的范数。这里 θ 是一个参数,大多数情况下我们可以取 θ=1 或 θ=10

学习率衰减

训练的成功通常取决于学习率参数 η。假设较大的 η 值会导致更快的训练(这是我们在训练开始时通常希望的)是合乎逻辑的,然后较小的 η 值允许我们微调网络。因此,在大多数情况下,我们希望在训练过程中减小 η。

这可以通过在训练的每个周期后将 η 乘以某个数字(例如 0.98)或使用更复杂的学习率计划来完成。

不同的网络架构

为问题选择正确的网络架构可能很棘手。通常,我们会采用一种已被证明适用于我们的特定任务(或类似任务)的架构。

选择一个对于我们拥有的训练样本数量来说足够强大的架构非常重要。选择过于强大的模型可能会导致过拟合。

另一个好方法是使用能够自动适应所需复杂性的架构。在某种程度上,ResNet 架构和 Inception 是自我调整的。


分享到: