【深度学习】正则化:Batch Normal与Dropout

目录

正则化

0 正则化介绍

0.0 什么是正则化?

0.1 正则化解决什么问题?

0.2 正则化常用手段

1 L1、L2正则化

1.0 范数定义

1.1 L1正则化(Ridge回归)

1.2 L2正则化(LASSO回归)

1.3 弹性网络

1.4 参考文献

2 Batch Normalization

2.0 论文阅读

2.1 Batch Normalization作用

2.2 BN的添加位置及限定

2.3 Pytorch框架中的具体实现

2.4 参考文献


正则化

0 正则化介绍

0.0 什么是正则化?

《Deep Learning》书中定义正则化为“对学习算法的修改——旨在减少泛化误差而不是训练误差” ​ 模型可以看成是一个高维函数,对于不同的模型参数,能得到千千万万个不同的模型,我们将这所有的可能得到的模型称之为假设空间。我们只需要通过训练将生成真实数据的一组模型参数找出来即可。从已有的假设空间中通过训练找到一个泛化能力优秀的拟合模型。正则化可以帮助我们从假设空间中找到这样一个模型:训练误差较低,测试误差较低,而且模型复杂度也较小。所以正则化是一种优化模型的方法。

0.1 正则化解决什么问题?

过拟合。

过拟合造成原因(导致方差过大):
1、训练集和测试集的噪声数据分布不一致:训练集噪声和测试集噪声分布不一致。模型学到了训练集的噪声,但无法识别测试集的噪声。(Hinton在Dropout中提出的)
2、训练数据不足,参数量过大。

0.2 正则化常用手段

1)参数惩罚:L1称为lasso回归 L2称为Ridge回归 ​

2)增强数据集:镜像,缩放,旋转 ​

3)提前终止 ​

4)多任务学习:MTCNN 增加任务(引入置信度)增加损失函数 ​

5)dropout:理论上网络较深时,不会出现无任何神经元连接输出层 ​

6)标准化:LRN、BN(Batch Normalization)等

 

1 L1、L2正则化

1.0 范数定义

范数是衡量某个向量空间(或矩阵)中的每个向量以长度或大小。范数的一般化定义:对实数p>=1, 范数定义如下:

【深度学习】正则化:Batch Normal与Dropout

 

当p=1时,是L1范数,其表示某个向量中所有元素绝对值的和。

当p=2时,是L2范数, 表示某个向量中所有元素平方和再开根, 也就是欧几里得距离公式。

什么是稀疏化?稀疏化指的是神经元的权重为0。

1.1 L1正则化(Ridge回归)

  • 使用方式:

【深度学习】正则化:Batch Normal与Dropout

损失函数中加入L1正则项对W进行惩罚,抑制W,会使W抑制为0。 在剪枝时常用,平时训练时使用很可能导致网络稀疏化(退化)。

【深度学习】正则化:Batch Normal与Dropout

1.2 L2正则化(LASSO回归)

  • 使用方式:

【深度学习】正则化:Batch Normal与Dropout

损失函数中加入L2正则项对W进行惩罚,抑制W。

【深度学习】正则化:Batch Normal与Dropout

1.3 弹性网络

  • 综合L1、L2正则化对网络优化。

【深度学习】正则化:Batch Normal与Dropout

1.4 参考文献

【博客 —— L1、L2正则化详解】

【博客 —— 机器学习中正则化项L1和L2的直观理解】

【博客 —— 带约束的最优化问题】

 

2 Batch Normalization

2.0 论文阅读

Batch normalization是一种用于通过重新居中和重新缩放来对输入层进行规范化,从而使神经网络更快,更稳定的方法。

【Batch Normalization From Wikipedia】

通过减少隐藏层内部的变量偏移来加速网络的学习

论文: 【Batch Normalization】

Abstract

神经网络训练非常复杂,因为在训练过程中,最初的输入会随着前向过程发生变化,导致隐藏层各层输入的分布也会发生变化。这减缓了设置了较低的学习率、严格参数初始化和具有饱和非线性**函数的神经网络的训练。我们将这种情况称为内部协变量(协变量?)的偏移,并通过标准化每一层的输入来解决这个问题。这种方法的优势在于可以使用更高的学习率,并且对参数初始化不再那么敏感。它也起到了正则化的作用,并减少了在某些情况需要Dropout的情况。

