深度学习实战:基于TensorFlow 2和Keras(原书第2版)
上QQ阅读APP看书,第一时间看更新

1.8 正则化

本节将回顾一些改进训练阶段的最佳实践。主要涉及正则化和批量归一化。

1.8.1 采用正则化以避免过拟合

直观地讲,好的机器学习模型应该在训练数据上达到较低的错误率。数学上,这等价于在给定模型的情况下,最小化训练数据的损失函数:

min:{loss(Training Data | Model)}

但是,这么做可能还不够。模型为了抓取训练数据原生表达的所有关系,可能变得过于复杂。这种复杂性的增加可能会带来两个负面结果。首先,复杂的模型可能需要大量时间才能运行。其次,复杂的模型在训练数据上可能会取得很好的性能,但在验证数据上却表现不佳。这是因为模型在特定的训练上下文中构造了许多参数之间的关系,但是实际上这些关系在更一般的上下文中并不存在。我们把这种导致模型失去泛化的能力称为“过拟合”。如图1-31所示。再次强调,学习更多的是有关泛化而不是记忆。

050-01

图1-31 损失函数和过拟合

根据经验,训练时如果看到损失函数值在验证集上起初减少,之后有所增加,则应该存在模型复杂性问题,它过拟合训练数据。

为了解决过拟合问题,需要一种方法来捕获模型复杂性,即模型本身的复杂程度。解决方案是什么?模型不过是权重向量。除了为零或非常接近零的权重值,每个权重值都会影响输出。因此,模型的复杂性可简便地由非零权重值个数表示。换句话说,如果有两个模型M1和M2在损失函数方面实现了几乎相同的性能,那么我们应该选择最简单的模型,即非零权重值最少的模型。

我们可以使用超参数λλ≥ 0)来控制具有简单模型的重要性,如以下公式所示:

min:{loss(Training Data | Model)}+λ*complexity(Model)

机器学习中使用了三种不同类型的正则化:

  • L1正则化(也称为LASSO):模型复杂性表示为权重绝对值的总和。
  • L2正则化(也称为Ridge):模型复杂性表示为权重的平方和。
  • 弹性正则化(elastic regularization):模型复杂性通过结合上述两种技术来捕获。

注意,使用正则化是提高网络性能的好办法,特别是在存在显著过拟合的情况下。这套实验为有兴趣的读者提供练习。

另外值得注意的是,TensorFlow支持L1、L2和ElasticNet正则化。可通过以下代码增加正则化:

050-02

011-03完整的正则化器可参考https://www.tensorflow.org/api_docs/python/tf/keras/regularizers。

1.8.2 理解批量归一化

BatchNormalization(批量归一化)是正则化的另一种形式,并且是近几年提出的最有效的改进之一。BatchNormalization可以加快训练速度,在某些情况下通过减半训练epoch数,并提供一些正则化方法。让我们看看其背后的直观思想。

在训练过程中,前置神经元层的权重值会自然而然地改变,而这会致使后置神经元层的输入产生显著变化。也就是说,每一层必须持续不断地调整其权重以适应每批次的不同分布特征。这可能会大大减缓模型的训练速度。为此,BatchNormalization的核心思想是使神经元层的输入在分布特征、相邻批次和相邻epoch之间更加相似。

另一个问题是,sigmoid激活函数值在接近零时非常奏效,但当值远大于零时,往往会“卡住”。假设神经元输出偶然波动到远离sigmoid函数的零值,那么该神经元就无法更新其自身权重。

因此,BatchNormalization的另一个核心思想是将神经元层的输出转换为接近零的高斯分布单元。这样,各批次之间的差异将大大减少。数学公式非常简单。通过减去其批次平均值μ,激活输入x将以零为中心。然后,将结果除以σ +∈(其中σ为批次的方差,∈为小偏移量),防止除以零。最后,使用线性变换y=λx+β确保在训练期间应用归一化。

通过上述方法,λβ作为训练阶段以相似方式在各层得到优化的参数。BatchNorma-lization已被证明是提高训练速度和准确度的行之有效的方法,因为它既有助于防止激活函数变得太小而消失,又能防止激活函数变得太大而激增。