庖丁解牛yolo_v4之CmBN
一文搞定深度学习中的规范化BN,LN,IN,GN,CBN凡心所向素履所往计算机视觉14 人赞同了该文章【写在前边】本笔记详细总结BN的原理及细节(均值标准差的计算,训练和测试的区别)和BN的改进版本LN IN GN CBN等。。。。论文:2015年Google提出了BNhttps://arxiv.org/pdf/1502.03167.pdf2016年多伦多大学提出了LNhttps://arxiv.
一文搞定深度学习中的规范化BN,LN,IN,GN,CBN
计算机视觉
14 人赞同了该文章
【写在前边】
本笔记详细总结BN的原理及细节(均值标准差的计算,训练和测试的区别)和BN的改进版本LN IN GN CBN等。。。。
论文:
2015年Google提出了BN
https://arxiv.org/pdf/1502.03167.pdf
2016年多伦多大学提出了LN
https://arxiv.org/pdf/1607.06450v1.pdf
2017年牛津提出了IN
https://arxiv.org/pdf/1607.08022.pdf
2018年何恺明FAIR提出了GN
https://arxiv.org/pdf/1803.08494.pdf
2020年清华&微软亚洲研究院提出了CBN
https://arxiv.org/abs/2002.05712
https://github.com/Howal/Cross-iterationBatchNorm
参考:
https://blog.csdn.net/ft_sunshine/article/details/99203548
https://blog.csdn.net/liuxiao214/article/details/81037416
https://blog.csdn.net/debug_moner/article/details/104477896/
本文目录:
一、BatchNormalization(BN)
二、Adaptive BN(AdaBN)
三、Layer Normalization(LN)
四、Weight Normalization(WN)
五、Instance Normalization(IN)
六、Group Normalization(GN)
七、Cross-Iteration Batch Normalizartion(CBN)
本文声明:
1.写该总结的初衷在于学习和记录,如有侵权,私聊我修改。
2.水平有限,不足之处感谢指出。
3.如有想法,欢迎讨论;如有收获,感谢收藏点赞;没有时间看的同学欢迎收藏mark;欢迎关注专栏,我将持续更新~~
推荐阅读:
(1)two/one-stage,anchor-based/free目标检测发展及总结:一文了解目标检测 https://zhuanlan.zhihu.com/p/100823629
(2)人体关键点检测(姿态估计)简介+分类汇总 https://zhuanlan.zhihu.com/p/102457223
(3)一文了解通用行为识别ActionRecognition:了解及分类 https://zhuanlan.zhihu.com/p/103566134
一、Batch Normalization(BN)
1.BN介绍
(1)提出BN的原因
解决Internal Covariate Shift问题:训练深层网络时,层内神经元间、层间神经元间激活值的量级差别较大,不满足iit独立同分布时,模型不稳定不容易收敛(直观来看解决方案要么自适应地调节每一层甚至每一个神经元的学习率,要么把神经元激活值规范化一下)。
缓解过拟合:深层网络容易过拟合,有时候dropout可能也解决不了
(2)批规范化BN,标准化Standardization,正则化Regularization
批规范化(Batch Normalization,BN):在minibatch维度上在每次训练iteration时对隐藏层进行归一化
标准化(Standardization):对输入数据进行归一化处理
正则化(Regularization):通常是指对参数在量级和尺度上做约束,缓和过拟合情况,L1 L2正则化
(3)BN公式
BN在2015年被提出,能有效提升网络收敛的稳定性和速度.在训练的每次iteration,BN会对隐藏层神经元的激活值做规范化(减均值,除标准差,这个均值和标准差是对当前的minibatch求解得到的).自然地,如果minibatch的尺寸是1的话,训练的时候学习不到任何东西,因为均值是它本身,方差是1,规范化之后神经元的值会变成0.但是,如果使用大规模的minibatch,BN是非常有效的.
简而言之,BN的思想就是将激活前隐层的值x变为BN(x),x减去均值除以标准差,这样隐层状态不再发散,之后的激活值也更规范,但有时候处理完之后的分布不一定是我们想要的(这样的规范反而会使网络表达能力下降),所以乘上缩放系数γ,加上偏移β。
(4)全连接层和卷积层BN的区别
全连接层BN:
全连接层BN通常会在线性变换之后激活之前进行,各个神经元间的均值和方差不共享,需要在mini-batch中计算各自的均值方差(线性变换之后求均值、方差),γ和β是当前层所有神经元共享的标量。
卷积层BN:
卷积层BN通常会在卷积之后,激活之前进行。多个卷积核卷积生成多通道的特征图,每个通道都要单独处理,各通道有自己的均值方差,γ,β,每个通道内部(一张特征图上)所有神经元共享均值方差(mini-batch数据卷积后m×w×h个神经元求均值方差)
(5)训练和测试BN的区别
训练的时候就按照(4)中的策略每次iteration都要根据隐层值计算新的均值方差,但是测试的时候我们可能没那么多数据(比如就预测一个样本),这时BN用的均值和方差是固定的常量(这个常量是在模型训练时每次iteration通过移动平均法更新的全局量,模型训练结束,这个全局量就是考虑了全量训练数据的常量了)。
Question:为什么训练的时候不用全量训练数据的均值和方差常量呢?
Answer:训练的时候为了模型稳定,需要在当前batch数据中维持隐藏层激活值的稳定,因此不用考虑别的数据,而且不同batch数据间的均值和方差可能差别较大,这个差别实际上能够增加模型鲁棒性,一定程度上减少过拟合,如果在训练的时候就用全量训练数据的均值和方差可能会加剧过拟合。
(6)BN的手动实现
BN
a:看代码可以看到,FC的话是在dim=0处求均值,Conv的话是在dim=0,2,3处求均值,dim=1是通道维度,dim=0是batch维度[B,C,W,H]。
b:训练的时候是每个训练iter都要去计算均值,测试是直接使用全局的均值(这个全局的均值是每次训练1iteration都会使用移动平均法迭代地更新一个全局的值,训练结束后就先相当于使用全量训练数据产生了一个全局的固定值了)。
LeNet using BN
(7)BN的自动实现nn.BatchNorm*d()
FC就用BatchNorm1d,Conv就用BatchNorm2d,需要指定的参数就是输出层神经元个数(FC)或者是输出特征图通道数(Conv)。
最后简单总结一下:
BN通过在mini-batch数据上对隐层状态进行规范化使得神经元状态处理匹配的量级上,加速和稳定模型的收敛,从2015提出开始,现在几乎是深度模型训练必备的trick了。公式和原理上来讲虽然简答,但主要要搞懂的地方如下:
a:全连接层和卷积层的BN是不太一样的(分别是在什么维度上求均值方差)
b:训练和预测时的BN是不一样的
接下来就来总结一些BN的改进
二、Ada BN
AdaBN也不算是对BN的改进,只是在迁移学习中,由于输入数据的源domain不同,BN层参数无法直接用(毕竟是从训练数据中求出来的),这时使用一种策略来缓解这个问题,就是所谓的AdaBN。
实现方法如下:
把模式设置为训练模式(torch.is_grad_enabled=True),但是在“训练”过程中不更新模型参数,而是在每一次iteration中只更新global mean和global variance,相当于是在新的数据集上“假装训练一遍”,得到在新数据集上的均值和方差,这样就可以用于新数据集上的推理了(当然可能模型参数并不一定适用于新数据,可能需要finetune甚至重新训练,但至少BN参数是在新数据集上自适应adaptive了)
三、Layer Normalization(LN)
1.BN的缺点
(1)BN操作的效果受batchsize影响很大,如果batchsize较小,每次训练计算的均值方差不具有代表性且不稳定,甚至使模型效果恶化。
(2)BN很难用在RNN这种序列模型中,且效果不好
(3)这一点算是BN的特点不能算是其缺点:训练和测试的BN参数是不同的
2.LN
(1)层规范化LayerNormalization,LN是对当前隐藏层整层的神经元进行规范化
(2)LN VS BN:
对于[B,C,W,H]这样的训练数据而言,BN是在B,W,H维度求均值方差进行规范化,而LN是对C,W,H维度求均值方差进行规范化(当前层一共会求batchsize个均值和方差,每个batchsize分别规范化)
这样LN就与batchsize无关了,小的batchsize也可以进行归一化训练,LN也可以很轻松地用到RNN中。
(3)总结
LN与batchsize无关,在小batchsize上效果可能会比BN好,但是大batchsize的话还是BN效果好。
LN可以轻松用到RNN上,且效果还不错
四、Weight Normalization(WN)
BN LN IN GN都是对神经元状态(输入数据)的规范化,而WN提出对权重进行规范化,其实本质上都是对数据的规范化。
WN是个神奇的操作,但效果上被BN LN IN GN碾压,所以这里只简单提一下有这么个操作。
五、Instance Normalization(IN)
1.背景
BN注重对batchsize数据归一化,但是在图像风格化任务中,生成的风格结果主要依赖于某个图像实例,所以对整个batchsize数据进行归一化是不合适的,因而提出了IN只对HW维度进行归一化。
http://2.IN
在图像风格化任务中,更合适使用IN来做规范化。
IN只对W,H维度求均值方差进行归一化。
六、Group Normalization(GN)
1.背景
BN依赖大batchsize,LN虽然不依赖batchsize,但是在CNN中直接对当前层所有通道数据进行规范化也不太好。
2.GN
GN先对通道进行分组,每个组内的所有C_i,W,H维度求均值方差进行规范化,也与batchsize无关。
到这里,给出一张图来对比一下BN LN IN GN,一目了然:
如果看这个图还不清晰的话,再来一组更直观的图:
首先给出一次训练iteration时某层数据示例:
那么BN的归一化范围就是下图红色部分:
LN和IN如下图
GN如下图
可以粗略的进行如下总结:
BN是最传统的,如果batchsize允许够大的话,用在CNN中的效果依然是最好的;LN适合RNN;IN适合图像风格化任务;GN更适合小batchsize的CNN训练
七、Cross-Iteration BN(CBN)
1.背景
还是为了解决BN在小batchsize时效果不好的问题
2.CBN
(1)作者认为连续几次训练iteration中模型参数的变化是平滑的
(2)作者将前几次iteration的BN参数保存起来,当前iteration的BN参数由当前batch数据求出的BN参数和保存的前几次的BN参数共同推算得出(顾名思义 Cross-Interation BN)
(3)训练前期BN参数记忆长度短一些,后期训练稳定了可以保存更长时间的BN参数来参与推算,效果更好
3.我个人的理解:
可以将CBN粗糙地总结为 “前几次训练的BN(LN/GN应该都可以)参数” + 当前batch数据计算的BN(LN/GN)参数 来计算得出当前次训练iteration真正的CBN参数。
当然具体如何推算可以去看论文
今天的总结就到这,可能有不准确的地方,大家可以指出~~~
盆友们看完点个赞再走吧~~~~~~~~~~~~~~~~
BN是由Google于2015年提出,这是一个深度神经网络训练的技巧,它不仅可以加快了模型的收敛速度,而且更重要的是在一定程度缓解了深层网络中“梯度弥散”的问题,从而使得训练深层网络模型更加容易和稳定。所以目前BN已经成为几乎所有卷积神经网络的标配技巧了。
从字面意思看来Batch Normalization(简称BN)就是对每一批数据进行归一化,确实如此,对于训练中某一个batch的数据{x1,x2,...,xn},注意这个数据是可以输入也可以是网络中间的某一层输出。在BN出现之前,我们的归一化操作一般都在数据输入层,对输入的数据进行求均值以及求方差做归一化,但是BN的出现打破了这一个规定,我们可以在网络中任意一层进行归一化处理,因为我们现在所用的优化方法大多都是min-batch SGD,所以我们的归一化操作就成为Batch Normalization。
我们为什么需要BN
我们知道网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。BN的提出,就是要解决在训练过程中,中间层数据分布发生改变的情况。
BN怎么做
如上图所示,BN步骤主要分为4步:
- 1、求每一个训练批次数据的均值
- 2、求每一个训练批次数据的方差
- 3、使用求得的均值和方差对该批次的训练数据做归一化。其中ε是为了避免除数为0时所使用的微小正数。
- 4、尺度变换和偏移:将乘以调整数值大小,再加上增加偏移后得到,这里的是尺度因子,是平移因子。这一步是BN的精髓,由于归一化后的基本会被限制在正态分布下,使得网络的表达能力下降。为解决该问题,我们引入两个新的参数:,。 和是在训练时网络自己学习得到的,如果,而,那么就会恢复到之前的原数据。
BN的优势
BN对神经网络训练可谓是有诸多优点,可以分成以下几个方面:
-
解决内部协变量偏移
(最近一篇论文否定了BN是改善内部协变量偏移的观点,参考论文How Does Batch Normalization Help Optimization?)
如果单单是做了减均值除方差归一化的操作,那么就会像图中这样子,把输入数据框定在以0为中心的一块区域,在这一区域内绝大多数激活函数都会有一个问题:函数梯度变化程线性增长,不能保证对数据的非线性变换,从而影响数据表征能力,降低神经网络的作用。
sigmoid函数是这样,其他主流的激活函数也一样,如图:
BN的本质就是利用优化变一下方差大小和均值位置,使得新的分布更切合数据的真实分布,保证模型的非线性表达能力。BN的极端的情况就是这两个参数等于mini-batch的均值和方差,那么经过batch normalization之后的数据和输入的数据分布基本保持一致。 -
使得梯度变平缓
我们知道,如果梯度变得平缓后就可以使用大的学习率(learning rate),从而使得学习速度变快加速收敛到最优点的时间。 -
优化激活函数
可以看到,同样的激活函数,在使用BN与不使用BN有着明显的差异(虚线代表没有使用,实线代表使用),使用BN后能在更短的时间达到较稳定的状态。 -
增强优化器作用
同样,在增强优化器功效方面BN也有一定的作用,比较典型的是sigmoid函数,在没有使用BN之前它的迭代是震荡的,不稳定的,在使用了BN之后有了非常明显的提升。 -
解决梯度弥散问题
拿sigmoid和relu来举例,如果没有使用BN的话,第一层与第二层蓝色的曲线相差会很大,但是使用了BN的黄色曲线相差的值其实并不是很多了。 -
使模型具有正则化效果
采用BN算法后可以选择更小的L2正则约束参数,因为BN本身具有提高网络泛化能力的特性。
总结
使用BN会有以下几个优点:
- 解决内部协变量偏移
- 使得梯度变平缓
- 优化激活函数
- 解决梯度弥散问题
- 使模型正则化具有正则化效果
(各大深度学习框架在搭建网络时需要指定BN层)
作者:机器不会学习
链接:https://www.jianshu.com/p/a78470f521dd
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
更多推荐
所有评论(0)