1 Introduction

< 中间提到一大段关于SGD算法,暂时跳过; Mini-Batch SGD相对于One Example SGD的两个优势:梯度更新方向更准确;并行计算速度快;SGD训练的缺点:超参数调起来很麻烦。>

使用小批量的样本比使用单个样本多了以下好处:首先,小批量样本损失的梯度是对整个训练集梯度的估计,单批训练样本的质量随batch_size的增加而提高。其次,由于计算机的并行化处理设计,使得批量计算的效率远高于单个样本计算效率。

虽然随机梯度下降法简单有效,但它对网络模型的超参数、权重和学习率有较高的要求。每一层的输入都会受前面几层所有参数的影响,这使得训练变得复杂,且网络参数的微小变化会随着网络模型的加深而放大。

隐藏层输入分布的变化带来了后续层需要不断适应新的分布的问题。当输入到学习系统中的分布发生变化时,会被称为经验协变量偏移。而且这种偏移会在网络模型的各个部分发生。

固定子网络输入的分布对其他层也会产生积极影响。例如当**函数时为饱和函数Sigmiod时,当|x|过大时会使梯度接近于0,网络将难以训练。这种负面影响随网络层的加深而增大,但在实际应用中可以通过ReLU**函数、严格初始化和小的学习率来解决。然而,如果我们能够确保非线性输入的分布在网络训练时保持更稳定,那么优化器就不太可能陷入饱和状态,训练就会加速。

我们可以通过使用Batch Normalization消除网络内部输入的分布变换来实现给予网络较大的学习率进行训练。它通过一个标准化步骤修正了每层输入的平均值和方差。通过减少梯度对参数尺度(参数量)或参数初始值的依赖性,使得批处理归一化对网络梯度的反向传播也有有益的影响。这还使我们能够使用更高的学习率,而不会出现每层输入分布差异。此外,批量标准化正则化了模型,减少了辍学的需要(Srivastava等人,2014年)。最后,Batch Normalization可以通过防止网络输出陷入饱和区域使得我们可以使用饱和非线性的**函数。

We refer to the change in the distributions of internal nodes of a deep network, in the course of training, as Internal Covariate Shift. Eliminating it offers a promise of faster training. We propose a new mechanism, which we call Batch Normalization, that takes a step towards reducing internal covariate shift, and in doing so dramatically accelerates the training of deep neural nets. It accomplishes this via a normalization step that fifixes the means and variances of layer inputs. Batch Normalization also has a benefificial effect on the gradient flflow through the network, by reducing the dependence of gradients on the scale of the parameters or of their initial values. This allows us to use much higher learning rates with out the risk of divergence. Furthermore, batch normalization regularizes the model and reduces the need for Dropout (Srivastava et al., 2014). Finally, Batch Normalization makes it possible to use saturating nonlinearities by preventing the network from getting stuck in the saturated modes.

2 Towards Reducing Internal Covariate Shift

我们将内部协变量转移定义为训练过程中由于网络参数的变化而引起的网络**后分布的变化。为了改善训练,我们寻求减少内部协变量的偏移。通过在训练过程中固定隐藏层每层输入x的分布,可以提高训练速度。这一点是早就被发现的 (LeCun et al., 1998b; Wiesler & Ney, 2011) ,如果网络训练的输入被白化(whitened),即将输入线性变换为零均值和单位方差,并进行去相关,则网络训练的收敛速度更快。

< 剩余部分讲了训练时遇到的一些问题 >

3 Normalization via Mini-Batch Statistics

使用BN必须使用批梯度下降即最小的batch_size要大于1。

BN将标准化每一批同一纬度的输入,使其均值为0方差为1。比如当前层的神经元如图 【深度学习】正则化:Batch Normal与Dropout,我们将标准化这一批数据1号神经元的输入,其次标准化这一批数据同时输入2号神经元的数据,最后,标准化这一批数据同时输入3号神经元的数据。按神经元的维度使用下面公式对数据进行标准化:【深度学习】正则化:Batch Normal与Dropout,其中【深度学习】正则化:Batch Normal与Dropout为单个神经的第k个输入。

