来聊聊批归一化BN(Batch Normalization)层

2023-12-18 12:48

本文主要是介绍来聊聊批归一化BN(Batch Normalization)层,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点击上方“AI算法修炼营”,选择加星标或“置顶”

标题以下,全是干货

一、Batch Normalization是什么?

Batch Normalization (BN) 是最早出现的,也通常是效果最好的归一化方式。feature map:  包含 N 个样本,每个样本通道数为 C,高为 H,宽为 W。

对其求均值和方差时,将在 N、H、W上操作,而保留通道 C 的维度。具体来说,就是把第1个样本的第1个通道,加上第2个样本第1个通道 ...... 加上第 N 个样本第1个通道,求平均,得到通道 1 的均值(注意是除以 N×H×W 而不是单纯除以 N,最后得到的是一个代表这个 batch 第1个通道平均值的数字,而不是一个 H×W 的矩阵)。

求通道 1 的方差也是同理。对所有通道都施加一遍这个操作,就得到了所有通道的均值和方差。具体公式为:

如果把  类比为一摞书,这摞书总共有 N 本,每本有 C 页,每页有 H 行,每行 W 个字符。BN 求均值时,相当于把这些书按页码一一对应地加起来(例如第1本书第36页,第2本书第36页......),再除以每个页码下的字符总数:N×H×W,因此可以把 BN 看成求“平均书”的操作(注意这个“平均书”每页只有一个字),求标准差时也是同理。

我们可以在 pytorch 下自己写一个 BN ,看看和官方的版本是否一致,以检验上述理解是否正确:

# coding=utf8
import torch
from torch import nn# track_running_stats=False,求当前 batch 真实平均值和标准差,
# 而不是更新全局平均值和标准差
# affine=False, 只做归一化,不乘以 gamma 加 beta(通过训练才能确定)
# num_features 为 feature map 的 channel 数目
# eps 设为 0,让官方代码和我们自己的代码结果尽量接近
bn = nn.BatchNorm2d(num_features=3, eps=0, affine=False, track_running_stats=False)# 乘 10000 为了扩大数值,如果出现不一致,差别更明显
x = torch.rand(10, 3, 5, 5)*10000
official_bn = bn(x)# 把 channel 维度单独提出来,而把其它需要求均值和标准差的维度融合到一起
x1 = x.permute(1,0,2,3).view(3, -1)mu = x1.mean(dim=1).view(1,3,1,1)
# unbiased=False, 求方差时不做无偏估计(除以 N-1 而不是 N),和原始论文一致
# 个人感觉无偏估计仅仅是数学上好看,实际应用中差别不大
std = x1.std(dim=1, unbiased=False).view(1,3,1,1)my_bn = (x-mu)/stddiff=(official_bn-my_bn).sum()
print('diff={}'.format(diff)) # 差别是 10-5 级的,证明和官方版本基本一致

二、BN的优势与作用

BN使得网络中每层输入数据的分布相对稳定,加速模型学习速度

BN通过规范化与线性变换使得每一层网络的输入数据的均值与方差都在一定范围内,使得后一层网络不必不断去适应底层网络中输入的变化,从而实现了网络中层与层之间的解耦,允许每一层进行独立学习,有利于提高整个神经网络的学习速度。当学习率设置太高时,会使得参数更新步伐过大,容易出现震荡和不收敛。但是使用BN的网络将不会受到参数数值大小的影响。

BN使得模型对网络中的参数不那么敏感,简化调参过程,使得网络学习更加稳定

在神经网络中,我们经常会谨慎地采用一些权重初始化方法(例如Xavier)或者合适的学习率来保证网络稳定训练。

BN允许网络使用饱和性激活函数(例如sigmoid,tanh等),缓解梯度消失问题

在不使用BN层的时候,由于网络的深度与复杂性,很容易使得底层网络变化累积到上层网络中,导致模型的训练很容易进入到激活函数的梯度饱和区;通过normalize操作可以让激活函数的输入数据落在梯度非饱和区,缓解梯度消失的问题;另外通过自适应学习 与又让数据保留更多的原始信息。
BN具有一定的正则化效果

在Batch Normalization中,由于我们使用mini-batch的均值与方差作为对整体训练样本均值与方差的估计,尽管每一个batch中的数据都是从总体样本中抽样得到,但不同mini-batch的均值与方差会有所不同,这就为网络的学习过程中增加了随机噪音,与Dropout通过关闭神经元给网络训练带来噪音类似,在一定程度上对模型起到了正则化的效果。另外,原作者通过也证明了网络加入BN后,可以丢弃Dropout,模型也同样具有很好的泛化效果。

