上一章:八、(一)预训练网络与迁移学习
更多章节:人工智能入门课程
目录
随着神将网络深度增加,其训练过程变得越来越具有挑战性。一个做主要的问题是所谓的梯度消失或者梯度爆炸。这个帖子很好的介绍了这些问题。
为了使深度网络训练更有效,有一些技术可以使用。
保持值在合理的区间内
为了使数值计算更稳定,我们希望确保神经网络中使用的所有值都在合理的范围。通常是[-1..1]或者[0..1]。这不是非常严格的要求,但是浮点数计算的性质是,不同量级的值不能准确的一起操作。比如,如果我们把和相加,我们可能会得到,因为较小的值会转换为与较大的值相同的量级,从而较小的数以尾数的形式丢失了。
大多数激活函数在[-1..1]附近具有非线性的特性,因此,将所有输入数据缩小到[-1..1] 或者 [0..1]区间是有意义的。
初试权重初始化
理想情况下,我们希望通过神经网络层后,所有的值都在相同的范围内。因此,以保持值分布的方式来初始化权重很重要。
正态分布N(0,1)并不是很好的主意,因为如果我们有n个输入,输出的标准差会是n,同时输出值可能会跳出[0..1]区间。
以下初始化方式经常被用到:
- 均匀分布--均匀
- N(0,1/n) -- 高斯
- N(0,1/√n_in) 确保对于均值为0并且标准差为1的输入,将保持相同的均值/标准差。
- N(0,√2/(n_in+n_out)) -- 所谓的Xavier初始化 (glorot),它不管在前向还是后向传播中都有助于将信号保持在范围内。
批量归一化
即使进行了适当的权重初始化,权重都可能在训练过程中变得非常大或者非常小,从而导致信号超出合理范围。我们可以通过使用一种归一化技术将信号恢复。虽然有多种(权重归一化,层归一化),但最常用的还是批量归一化。
批量归一化的思想是考虑整个小批量中的所有值,并根据这些值进行归一化(即减去均值并除以标准差)。归一化被实现为一个网络层,该归一化层位于应用权重之后,激活函数之前。应用归一化后,我们可能会看到更高的最终准确度和更快的训练速度。
这是关于批量归一化的 原始论文,维基百科上的解释,和一篇很好的介绍性的博客文章(以及俄语版的)。
随机失活(Dropout)
Dropout 是一种有趣的技术,在训练时按照一定的百分比随机移除神经元。它也被实现为一个带一个参数的层(神经元被移除的百分比通常为10%-50%),在训练过程中,在它将向量传输到下一层之前,它随机将输入向量的元素置零。
虽然这可能听起来像一个奇怪的想法,你可以看到Dropout.ipynb笔记中,dropout在训练MINIST数字分类器时的效果。它加快了训练速度,并且可以使我们在更少的训练周期取得更高的准确率。
这种效果可以用几种方式解释:
- 它可以被当作模型的随机冲击因子(a random shocking factor),使得优化脱离局部(采样集)最小值。
- 因为可以说在dropout期间,我们在训练稍有不同的模型,它可以被认为是隐式的取了模型的平均。
有些人说,当一个喝醉了的人尝试学习一些东西,他相比于没喝醉的人在第二天早晨会记得更清楚,因为一个大脑存在部分功能障碍的神经元时,会尝试更好的适应来理解它的含义。我们从未对自己测试过,这是不是正确的。
防止过拟合
深度学习中最重要的一个方面是能够防止过拟合。尽管使用非常强大的神经网络模型非常具有诱惑力,我们始终需要平衡模型的参数数量和模型的样本数量。
确保您理解我们之前已经介绍过的过拟合的概念。
有几种方法可以阻止过拟合:
- 提前停止训练--持续检测验证数据集上的误差,并在验证误差开始上升时停止训练。
- 显示权重衰减/规则化--给权重绝对值很高的损失函数增加一个额外的惩罚,以防止模型产生不稳定的结果。
- 模型平均--训练多个模型,然后求取结果的平均值。这有助于最小化方差(variance).
- 随机失活--Dropout (隐式模型平均)
优化器/训练算法
训练的另一个非常重要的方面是,选择一个好的训练算法。虽然经典梯度下降是一个合理的选择,但它有时可能太慢,或者会产生其他问题。
在深度学习中,我们使用随机梯度下降(SGD),这是一种应用于从训练集随机选取的小批量数据集的梯度下降。它使用如下公式调整权重:
= - η∇ℒ
动量(Momentum)
在动量随机梯度下降(momentum SGD)中,我们保留先前步骤的一部分的梯度。这就好像,当我们带着惯性向某个方向运动,然后我们受到一个其他方向的力,我们的轨迹不会立即变化,还会保持一部分原始的运动。这里我们引入另一个向量v来表示速度:
- = γ - η∇ℒ
- = +
这里参数γ代表我们考虑惯性的程度:γ=0代表经典SGD;γ=1是一个纯运动方程。
亚当(Adam), 阿达格拉德(Adagrad)等
因为在每一层,我们使用信号乘以矩阵Wi,根据||Wi||,梯度可以减小并接近0,也可以无限上升。这就是梯度爆炸/消失问题的本质。
这个问题的解决方法是,在方程中仅使用梯度的方向,并忽略绝对值,即:
= - η(∇ℒ/||∇ℒ||), where ||∇ℒ|| = √∑(∇ℒ)
这个算法被称作Adagrad。另一些算法使用了相同的思想有:RMSProp, Adam。
Adam在许多应用中非常有效,如果您不确定使用哪个算法,那就使用Adam。
梯度裁剪(Gradient clipping)
梯度裁剪是上面思想的延伸。当 ||∇ℒ|| ≤ θ,我们使用权重优化中的原始梯度,当||∇ℒ|| > θ ,我们将梯度除以其范数(norm)。这里θ是一个参数,在大多数情况下,我们可以取 θ=1 或 θ=10。
学习率衰减
训练的成功,常常依赖于学习率参数η。逻辑上来说,更大的η值可以加快训练,这通常是我们在训练初期希望的,而较小的η允许我们微调(fine-tune)网络。因此,在大多数情况下,我们希望在训练过程中η逐渐减小。
这可以在通过在每个训练周期后将η乘以某个数字(例如0.98),或者使用更复杂的学习率调度来实现。
不同的网络结构
为你的问题选择正确的网络架构可能有些棘手。通常,我们会选择已经被证明适用于我们特定(或者相似的)任务有效的架构。这是一个有关计算机视觉的神经网络架构的很好的概述。
选择一个对我们拥有的训练样本数量而言足够强大的架构很重要。选择过于强大的模型可能会导致过拟合。
另一个好的方法是,使用能够自动调整所需复杂性的架构。在某些程度上,ResNet架构和Inception是自动调整的。更多计算机视觉架构。
上一章:八、(一)预训练网络与迁移学习
更多章节:人工智能入门课程