值得注意的是当**函数是Sigmoid或者tanh时,正则化可能使得**后的输出分布在非线性函数的线性区域内。所以我们使标准化的输出为 【深度学习】正则化:Batch Normal与Dropout,其中γ和β是为了保证**函数的非线性而设置的参数, 能使【深度学习】正则化:Batch Normal与Dropout 偏移到非线性区域。而且γ和β是可学习的,由训练集整体决定。当 【深度学习】正则化:Batch Normal与Dropout【深度学习】正则化:Batch Normal与Dropout时就会还原为BN前的分布。

小批次处理流程:

【深度学习】正则化:Batch Normal与Dropout

< 图1 >其中【深度学习】正则化:Batch Normal与Dropout为这一批数据。ε 为维持这一批样本方差的稳定性。 如果我们忽略ε和滑动系数【深度学习】正则化:Batch Normal与Dropout【深度学习】正则化:Batch Normal与Dropout的话,每一层同一个神经元的输入都将是相同的分布。

3.1 Training and Inference with BatchNormalized Networks

 

在推理(使用)的时候,对于输入将会使用训练时的整体均值和方差使用 【深度学习】正则化:Batch Normal与Dropout进行标准化。其中【深度学习】正则化:Batch Normal与Dropout,m为Batch_size大小。

由于推理时使用的是固定的均值和方差,BN就简单地视作一个**函数。

【深度学习】正则化:Batch Normal与Dropout

< 图2 >

3.2 Batch-Normalized Convolutional Networks

我们可以对输入层的输入使用BN,但是输入层的输入可能属于多峰分布(多高斯分布),而且在前两层使用BN并不会较少内部协变量的偏移。

注意到,我们对单个神经元的输出W·x+b进行了标准化,所以偏移量b是可以忽略的,因为偏移的作用包含在了公式 【深度学习】正则化:Batch Normal与Dropout【深度学习】正则化:Batch Normal与Dropout中。所以我们可以将 【深度学习】正则化:Batch Normal与Dropout替换为【深度学习】正则化:Batch Normal与Dropout进行计算(公式中g为**函数)。其中将BN变换独立应用于x = Wu的每个维度,每个维度具有一对独立的学习参数【深度学习】正则化:Batch Normal与Dropout【深度学习】正则化:Batch Normal与Dropout

对于卷积网络来说,我们希望BN服从卷积属性。所以我们改变了< 图1 >中的 【深度学习】正则化:Batch Normal与Dropout【深度学习】正则化:Batch Normal与Dropout,其中m为Batch_size,p、q为特征图的长宽。如下图中的有颜色的通道: 

【深度学习】正则化:Batch Normal与Dropout

此时BN针对的就是同一通道的数据进行优化。计算公式如下:

【深度学习】正则化:Batch Normal与Dropout【深度学习】正则化:Batch Normal与Dropout【深度学习】正则化:Batch Normal与Dropout

上图和公式来自于:[博客 —— 深入理解Batch Normalization]

3.3 Batch Normalization enables higher learning rates

未加BN的网络,过高的学习率可能会导致梯度消失和梯度爆炸,以及陷入局部最优解的情况。通过对整个网络进行标准化**,可以防止网络参数的细微变化导致网络梯度的剧烈变化和陷入局部最优解的情况。

BN也使网络训练更能适应参数范围。通常情况下,大的学习速率会增加层参数的尺度,从而放大反向传播过程中的梯度,导致模型爆炸。但是,使用批处理规范化,通过层的反向传播不受其参数范围的影响。对于w放大α倍则经过BN后所得结果不变,即【深度学习】正则化:Batch Normal与Dropout我们可以看到 【深度学习】正则化:Batch Normal与Dropout标量α不影响雅克比(Jacobian 这是嘛?)矩阵和梯度的方向传播。更大权重导致较小的梯度,BN将稳定参数增长。 < 后面讲了雅克比矩阵相关的一些东西,暂时不懂 >

3.4 Batch Normalization regularizes the model

当训练加入了BN的网络时,可见的是当前网络中的单个训练样本结合了同一批次的其他样本标准化后进行了训练,并且网络不再为当前的单个训练样本生成确定性的值,而是通过一批数据优化网络参数。这有利于提高网络的泛化力。而且我们可移除Dropout或降低Dropout的强度。

2.1 Batch Normalization作用

2.1.0 BN优缺点

优点:

1)对参数初始化的不敏感:在某些情况下可以取消 dropout 和 L2 正则项参数,或者采取更小的惩罚力度。由于BN会使隐藏层的输入维持在正太分布即输入都在[-1, 1]之间,即使当前层给予较大的w经过BN层后也会将数据拉回正太分布避免了梯度爆炸,避免梯度消失也同理。

