【BN】《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》

本文探讨了Batch Normalization在深度学习中的应用,解决了训练过程中内部协变量偏移的问题,加速了模型训练,并提高了模型的稳定性。通过实验验证,BN不仅能够显著提高训练速度,还能使Sigmoid激活函数收敛,实现高精度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

ICML-2015


在 CIFAR-10 上的小实验可以参考如下博客:
【Keras-Inception v2】CIFAR-10



1 Background and Motivation

机器学习中存在一个training data 和 testing data 分布不一致的问题,叫做 Covariate Shift

我们讲的规范一点(【机器学习】covariate shift现象的解释):
假设q1(x)是测试集中一个样本点的概率密度,q0(x)是训练集中一个样本点的概率密度。最终我们估计一个条件概率密度p(y|x,θ),它由x和一组参数θ={θ1,θ2…θm}所决定。对于一组参数来说,对应loss(θ)函数评估性能的好坏
综上,当我们找出在q0(x)分布上最优的一组θ’时,能否保证q1(x)上测试时也最好呢?
传统机器学习假设训练集和测试集是独立同分布的,即q0(x)=q1(x),所以可以推出最优θ’依然可以保证q1(x)最优。但现实当中这个假设往往不成立,伴随新数据产生,老数据会过时,当q0(x)不再等于q1(x)时,就被称作covariate shift

作者注意到
The distribution of each layer’s inputs changes during training(这也就是 Internal Covariate Shift

缺点如下:

  • slows down the training by requiring lower learning rates and careful parameter initialization
  • hard to train models with saturating nonlinearities

作者的解决方法:normalization for each training mini-batch
在这里插入图片描述
代码见附录

初始化不好,Wx+b 偏大或者偏小,Sigmoid’(Z)很小,梯度消失,网络越深越明显(反向传播的时候,激活函数的导数和W会随着网络的向前深入一直连乘下去)

解决办法:

  • Relu
  • careful initialization
  • small learning rate

作者的解决办法
ensure that the distribution of nonlinearity inputs remains more stable as the network trains

注意一个前提
It is based on the premise that convariate shift also applies to sub-network and layers.

2 Advantages

  • reaching 4.9% top-5 validation error (and 4.8% test error), exceeding the accuracy of human raters.

3 Innovations

注意到了 Internal Covariate Shift 的问题,并提出BN,大大加速训练速度

4 Method

4.1 Batch Normalization

在这里插入图片描述

x = Wu+b


可导性证明
在这里插入图片描述

y y y l l l 的关系就是损失函数,用链式求导法则感觉怪怪的,比如 ∂ l ∂ μ B \frac{\partial l}{\partial \mu_{B}} μBl 中, x ^ i = f 1 ( μ B , σ B 2 ) \hat{x}_{i} =f_1(\mu_{B}, \sigma_{B}^{2}) x^i=f1(μB,σB2) , σ B 2 = f 2 ( μ B ) \sigma_{B}^{2} = f_2(\mu_{B}) σB2=f2(μB) ,按链式求导法则应该是

∂ l ∂ μ B = ∂ l ∂ x ^ i ⋅ ( ∂ x ^ i ∂ σ B 2 ⋅ ∂ σ B 2 ∂ μ B + ∂ x ^ i ∂ μ B ) + ∂ l ∂ σ B 2 ⋅ ∂ σ B 2 ∂ μ B \frac{\partial l}{\partial \mu_{B}} = \frac{\partial l}{\partial \hat{x}_{i} } \cdot (\frac{\partial \hat{x}_{i} }{\partial \sigma_{B}^{2} } \cdot \frac{\partial \sigma_{B}^{2} }{\partial \mu_{B} }+ \frac{\partial \hat{x}_{i} }{\partial \mu_{B} }) + \frac{\partial l}{\partial \sigma_{B}^{2} } \cdot \frac{\partial \sigma_{B}^{2} }{\partial \mu_{B} } μBl=x^il(σB2x^iμBσB2+μBx^i)+σB2lμBσB2

而论文的做法是

∂ l ∂ μ B = ∂ l ∂ x ^ i ⋅ ∂ x ^ i ∂ μ B + ∂ l ∂ σ B 2 ⋅ ∂ σ B 2 ∂ μ B \frac{\partial l}{\partial \mu_{B}} = \frac{\partial l}{\partial \hat{x}_{i} } \cdot \frac{\partial \hat{x}_{i} }{\partial \mu_{B} } + \frac{\partial l}{\partial \sigma_{B}^{2} } \cdot \frac{\partial \sigma_{B}^{2} }{\partial \mu_{B} } μBl=x^ilμBx^i+σB2lμBσB2

∂ l ∂ x i \frac{\partial l}{\partial x_i} xil 也是这样处理的,不晓得是我记错了还是神经网路的求导不一样,有待我进一步否定自己


在这里插入图片描述

注意测试的时候 μ \mu μ σ \sigma σ 要固定下来,固定的方法如下(参考 【深度学习】深入理解Batch Normalization批标准化):

因为每次做Mini-Batch训练时,都会有那个Mini-Batch里m个训练实例获得的均值和方差,现在要全局统计量,只要把每个Mini-Batch的均值和方差统计量记住,然后对这些均值和方差求其对应的数学期望即可得出全局统计量。也即步骤10所示!

Q:疑问?为什么要来个 m m − 1 \frac{m}{m-1} m1m m m m 是 batch size
A:在概率统计里,当计算方差时,如果期望已知,则除以 m m m,如果期望需要用样本的均值估计出来,则除以 m − 1 m-1 m1

训练的时候方差已知,除以 m m m,现在方差是估计值,除以 m − 1 m-1 m1

11 由如下表达式推导得来
y = γ ⋅ x − E [ x ] V a r [ x ] + ε + β y = \gamma \cdot \frac{x-E[x]}{\sqrt{Var[x]+\varepsilon }} + \beta y=γVar[x]+ε xE[x]+β


4.2 Inception-v2

有些人总结 v2和v3都出自一篇论文(【Inception-v3】《Rethinking the Inception Architecture for Computer Vision》),结构一样,只是穿上了钢铁侠的盔甲,v3 = v2 + RMSProp + LSR + BN auxiliary

也有些人认为 v2 是出自本片博客讲述的论文(《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》),此论文对 Inception-v1 做了一点点小改进。

  • 5×5 to 两个 3×3
  • parameters 增加 25%,computational cost 增加 30%
  • 28×28 的 Inception 数量 2 to 3
  • average pooling + max pooling 交替,v1中最后用 average pooling,中间都是 max pooling
  • 有 pass through 结构

个人还是倾向于 BN+小改进的 Inception-v1 = Inception-v2,结构如下
在这里插入图片描述
【Inception-v1】《Going Deeper with Convolutions》 的结构见表1

5 Datasets

LSVRC 2012

6 Experiments

1)小试牛刀——MINIST
在这里插入图片描述
分布看不懂可以想想成是高斯分布,面积的15%,50%,80%