三、BN的局限

局限1:如果Batch Size太小,则BN效果明显下降。

BN是严重依赖Mini-Batch中的训练实例的,如果Batch Size比较小则任务效果有明显的下降。那么多小算是太小呢?图10给出了在ImageNet数据集下做分类任务时,使用ResNet的时候模型性能随着BatchSize变化时的性能变化情况,可以看出当BatchSize小于8的时候开始对分类效果有明显负面影响。之所以会这样,是因为在小的BatchSize意味着数据样本少,因而得不到有效统计量,也就是说噪音太大。这个很好理解,这就类似于我们国家统计局在做年均收入调查的时候,正好把你和马云放到一个Batch里算平均收入,那么当你为下个月房租发愁之际,突然听到你所在组平均年薪1亿美金时,你是什么心情,那小Mini-Batch里其它训练实例就是啥心情。

BN的Batch Size大小对ImageNet分类任务效果的影响(From GN论文)

BN的Batch Size大小设置是由调参师自己定的,调参师只要把Batch Size大小设置大些就可以避免上述问题。但是有些任务比较特殊,要求batch size必须不能太大,在这种情形下,普通的BN就无能为力了。比如BN无法应用在Online Learning中,因为在线模型是单实例更新模型参数的,难以组织起Mini-Batch结构。 

局限2:对于有些像素级图片生成任务来说,BN效果不佳;

对于图片分类等任务,只要能够找出关键特征,就能正确分类,这算是一种粗粒度的任务,在这种情形下通常BN是有积极效果的。但是对于有些输入输出都是图片的像素级别图片生成任务,比如图片风格转换等应用场景,使用BN会带来负面效果,这很可能是因为在Mini-Batch内多张无关的图片之间计算统计量,弱化了单张图片本身特有的一些细节信息。

局限3:RNN等动态网络使用BN效果不佳且使用起来不方便

对于RNN来说,尽管其结构看上去是个静态网络,但在实际运行展开时是个动态网络结构,因为输入的Sequence序列是不定长的,这源自同一个Mini-Batch中的训练实例有长有短。对于类似RNN这种动态网络结构,BN使用起来不方便,因为要应用BN,那么RNN的每个时间步需要维护各自的统计量,而Mini-Batch中的训练实例长短不一,这意味着RNN不同时间步的隐层会看到不同数量的输入数据,而这会给BN的正确使用带来问题。假设Mini-Batch中只有个别特别长的例子,那么对较深时间步深度的RNN网络隐层来说,其统计量不方便统计而且其统计有效性也非常值得怀疑。另外,如果在推理阶段遇到长度特别长的例子,也许根本在训练阶段都无法获得深层网络的统计量。综上,在RNN这种动态网络中使用BN很不方便,而且很多改进版本的BN应用在RNN效果也一般。

局限4:训练时和推理时统计量不一致

对于BN来说,采用Mini-Batch内实例来计算统计量,这在训练时没有问题,但是在模型训练好之后,在线推理的时候会有麻烦。因为在线推理或预测的时候,是单实例的,不存在Mini-Batch,所以就无法获得BN计算所需的均值和方差,一般解决方法是采用训练时刻记录的各个Mini-Batch的统计量的数学期望,以此来推算全局的均值和方差,在线推理时采用这样推导出的统计量。虽说实际使用并没大问题,但是确实存在训练和推理时刻统计量计算方法不一致的问题。

上面所列BN的四大罪状,表面看是四个问题,其实深入思考,都指向了幕后同一个黑手,这个隐藏在暗处的黑手是谁呢?就是BN要求计算统计量的时候必须在同一个Mini-Batch内的实例之间进行统计,因此形成了Batch内实例之间的相互依赖和影响的关系。如何从根本上解决这些问题?一个自然的想法是:把对Batch的依赖去掉,转换统计集合范围。在统计均值方差的时候,不依赖Batch内数据,只用当前处理的单个训练数据来获得均值方差的统计量,这样因为不再依赖Batch内其它训练数据,那么就不存在因为Batch约束导致的问题。在BN后的几乎所有改进模型都是在这个指导思想下进行的。

但是这个指导思路尽管会解决BN带来的问题,又会引发新的问题,新的问题是:我们目前已经没有Batch内实例能够用来求统计量了,此时统计范围必须局限在一个训练实例内,一个训练实例看上去孤零零的无依无靠没有组织,怎么看也无法求统计量,所以核心问题是对于单个训练实例,统计范围怎么算?

