logo

模型正则化

王哲峰 / 2022-07-15


目录

监督学习的目的

监督机器学习的目的是为了让建立的模型能够发现数据中普遍的一般的规律, 这个普遍的一般的规律无论对于训练集还是未知的测试集,都具有较好的拟合能力。 假设空间中模型千千万,当我们站在上帝视角,心里相信总会有个最好的模型可以拟合我们的训练数据, 而且这个模型不会对训练集过度学习,它能够从训练集中尽可能的学到适用于所有潜在样本的“普遍规律”, 不会将数据中噪声也学习了。这样的模型也就是我们想要的、能够有较低的泛化误差的模型

过拟合和欠拟合

过拟合

过拟合是指在机器学习模型训练过程中,模型对训练数据学习过度, 将数据中包含的噪声和误差也学习了,使得模型在训练集上表现很好, 而在测试集上表现很差的一种现象

过拟合发生的原因:

解决或者缓解过拟合的方法:

欠拟合

过拟合的反面是欠拟合。当在测试数据上仍有改进空间时就会发生欠拟合, 这种情况意味着模型尚未学习训练数据中的相关模式

欠拟合发生的原因:

机器学习正则化

正则化的目的是防止模型出现过拟合

正则化

监督机器学习的核心问题是确定正则化参数的同时最小化经验风险,最小化经验风险是为了让模型更加充分的拟合给定的训练数据。 而正则化参数则控制的是模型的复杂度,防止模型过分的拟合训练数据

下面的公式是机器学习中最核心、最关键、最能概述监督学习的核心思想的公式

$$argmin \frac{1}{N}\sum_{i=1}^{N}L(y_i, f(x_i; \delta)) + \lambda J(f)$$

从上面的公式可以看出,监督机器学习的模型效果的控制有两项

对于正则化项,$\lambda$ 是正则化系数,通常是大于 0 的较小的正数(0.01,0.001,…), 是一种调整经验误差和正则化项之间关系的系数。所以, 在实际的训练过程中,$\lambda$ 作为一种超参数很大程度上决定了模型的好坏

对于正则化项,正则化项的形式有很多,但常见的也就是 L1 和 L2 正则化。也有 L0 正则化

Lp 范数

范数可以理解为用来表征向量空间中的距离,而距离的定义很抽象, 只要满足非负、自反、三角不等式就可以称之为距离

Lp 范数不是一个范数,而是一组范数,其定义如下:

$$||x||_{p} = \bigg(\sum_{i}^{n}x_{i}^{p}\bigg)^{\frac{1}{p}}$$

其中 $p$ 的范围是 $[1, \infty)$$p$ 在范围 $(0, 1)$ 内定义的并不是范数,因为违反了三角不等式

根据 $p$ 的变化,范数有着不同的变化,下面是一个经典的有关 $p$ 范数的变化图。 表示 $p$$0$$\infty$变化时,单位球(unit ball) 的变化情况:

img

可以看到:当 $0 < p < 1$ 时,单位球(unit ball)并不是凸集,而在 $p \geq 1$ 范数定义下的单位球(unit ball)都是凸集

L0 范数

L0 范数表示向量中非零元素的个数:

$$||x||_{0} = \#(i|x_{i} \neq 0)$$

可以通过最小化 L0 范数寻找最少最优的稀疏特征项。但不幸的是, L0 范数的最优化问题是一个 NP hard 问题(L0 范数同样是非凸的)。 因此,在实际应用中我们经常对 L0 进行凸松弛,理论上有证明, L1 范数是 L0 范数的最优凸近似,因此通常使用 L1 范数来代替直接优化 L0 范数

L1 范数

L1 范数定义

L1 范数就是向量各元素的绝对值之和:

$$||x||_{1} = \sum_{i}^{n}|x_{i}|$$

L1 正则化

带 L1 范数的回归被称为最小绝对值收敛和选择算子、套索算法(LASSO regularization)

$$\min \frac{1}{N}\sum_{i=1}^{N}L(y_i, f(x_i)) + \lambda ||w||$$

以 L1 范数作为正则项,对模型有两个好处:

L2 范数

L2 范数定义

$$||x||_{2}=\sqrt{\sum_{i}^{n}(x_{i}^{2})}$$

L2 正则化

带 L2 范数的回归,也叫岭回归(Ridge Regression),或权值衰减(Weight Decay)

$$\min \frac{1}{N}\sum_{i=1}^{N}L(y_i, f(x_i)) + \frac{1}{2} \lambda ||w||^{2}$$

L1 正则与 L2 正则的区别

一般理解角度

下图分别是带 L2 正则项的回归问题(左侧)、带 L1 正则项的回归问题(右侧)。 蓝色的圆圈表示问题可能的解范围,橘色的表示正则项可能的解范围。 而整个目标函数(经验风险 + 正则项)有解当且仅当两个解范围相切

img

从上图可以很容易地看出:

所以有如下结论,L1 范数可以导致稀疏解,L2 范数导致稠密解

贝叶斯先验角度

从贝叶斯先验的角度看,当训练一个模型时,仅依靠当前的训练数据集是不够的, 为了实现更好的泛化能力,往往需要加入先验项,而加入正则项相当于加入了一种先验

img

神经网络正则化

数据增强

提前终止

权值衰减

权值衰减(weight decay)

损失函数正则化

L1 和 L2 正则化

未正则化的交叉熵损失函数

$$J = -\frac{1}{n}\sum_{i=1}^{n}\Big(y_{i}\log(\hat{y}^{(L)}_{i}) + (1 - y_{i})\log(1 - \hat{y}^{(L)}_{i})\Big)$$

L1 正则化

$$J = \underbrace{-\frac{1}{n}\sum_{i=1}^{n}\Big(y_{i}\log(\hat{y}^{(L)}_{i}) + (1 - y_{i})\log(1 - \hat{y}^{(L)}_{i})\Big)}_{\text{cross-entropy cost}} + \underbrace{\frac{1}{n}\lambda\sum_{l}\sum_{k}\sum_{j} ||W_{k,j}^{[L]}||}_{\text{L1 regularization cost}}$$

L2 正则化

L2 正则化的交叉熵损失函数

$$J = \underbrace{-\frac{1}{n}\sum_{i=1}^{n}\Big(y_{i}\log(\hat{y}^{(L)}_{i}) + (1 - y_{i})\log(1 - \hat{y}^{(L)}_{i})\Big)}_{\text{cross-entropy cost}} + \underbrace{\frac{1}{n}\frac{1}{2}\lambda\sum_{l}\sum_{k}\sum_{j} W_{k,j}^{[L]2}}_{\text{L2 regularization cost}}$$

Dropout

原理

当网络的模型变得很复杂时,权值衰减方法不能有效地对过拟合进行抑制。就需要使用 Dropout 方法

Dropout 是深度学习中经常采用的一种正则化方法。它的做法可以简单的理解为在 DNNs 训练的过程中, 为网络每一层的神经元设定一个失活(drop)概率 $p$ 丢弃部分神经元, 即使得被丢弃的神经元输出为 0。在网络图上则表示为该神经元节点的进出连线被删除。 最后会得到一个神经元更少、模型相对简单的神经网络,能够在很大程度上简化神经网络结构,防止神经网络过拟合

img

如果在卷积网络的末端有全连接层,那么很容易实现 Dropout。当然 Dropout 也只适用于 CNN 的全连接层, 对于所有其他层,不应该使用 Dropout。相反,应该在卷积之间插入批处理标准化。这将使模型规范化, 并使模型在训练期间更加稳定

神经网络训练时,每传递一次数据,就会随机选择要删除的神经元,然后将其删除,被删除的神经元不再进行信号的传递。 测试时,虽然会传递所有的神经元信号,但是对于各个神经元的输出,要乘上训练时的删除比例后再输出

正则化解释

在 Dropout 每一轮训练过程中随机丢弃神经元的操作相当于多个 DNNs 进行取平均, 因此用于预测时具有 vote 的效果

减少神经元之间复杂的共适应性。当隐藏层神经元被随机删除之后, 使得全连接网络具有了一定的稀疏化,从而有效地减轻了不同特征的协同效应。 也就是说,有些特征可能会依赖于固定关系的隐含节点的共同作用, 而通过 Dropout 的话,就有效地阻止了某些特征在其他特征存在下才有效果的情况, 增加了神经网络的鲁棒性

因为 Dropout 可以随时随机的丢弃任何一个神经元,神经网络的训练结果不会依赖于任何一个输入特征, 每一个神经元都以这种方式进行传播,并为神经元的所有输入增加一点权重, Dropout 通过传播所有权重产生类似于 L2 正则化收缩权重的平方范数的效果, 这样的权重压缩类似于 L2 正则化的权值衰减,这种外层的正则化起到了防止过拟合的作用。 所以说,总体而言,Dropout 的功能类似于 L2 正则化,但又有所区别

使用

另外需要注意的一点是,对于一个多层的神经网络,Dropout 某层神经元的概率并不是一刀切的。 对于不同神经元个数的神经网络层,可以设置不同的失活或者保留概率, 对于含有较多权值的层,可以选择设置较大的失活概率(即较小的保留概率)

所以,总结来说就是如果担心某些层所含神经元较多或者比其他层更容易发生过拟合, 可以将该层的失活概率设置的更高一些

Dropout 和 BN