2)加速版 BN

加速技术

  • Increase learning rate
  • Remove Dropout
  • Reduce the L2 weight regularization
  • Accelerate the learning rate decay
  • Remove Local Response Normalization
  • Shuffle training examples more thoroughly
  • Reduce the photometric distortions

加速版本

  • Inception-v1
  • BN-baseline = Inception-v1 + BN,initial learning rate is 0.0015
  • BN-x5:learning rate*5 = 0.0075
  • BN-x30:learning rate*30 = 0.045
  • BN-x5-Sigmoid:Sigmoid instead of Relu

3)华山论剑(掌门solo)
在这里插入图片描述
不得不佩服的是 BN使得 Sigmoid 都能收敛,而且精度相当高(Without Batch Normalization, Inception with sigmoid never achieves better than 1/1000 accuracy.)霸气如斯!!!

需要注意的是 BN-x30 反而比 BN-x5 慢,但是最终精度高

BN 大大的提升了训练的速度

在这里插入图片描述

4)决战光明顶(门派混战——ensemble)
在这里插入图片描述

7 Conclusion / Future work

7.1 Conclusion

BN 是加在 activation function 之前的,而且是以 mini-batch 来计算,不像之前的有些工作加在activation function 之后。

BN 能使得训练更稳定,网络能用更大的 learning rate(会快许多),不那么 care initial 的质量,有些 regularization 的味道,in some case eliminating the need for Dropout.

Q1:链式求导法则的疑惑
Q2:Algorithm 2 的通透理解
Q3:归一化后 γ \gamma γ (scale)and β \beta β (shift)的作用以及意义
Q4:Batch Normalization also makes training more resilient to the parameters scale. 公式证明的理解


参考学习来自 [深度学习框架]PyTorch常用代码段

当使用 torch.nn.DataParallel 将代码运行在多张 GPU 卡上时,PyTorch 的 BN 层默认操作是各卡上数据独立地计算均值和标准差,同步 BN 使用所有卡上的数据一起计算 BN 层的均值和标准差,缓解了当批量大小(batch size)比较小时对均值和标准差估计不准的情况,是在目标检测等任务中一个有效的提升性能的技巧。

sync_bn = torch.nn.SyncBatchNorm(num_features, eps=1e-05, momentum=0.1, affine=True, 
                                 track_running_stats=True)

将已有网络的所有BN层改为同步BN层

def convertBNtoSyncBN(module, process_group=None):
    '''Recursively replace all BN layers to SyncBN layer.

    Args:
        module[torch.nn.Module]. Network
    '''
    if isinstance(module, torch.nn.modules.batchnorm._BatchNorm):
        sync_bn = torch.nn.SyncBatchNorm(module.num_features, module.eps, module.momentum, 
                                         module.affine, module.track_running_stats, process_group)
        sync_bn.running_mean = module.running_mean
        sync_bn.running_var = module.running_var
        if module.affine:
            sync_bn.weight = module.weight.clone().detach()
            sync_bn.bias = module.bias.clone().detach()
        return sync_bn
    else:
        for name, child_module in module.named_children():
            setattr(module, name) = convert_syncbn_model(child_module, process_group=process_group))
        return module

7.2 Future work

  • BN+RNN
  • domain adaptation

We believe that further theoretical analysis of the algorithm would allow still more improvements and applications.

8 Other normalizations

在这里插入图片描述
更形象化的理解,四种 normalization 如下所示
在这里插入图片描述
在这里插入图片描述

9 附录 sigmoid

import matplotlib.pyplot as plt
import numpy as np
import math
x = np.arange(-10,10,1)
y = 1/(1+ math.e**-x)
z = y*(1-y)
plt.plot(x,y)
plt.plot(x,z)
plt.xlabel("z = Wx+b")
plt.ylabel("Sigmoid")
ax = plt.gca()
#去掉边框
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
#移位置 设为原点相交
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

plt.legend(["Sigmoid (z)", "Sigmoid' (z)"])# 图例
plt.grid()#网格
plt.savefig('1.jpg')
plt.show()

Batch Normalization原理与实战

在这里插入图片描述


《How does batch normalization help optimization?》(NIPS-2018)

在这里插入图片描述
在这里插入图片描述

参考

【1】当我们的经验无法适应新环境的时候该怎么办? Covariate Shift(★★★)
【2】深度学习中 Batch Normalization为什么效果好? - 我不坏的回答 - 知乎
https://www.zhihu.com/question/38102762/answer/391649040 (★★★★★,防止梯度消失爆炸)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值