四、BN的折叠优化

折叠Batch Normalization,也叫作折叠BN。我们知道一般BN是跟在卷积层后面,一般还会接上激活函数,也就是conv+BN+relu这种基本组件,但在部署的时候前向推理框架一般都会自动的将BN和它前面的卷积层折叠在一起,实现高效的前向推理网络。

我们知道卷积层的计算可以表示为:

然后BN层的计算可以表示为:

我们把二者组合一下,公式如下:

然后令

那么,合并BN层后的卷积层的权重和偏置可以表示为:

值得一提的是,一般Conv后面接BN的时候很多情况下是不带Bias的,这个时候上面的公式就会少第二项。

由于完整代码太长,完整可以参考这个工程:https://github.com/BBuf/cv_tools/blob/master/merge_bn.py

def fuse(conv, bn):global ii = i + 1# ********************BN参数*********************mean = bn.running_meanvar_sqrt = torch.sqrt(bn.running_var + bn.eps)gamma = bn.weightbeta = bn.bias# *******************conv参数********************w = conv.weightif conv.bias is not None:b = conv.biaselse:b = mean.new_zeros(mean.shape)if(i >= 2 and i <= 7):b = b - mean + beta * var_sqrtelse:w = w * (gamma / var_sqrt).reshape([conv.out_channels, 1, 1, 1])b = (b - mean)/var_sqrt * gamma + betafused_conv = nn.Conv2d(conv.in_channels,conv.out_channels,conv.kernel_size,conv.stride,conv.padding,groups=conv.groups,bias=True)fused_conv.weight = nn.Parameter(w)fused_conv.bias = nn.Parameter(b)return fused_conv

参考资料:

1、《深度学习算法优化系列十一 | 折叠Batch Normalization》

2、《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》

3、《How Does Batch Normalization Help Optimization?》

4、https://zhuanlan.zhihu.com/p/43200897

目标检测系列秘籍一:模型加速之轻量化网络秘籍二:非极大值抑制及回归损失优化秘籍三:多尺度检测秘籍四:数据增强秘籍五:解决样本不均衡问题秘籍六:Anchor-Free视觉注意力机制系列Non-local模块与Self-attention之间的关系与区别?视觉注意力机制用于分类网络:SENet、CBAM、SKNetNon-local模块与SENet、CBAM的融合:GCNet、DANetNon-local模块如何改进?来看CCNet、ANN
语义分割系列一篇看完就懂的语义分割综述最新实例分割综述:从Mask RCNN 到 BlendMask超强视频语义分割算法!基于语义流快速而准确的场景解析CVPR2020 | HANet:通过高度驱动的注意力网络改善城市场景语义分割基础积累系列卷积神经网络中的感受野怎么算?
图片中的绝对位置信息,CNN能搞定吗?理解计算机视觉中的损失函数深度学习相关的面试考点总结自动驾驶学习笔记系列 Apollo Udacity自动驾驶课程笔记——高精度地图、厘米级定位 Apollo Udacity自动驾驶课程笔记——感知、预测 Apollo Udacity自动驾驶课程笔记——规划、控制自动驾驶系统中Lidar和Camera怎么融合?竞赛与工程项目分享系列如何让笨重的深度学习模型在移动设备上跑起来基于Pytorch的YOLO目标检测项目工程大合集目标检测应用竞赛:铝型材表面瑕疵检测基于Mask R-CNN的道路物体检测与分割
SLAM系列视觉SLAM前端:视觉里程计和回环检测视觉SLAM后端:后端优化和建图模块视觉SLAM中特征点法开源算法:PTAM、ORB-SLAM视觉SLAM中直接法开源算法:LSD-SLAM、DSO视觉SLAM中特征点法和直接法的结合:SVO
2020年最新的iPad Pro上的激光雷达是什么?来聊聊激光SLAM

这篇关于来聊聊批归一化BN(Batch Normalization)层的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/508422

相关文章

聊聊说话的习惯

1 在日常生活中,每个人都有固定的说话习惯。心理学研究表明,通过一个人的说话习惯,也可以分析出他的性格特点。对于每一个人来讲,说话习惯已经融为他们生活中的一部分。在社交活动中,一些不良的说话习惯很可能会给他们带来麻烦。因此,了解说话习惯对心理活动的影响是十分有必要的。 2 具有顺畅的说话习惯的人,大多思路清晰、语速适中、用词准确并且声声人耳,是典型的顺畅型说话方式这种类型的人要么不说话,要么