在最近的网络结构设计中,Batch Normalization 在很大程度上取代了现代卷积体系结构中的 Dropout。 原因有如下几点:

  1. 首先,Dropout 对卷积层的正则化效果一般较差
    • 因为卷积层的参数很少,所以一开始就不需要太多的正则化。此外,由于特征映射中编码的空间关系, 激活变得高度相关,这使得 Dropout 无效。
  2. 其次,Dropout 规范化的研究已经过时了
    • 像 VGG16 这样的大型模型在网络的末端包含了完全连接的层。对于这样的模型, 通过在完全连接的层之间包含 Dropout 层来解决过拟合问题。 不幸的是,最近的网络架构设计逐渐抛弃了这种全连接结构。 通过全局平均池化(global average pooling)代替密集层(dense), 在提高性能的同时减小了模型大小

Batch Normalization

归一化

规范化、归一化,Normalization

归一化的目标是找到某种映射关系,将原数据映射到区间 $[a, b]$ 上。一般 $[a, b]$ 会取 $[-1, 1]$$[0, 1]$ 这些组合。 归一化的缩放是“拍扁”统一到区间,缩放仅仅跟最大、最小值的差别有关

归一化一般有两种应用场景:

常用归一化方法为 Min-Max Normalization:

$$x' = \frac{x - min(x)}{max(x) - min(x)}$$

归一化后,不同维度之间的特征在数值上有一定比较性,可以大大提高分类器的准确性,即提升模型精度

标准化

标准化,Standardization

用大数定理将数据转化为一个标准正态分布。标准化的缩放是更加“弹性”和“动态”的,和整体样本的分布有很大的关系。 缩放和每个点都有关系,通过方差体现出来

标准化公式为:

$$x' = \frac{x - \mu}{\sigma}$$

标准化后,最优解的寻优过程明显会变得平缓,更容易正确的收敛到最优解,即加速模型收敛

原理介绍

在神经网络模型训练过程中,当更新之前的权重(weight)时,每个中间激活层的输出分布会在每次迭代时发生变化, 这种现象为内部协变量位移(ICS)

关于内部协变量位移(ICS,Internal Covariate Shift) 解释参考知乎的解释

大家都知道在统计机器学习中的一个经典假设是“源空间(source domain)和目标空间(target domain)的数据分布(distribution)是一致的”。 如果不一致,那么就出现了新的机器学习问题,如 transfer learning/domain adaptation 等。 而 Covariate Shift 就是分布不一致假设之下的一个分支问题,它是指源空间和目标空间的条件概率是一致的, 但是其边缘概率不同。大家细想便会发现,的确,对于神经网络的各层输出,由于它们经过了层内操作作用, 其分布显然与各层对应的输入信号分布不同,而且差异会随着网络深度增大而增大, 可是它们所能“指示”的样本标记(label)仍然是不变的,这便符合了 Covariate Shift 的定义

Batch Normalization 的基本思想其实相当直观, 因为神经网络在做非线性变换前的激活输入值($X = WU + BX = WU + B$$U$ 是输入)随着网络深度加深, 其分布逐渐发生偏移或者变动(即上述的 Covariate Shift)。 之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于 Sigmoid 函数来说, 意味着激活输入值 $X = WU+B$ 是大的负值或正值),所以这导致后向传播时低层神经网络的梯度消失, 这是训练深层神经网络收敛越来越慢的本质原因。而 BN 就是通过一定的规范化手段, 把每层神经网络任意神经元这个输入值的分布强行拉回到均值为 0 方差为 1 的标准正态分布, 避免因为激活函数导致的梯度弥散问题。所以与其说 Batch Normalization 的作用是缓解 Covariate Shift, 倒不如说 Batch Normalization 可缓解梯度弥散问题

所以很自然的一件事就是,如果想防止这种情况发生,就得需要修正所有的分布。 简单地说,如果分布变动了,会限制这个分布,不让它移动,以帮助梯度优化和防止梯度消失, 这样能帮助神经网络更快。因此减少这种内部协变量位移是推动 Batch Normalization 发展的关键原则

Batch Normalization 严格意义上讲属于归一化手段,主要用于加速神经网络的收敛,但也具有一定程度的正则化效果。 Batch Normalization 的思路是调整各层的激活值分布使其拥有适当的广度。 为此,要向神经网络中插入对数据分布进行的正规化层,即 Batch Normalization 层, 通过将这个处理插入到激活函数的前面或后面,可以减小数据分布的偏向

Batch Normalization,顾名思义,以进行学习时的 batch 为单位,按 batch 进行规范化。 具体来说,就是对 batch 数据进行数据分布的均值为 0,方差为 1 的正规化,即通过在 batch 上减去经验平均值, 除以经验标准差来对前一个输出层的输出进行规范化。这将使数据看起来接近高斯分布

img

数学表示如下:

$$\hat{x_i} = \frac{x_i - \mu_B}{\sqrt{\sigma_{B}^{2} + \varepsilon}}$$

其中:

接着 Batch Normalization 层会对正规化后的数据进行缩放和平移的变换,数学表示如下:

$$y_{i} \leftarrow \gamma \hat{x}_{i} + \beta$$

其中:

优缺点

优点:

缺点:

在 Batch Normalization 无法很好工作的情况下,有几种可替代方法可用:

参考