Batch Normalization:Accelerating Deep Network Training by Reducing Internal Concariate Shift《》

本文探讨了深度学习中Batch Normalization(BN)的作用及其如何解决Internal Covariate Shift问题,加速训练过程并允许使用更高学习率。BN通过归一化每层的输入,改善了梯度消失和梯度爆炸现象,简化了网络权重初始化,支持更多激活函数,有助于构建更深层的神经网络。

internal covariate shift:
由于训练过程中网络参数的变化,导致网络内部激活层分布的变化。
这种思想的由来:
1,统计机器学习中有一个经典的假设:训练数据和测试数据是满足相同分布的。covariate shift:训练集的样本数据分布变化时,训练得到的模型无法很好的Generalization。
2,在神经网络中的各输出层可以作为下一层的输入层,也就是输出层可以作为训练数据,但每一层所指的label不变,所以如果各输出层如果分布不一样,就可以当作是covariate shift。

Introduce
1,介绍了SGD的优缺点,优点比如mini-batch,简单有效之类的。缺点,调参困难,特别是学习率和初始值。参数小的波动会扩大影响整个网络,特别是网络很深的时候。接着通过F2(F1(u,θ1),θ2)F_2(F_1(u,\theta_1),\theta_2)F2(F1(u,θ1),θ2)说明,如果输入输出的分布相同,θ2\theta_2θ2就无需调整去补偿x的分布的变化。也是ICS的思想
2,通过sigmod函数的分析,得到当|x|增大时,会导致导数的值趋于0,从而使得x陷入饱和区域,梯度消失。这里也提出另外一些工作比如relu,xavier的初始化。
3,提出ICS,并大致介绍了batch normalization的优点,后文会具体介绍。

Towards Reducing ICS
引入的思想:1,降低ICS。 2,当输入white时,网络训练的收敛速度变快。
大致介绍了在中心化的过程中(不包括除以方差),bias项的改变对中心化后的x没有影响。也就是说x^=x−E(x)x=u+b\hat{x} = x - E(x)\\ x= u + bx^=xE(x)x=u+b与b无关。因此不需要添加b。又通过矩阵Conv[x]=E[xxT]−E[x]E[x]TConv[x] = E[xx^T] - E[x]E[x]^TConv[x]=E[xxT]E[x]E[x]T标准化Conv−1/2(x−E(x))Conv^{-1/2}(x-E(x))Conv1/2(xE(x))x是层输入,Conv[x]是协方差矩阵,可以看出全维度的normalization的计算量非常大。

Normalzation via Mini-Batch Statistics
这部分反而是最简单的,作者对normalization进行了两个优化
1、由于全维度的normalization计算量太大,对每个特征维度分别进行normalization。比如有d个维度的输入x=(x(1)...,x(d))x = (x^{(1)} ...,x^{(d)})x=(x(1)...,x(d))
x^(k)=x(k)−E(x(k))Var[x(k)]\hat{x}^{(k)} = \frac{x^{(k)} - E(x^{(k)})}{\sqrt{Var[x^{(k)}]}}x^(k)=Var[x(k)]x(k)E(x(k))
作者提出简单的normalization可能会改变层中输入的表达,所以引入γk,βk\gamma_k,\beta_kγk,βk,当γk=x(k)\gamma_{{k}} = \sqrt{x^{(k)}}γk=x(k) β(k)=E(x(k))\beta^{(k)} = E(x^{(k)})β(k)=E(x(k))时,还原原始的输入值。
2、由于对整个训练集进行normalization计算量太大(主要是后续的batch normalization的backwards),在SGD中又使用了mini-batch,刚好对mini-batch中的数据进行normalization。

在这里插入图片描述
文中通过进一步的梯度推导公式,也说明了该函数可微分,可以进行backwards。
公式具体如下:
在这里插入图片描述
然后是它在测试集上的应用。测试集中使用的方差是方差的无偏估计(无偏估计指的是估计量的数学期望等于被估计参数)
在这里插入图片描述
对于cnn,文中将cnn中的每个特征图当成一个神经元,因此在使用Batch Normalization,mini-batch size 的大小就是:mpq,于是对于每个特征图都只有一对可学习参数:γ、β。说白了吧,这就是相当于求取所有样本所对应的一个特征图的所有神经元的平均值、方差,然后对这个特征图神经元做归一化。
batch normalization 允许使用更大的学习率,在一般情况下当学习率增大时,w变化的范围变大,会导致w的范围变大,从而在正向传播时,每一层的输出范围会变大,在反向传播时,可以大概知道对w求导的导数,与层输出相关,会导致反向传播的值很大,学习率又偏大,就可能导致梯度爆炸。
在这里插入图片描述