2)对权重的尺度不再敏感:尺度同一由滑动系数γ决定。

3)减少了对学习率的要求:现在我们可以使用初始很大的学习率(或者选择了较小的学习率,算法也能够快速训练收敛——不知道是否正确)。

4)可以将bias置为0:因为标准化过程会移除直流分量,所以不再需要bias.

5)深度网络可以使用Sigmoid和tanh了:由于标准化和滑动系数,BN抑制了梯度消失。

< 破坏原来的数据分布,一定程度上缓解过拟合 >

缺点:

1)需要计算均值与方差,不适合动态网络或者RNN。

2)计算均值方差依赖每批次和大量的数据,批次较小时使用GN更好。

3)对于不符合正太分布的数据不适用。

2.2 BN的添加位置及限定

BN一般放在ReLU系列**函数之前,Sigmoid和tanh**含放在之后。但在实际使用中无太大区别。

BN和DropOut存在冲突,建议将其放在Dropout之前,并将Dropout率减小。(L2正则化与BN配合使用是否存在限制?)或者使用高斯Dropout的进阶版均值Dropout。

在使用时需要调net.eval()函数。

2.3 Pytorch框架中的具体实现

Pytorch框架在训练时,会统计所有批次的均值和方差;在测试时,会使用训练时统计的均值和方差对数据进行标准化,因为测试时很可能当前输入的batch_size为1,对于BN来说这是无法统计均值和方差的。所有批次的初始均值running_mean = 0、初始方差为running_var = 0,计算方式如下:

【深度学习】正则化:Batch Normal与Dropout

running_mean为以往样本加权求出的均值;running_var为以往样本加权求出的方差;momentum是一个参数为加权权重; μ为使用当前批次的所有样本求得的均值;σ为使用当前批次的所有样本求得的方差。

对于BN层测试的均值和方差是通过统计训练的时候所有的batch的均值和方差的加权平均值。