聊聊分布式,再讨论分布式解决方案

前言 最近很久没有写博客了,一方面是因为公司事情最近比较忙,另外一方面是因为在进行 CAP 的下一阶段的开发工作,不过目前已经告一段落了。 接下来还是开始我们今天的话题,说说分布式事务,或者说是我眼中的分布式事务,因为每个人可能对其的理解都不一样。 分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免,本文就分布式事

聊聊资源调度

资源调度 般分为两个阶段: 是实现物理资源的虚拟化(即资源的抽象)于当前机器的性能越来越好,硬件配置越来越高,直接用物理机跑业务比较浪费,所以将物理机分割成更小单位的虚拟机,这样可以显著提升机器的利用效率,在公司内部一般采用容器技术来隔离资源 是将资源虚拟化后进 步在时间和空间上实现更细粒度的编排 ,优化资源的使用。 1 .一些数据 如果公司的几万台机器都是物理机,那么资源的使用率稍低: CP

简单的spring batch学习

前言 公司批量任务是数据库执行的,想修改成java执行批量任务,所以简单了解了下springbatch批量任务框架,此处是其学习笔记,具体学习视频地址为bilibili springbatch,以下为其学习笔记内容以及源码信息 一、课程目标 课程目标 系统了解Spring Batch批处理 项目中能熟练使用Spring Batch批处理 课程内容 前置知识 Java基础

选取训练神经网络时的Batch size ,BatchNorm

BatchNorm 优点:对于隐藏层的每一层输入,因为经过激活函数的处理,可能会趋向于大的正值和负值,容易出现梯度下降和梯度消失。所以强行拉回到服从均值为0,方差为1的标准正态分布,避免过拟合 缺点:正是因为这种强行改变分布的手段,使得隐层输入和原始数据分布差异太大,如果数据量不大时,容易欠拟合。可能不用更好一些 https://www.zhihu.com/search?type=conte

聊聊Spark中的宽依赖和窄依赖

开门见山,本文就针对一个点,谈谈Spark中的宽依赖和窄依赖,这是Spark计算引擎划分Stage的根源所在,遇到宽依赖,则划分为多个stage,针对每个Stage,提交一个TaskSet: 上图:一张网上的图: 基于此图,分析下这里为什么前面的流程都是窄依赖,而后面的却是宽依赖: 我们仔细看看,map和filter算子中,对于父RDD来说,一个分区内的数据,有且仅有一个子RDD的分区来

【数据分享】2000—2023年我国省市县三级逐月归一化植被指数(NDVI)数据(Shp/Excel格式)

之前我们分享过2000—2023年逐月归一化植被指数(NDVI)栅格数据(可查看之前的文章获悉详情),该数据来源于NASA定期发布的MOD13A3数据集!很多小伙伴拿到数据后反馈栅格数据不太方便使用,问我们能不能把数据处理为更方便使用的Shp和Excel格式的数据! 我们特地对数值在-0.2—1之间的NDVI栅格数据进行了处理,将2000-2023年逐月的归一化植被指数栅格分别按照我国省级行政边

深度学习速通系列:归一化和批量归一化

在深度学习中,归一化和批量归一化是两种常用的技术,它们有助于提高模型的训练效率和性能。下面详细解释这两种技术: 归一化(Normalization) 归一化是指将数据的数值范围调整到一个特定的区间,通常是[0, 1]或者[-1, 1],或者使其具有零均值和单位方差。这样做的目的是减少不同特征之间的数值范围差异,使得模型训练更加稳定和高效。 常见的归一化方法包括: 最小-最大归一化(Min

聊聊灰度发布

有没有在北京面试java的小伙伴,每家公司面试问的问题都不一样,昨天面试官问到了灰度发布,一脸懵,好像在哪儿听说过,毕竟我都没发布过,之前都是项目组长在干这些事儿,所以聊聊,了解一下 什么是灰度发布 全量发布:把旧服务kill掉,把新服务启动,这个过程就可以理解为全量发布 回滚周期长 如果我们更新完应用之后,我们做线上回归测试的时候发现有BUG,这个时候就要做回滚,过程就是把新服

Layer Normalization论文解读

基本信息 作者JL Badoi发表时间2016期刊NIPS网址https://arxiv.org/abs/1607.06450v1 研究背景 1. What’s known 既往研究已证实 batch Normalization对属于同一个Batch中的数据长度要求是相同的,不适合处理序列型的数据。因此它在NLP领域的RNN上效果并不显著,但在CV领域的CNN上效果显著。 2. What’s