而当进行正则化之后,每一层的输出范围确定。W较大,BN()反向传播的梯度反而减小,有利于遏制梯度爆炸

优点:
1,有效遏制了梯度消失和梯度爆炸。
2,解决了internal covariate shift的问题,将训练集和测试集强行拉到标准正态分布。

衍生的优点:
1,训练更快,优点(1,2)
2,容忍更高的学习率 优点(2)
3,让权重更容易初始化 优点(2)
4. 可支持更多的激活函数 优点(2)
5. 简化创建深层的神经网络

### Batch Normalization(BN)原理 Batch Normalization 由 Sergey Ioffe 和 Christian Szegedy 在 2015 年提出,旨在解决深度神经网络训练过程中的内部协变量偏移(Internal Covariate Shift)问题。内部协变量偏移指的是在训练过程中,随着前一层参数的更新,每一层输入的分布会发生变化,这使得后续层需要不断适应新的输入分布,从而导致训练速度变慢。 BN 的核心思想是对每一批次的输入数据进行归一化处理,使得输入数据的均值为 0,方差为 1。对于一个输入的 mini - batch 数据 $x = \{x_1, x_2, \cdots, x_m\}$,BN 的计算步骤如下: 1. 计算 mini - batch 的均值 $\mu_B$: $\mu_B=\frac{1}{m}\sum_{i = 1}^{m}x_i$ 2. 计算 mini - batch 的方差 $\sigma_B^2$: $\sigma_B^2=\frac{1}{m}\sum_{i = 1}^{m}(x_i - \mu_B)^2$ 3. 对输入数据进行归一化: $\hat{x}_i=\frac{x_i-\mu_B}{\sqrt{\sigma_B^2+\epsilon}}$,其中 $\epsilon$ 是一个很小的常数,用于防止分母为 0。 4. 引入可学习的参数 $\gamma$ 和 $\beta$ 进行缩放和平移: $y_i=\gamma\hat{x}_i+\beta$ 通过这种方式,BN 不仅将输入数据归一化到标准正态分布,还通过可学习的参数 $\gamma$ 和 $\beta$ 让模型能够根据自身需求调整数据的分布,增强了模型的表达能力。 ### Batch Normalization 在 YOLOv2 中的应用 YOLOv2 是一种目标检测算法,在其网络结构中引入了 Batch Normalization 带来了多方面的好处: - **加速训练**:由于 BN 解决了内部协变量偏移问题,使得网络在训练过程中每一层的输入分布更加稳定,减少了后续层对输入分布变化的适应过程,从而加快了训练速度。在 YOLOv2 中,使用 BN 后可以显著减少训练所需的迭代次数。 - **提高模型泛化能力**:BN 具有一定的正则化作用,它在一定程度上减少了模型对特定训练数据的依赖,降低了过拟合的风险。在 YOLOv2 中,使用 BN 可以提高模型在不同数据集和场景下的检测性能。 - **去除 Dropout**:在 YOLOv2 中,由于 BN 的正则化效果,模型不再需要使用 Dropout 来防止过拟合。Dropout 是一种随机丢弃神经元的正则化方法,而 BN 通过对数据分布的调整达到了类似的效果,并且避免了 Dropout 在训练和测试阶段不同处理方式带来的问题。 以下是一个简单的 PyTorch 代码示例,展示了如何在神经网络中使用 Batch Normalization: ```python import torch import torch.nn as nn # 定义一个简单的卷积神经网络,包含 BN 层 class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1) self.bn1 = nn.BatchNorm2d(16) self.relu = nn.ReLU() def forward(self, x): x = self.conv1(x) x = self.bn1(x) x = self.relu(x) return x # 创建模型实例 model = SimpleCNN() # 生成随机输入数据 input_data = torch.randn(1, 3, 32, 32) # 前向传播 output = model(input_data) print(output.shape) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值