Pytorch框架中的BN

  • BatchNorm1d

  • 【深度学习】正则化:Batch Normal与Dropout

    • 对2D或3D输入(具有可选附加通道尺寸的1D输入的小批量)应用 批归一化

    • 【深度学习】正则化:Batch Normal与Dropout

    • 在微型批次上按维度计算均值和方差,并且γ和β是维度大小为C的可学习参数向量(其中C为输入大小)。默认情况下,γ的元素设置为1,β的元素设置为0。通过有偏估计量计算标准差,相当于torch.var(input,unbiased = False)。

    • 同样默认情况下,在训练过程中,该层会继续对其计算的均值和方差进行累加估算,然后将其用于推理阶段的标准化。 保持动态估算,默认动量momentum 为0.1。

    • 如果track_running_stats设置为False,则此层将不保留运行时对均值和方差估计,而是在推理期间也只使用当前批的处理统计信息。

    • 【深度学习】正则化:Batch Normal与Dropout

    • 参数:

      • num_features - 来自预期输入形状为(N,C,L)或(N,C)中的C

      • eps - 为分母增加数值的稳定性。默认值:1e-5

      • momentum – 用于动态计算训练时的均值和方差。可以设置None只计算当前批次样本的均值和方差。默认值:0.1

      • affine – 一个布尔值,当设置True为时,此模块具有可学习的仿射参数。若False则γ=1,β=0,gamma=1,beta=0,并且不能学习被更新。默认:True

      • track_running_stats – 一个布尔值,设置为时True,表示跟踪整个训练过程中所有batch的均值和方差统计信息,而不只是仅仅依赖与当前输入的batch的均值和方差;设置为时False,此模块不跟踪此模型所有样本的均值和方差统计信息,就只是计算当前输入的batch的均值和方差了了,且running_mean和running_var为None。当在推理阶段的时候,如果track_running_stats=False,此时如果batch_size比较小,那么其均值和方差就会和全局均值和方差有着较大偏差。默认:True

    • 形状:

      • 输入: (N,C) or (N,C, L)

      • 输出: 输出和输入同形状 (N,C) or (N,C, L)

 

  • BatchNorm2d

  • 【深度学习】正则化:Batch Normal与Dropout

    • 对4D输入(具有可选附加通道尺寸的2D输入的小批量)应用 批归一化

    • 【深度学习】正则化:Batch Normal与Dropout

    •  

    • 在微型批次上按维度计算均值和方差,并且γ和β是维度大小为C的可学习参数向量(其中C为输入大小)。默认情况下,γ的元素设置为1,β的元素设置为0。通过有偏估计量计算标准差,相当于torch.var(input,unbiased = False)。

    • 同样默认情况下,在训练过程中,该层会继续对其计算的均值和方差进行累加估算,然后将其用于推理阶段的标准化。 保持动态估算,默认动量momentum 为0.1。

    • 如果track_running_stats设置为False,则此层将不保留运行时对均值和方差估计,而是在推理期间也只使用当前批的处理统计信息。

    • 【深度学习】正则化:Batch Normal与Dropout

  • 参数:

      • num_features - 来自预期输入形状为(N,C,H, W)中的C

      • eps - 为分母增加数值的稳定性。默认值:1e-5

      • momentum – 用于动态计算训练时的均值和方差。可以设置None只计算当前批次样本的均值和方差。默认值:0.1

      • affine – 一个布尔值,当设置True为时,此模块具有可学习的仿射参数。若False则γ=1,β=0,gamma=1,beta=0,并且不能学习被更新。默认:True

      • track_running_stats – 一个布尔值,设置为时True,表示跟踪整个训练过程中所有batch的均值和方差统计信息,而不只是仅仅依赖与当前输入的batch的均值和方差;设置为时False,此模块不跟踪此模型所有样本的均值和方差统计信息,就只是计算当前输入的batch的均值和方差了了,且running_mean和running_var为None。当在推理阶段的时候,如果值为False,此时如果batch_size比较小,那么其均值和方差就会和全局均值和方差有着较大偏差。默认:True

    • 形状:

      • 输入: (N,C, H, W)

      • 输出: 输出和输入同形状 (N,C, H, W)

  • BatchNorm3d

  • 【深度学习】正则化:Batch Normal与Dropout

    • 对5D输入(具有可选附加通道尺寸的3D输入的小批量)应用 批归一化

    • 【深度学习】正则化:Batch Normal与Dropout

    • 在微型批次上按维度计算均值和方差,并且γ和β是维度大小为C的可学习参数向量(其中C为输入大小)。默认情况下,γ的元素设置为1,β的元素设置为0。通过有偏估计量计算标准差,相当于torch.var(input,unbiased = False)。

    • 同样默认情况下,在训练过程中,该层会继续对其计算的均值和方差进行累加估算,然后将其用于推理阶段的标准化。 保持动态估算,默认动量momentum 为0.1。

    • 如果track_running_stats设置为False,则此层将不保留运行时对均值和方差估计,而是在推理期间也只使用当前批的处理统计信息。

    • 【深度学习】正则化:Batch Normal与Dropout

  • 参数:

      • num_features - 来自预期输入形状为(N,C,D, H, W)中的C

      • eps - 为分母增加数值的稳定性。默认值:1e-5

      • momentum – 用于动态计算训练时的均值和方差。可以设置None只计算当前批次样本的均值和方差。默认值:0.1

      • affine – 一个布尔值,当设置True为时,此模块具有可学习的仿射参数。若False则γ=1,β=0,gamma=1,beta=0,并且不能学习被更新。默认:True

      • track_running_stats – 一个布尔值,设置为时True,表示跟踪整个训练过程中所有batch的均值和方差统计信息,而不只是仅仅依赖与当前输入的batch的均值和方差;设置为时False,此模块不跟踪此模型所有样本的均值和方差统计信息,就只是计算当前输入的batch的均值和方差了了,且running_mean和running_var为None。当在推理阶段的时候,如果值为False,此时如果batch_size比较小,那么其均值和方差就会和全局均值和方差有着较大偏差。默认:True

    • 形状:

      • 输入: (N,C,D, H, W)

      • 输出: 输出和输入同形状 (N,C,D, H, W)

2.4 参考文献

【博客 —— 深入理解Batch Normalization批标准化】

【博客 —— Pytorch-BN层详细解读】

【博客 —— PyTorch中的Batch Normalization】

【知乎 —— Batch Normalization原理与实战】

 

更新日志:

2020/11/14 --- 更新正则化介绍、L1和L2正则化,以及Batch Normalization