BN、CBN、CmBN 的对比与总结

news2024/11/15 11:08:24

BN、CBN、CmBN 的对比与总结

最近看到了关于 Yolo 系列 trick 的总结文章 【Make YOLO Great Again】YOLOv1-v7全系列大解析(Tricks篇),其中提到了 YoloV4 中使用了 CmBN,这是对 CBN 的改进,可以较好的适应小 batch 的情形。论文中给出了一个简要的对比图:

在这里插入图片描述

这里结合此图对 BN 和其两种改进策略进行说明。所以需要注意的是,这里存在两个 batch 相关的概念:

  • batch:指代与 BN 层的统计量 实际想要相对应的数据池,也就是图片样本数。
  • mini-batch:由于整个 batch 独立计算时,受到资源限制可能不现实,于是需要将 batch 拆分成数个 mini-batch,每个 mini-batch 单独计算后汇总得到整个 batch 的统计量。从而归一化特征。

我们日常在分割或者检测中使用 BN 时,此时如果不使用特殊的设定,那么 batch 与 mini-batch 是一样的。CBN 和 CmBN 所做的就是如何使用多个独立的 mini-batch 的数据获得一个近似于更大 batch 的统计量以提升学习效果。

CBN 与 CmBN

CmBN(Cross mini-Batch Normalization)是 CBN(Cross-Iteration Batch Normalization)的修改版。

CBN 主要用来解决在 Batch-Size 较小时,BN 的效果不佳问题。CBN 连续利用多个迭代的数据来变相扩大 batch size 从而改进模型的效果。这种用前几个 iteration 计算好的统计量来计算当前迭代的 BN 统计量的方法会有一个问题:过去的 BN 参数是由过去的网络参数计算出来的特征而得到的,而本轮迭代中计算 BN 时,它们的模型参数其实已经过时了

假定 batch=4*mini batch,CBN 在 t t t 次迭代:

  • 模型基于之前的梯度被更新。此时的 BN 的仿射参数也是最新的。
  • 除了本次迭代的统计量,也会使用通过补偿后的前 3 次迭代得到的统计量。这 4 次的统计量会被一起用来得到近似于整个窗口的近似 batch 的 BN 的统计量。
  • 使用得到的近似统计量归一化特征。
  • 使用当前版本的仿射参数放缩和偏移。

CmBN 是基于 CBN 改进的,按照论文的图示的意思,主要的差异在于从滑动窗口变为固定窗口。每个 batch 中的统计不会使用 batch 之前的迭代的信息,仅会累积该窗口内的 4 次迭代以用于最后一次迭代的更新。这一策略基本与梯度累积策略仍有不同,梯度累加仅仅累加了梯度,但是前面的图中明显可以看到 BN 的统计量实际上也累积了起来,而图 4 中的展现的 BN 似乎更像是梯度累积。

CBN 的实现

# https://github.com/Howal/Cross-iterationBatchNorm/blob/f6d35301789c96e52699a9cbc8d2de8681547770/mmdet/models/utils/CBN.py#L74
def forward(self, input, weight):
    # deal with wight and grad of self.pre_dxdw!
    self._check_input_dim(input)
    y = input.transpose(0, 1)
    return_shape = y.shape
    y = y.contiguous().view(input.size(1), -1)

    # burnin
    if self.training and self.burnin > 0:
        self.iter_count += 1
        self._update_buffer_num()

    if self.buffer_num > 0 and self.training and input.requires_grad:  # some layers are frozen!
        # cal current batch mu and sigma
        cur_mu = y.mean(dim=1)
        cur_meanx2 = torch.pow(y, 2).mean(dim=1)
        cur_sigma2 = y.var(dim=1)
        # cal dmu/dw dsigma2/dw
        dmudw = torch.autograd.grad(cur_mu, weight, self.ones, retain_graph=True)[0]
        dmeanx2dw = torch.autograd.grad(cur_meanx2, weight, self.ones, retain_graph=True)[0]
        # update cur_mu and cur_sigma2 with pres
        mu_all = torch.stack([cur_mu, ] + [tmp_mu + (self.rho * tmp_d * (weight.data - tmp_w)).sum(1).sum(1).sum(1) for tmp_mu, tmp_d, tmp_w in zip(self.pre_mu, self.pre_dmudw, self.pre_weight)])
        meanx2_all = torch.stack([cur_meanx2, ] + [tmp_meanx2 + (self.rho * tmp_d * (weight.data - tmp_w)).sum(1).sum(1).sum(1) for tmp_meanx2, tmp_d, tmp_w in zip(self.pre_meanx2, self.pre_dmeanx2dw, self.pre_weight)])
        sigma2_all = meanx2_all - torch.pow(mu_all, 2)

        # with considering count
        re_mu_all = mu_all.clone()
        re_meanx2_all = meanx2_all.clone()
        re_mu_all[sigma2_all < 0] = 0
        re_meanx2_all[sigma2_all < 0] = 0
        count = (sigma2_all >= 0).sum(dim=0).float()
        mu = re_mu_all.sum(dim=0) / count
        sigma2 = re_meanx2_all.sum(dim=0) / count - torch.pow(mu, 2)

        self.pre_mu = [cur_mu.detach(), ] + self.pre_mu[:(self.buffer_num - 1)]
        self.pre_meanx2 = [cur_meanx2.detach(), ] + self.pre_meanx2[:(self.buffer_num - 1)]
        self.pre_dmudw = [dmudw.detach(), ] + self.pre_dmudw[:(self.buffer_num - 1)]
        self.pre_dmeanx2dw = [dmeanx2dw.detach(), ] + self.pre_dmeanx2dw[:(self.buffer_num - 1)]

        tmp_weight = torch.zeros_like(weight.data)
        tmp_weight.copy_(weight.data)
        self.pre_weight = [tmp_weight.detach(), ] + self.pre_weight[:(self.buffer_num - 1)]

    else:
        x = y
        mu = x.mean(dim=1)
        cur_mu = mu
        sigma2 = x.var(dim=1)
        cur_sigma2 = sigma2

    if not self.training or self.FROZEN:
        y = y - self.running_mean.view(-1, 1)
        # TODO: outside **0.5?
        if self.out_p:
            y = y / (self.running_var.view(-1, 1) + self.eps)**.5
        else:
            y = y / (self.running_var.view(-1, 1)**.5 + self.eps)
        
    else:
        if self.track_running_stats is True:
            with torch.no_grad():
                self.running_mean = (1 - self.momentum) * self.running_mean + self.momentum * cur_mu
                self.running_var = (1 - self.momentum) * self.running_var + self.momentum * cur_sigma2
        y = y - mu.view(-1, 1)
        # TODO: outside **0.5?
        if self.out_p:
            y = y / (sigma2.view(-1, 1) + self.eps)**.5
        else:
            y = y / (sigma2.view(-1, 1)**.5 + self.eps)

    y = self.weight.view(-1, 1) * y + self.bias.view(-1, 1)
    return y.view(return_shape).transpose(0, 1)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电容笔值不值得买?电容笔十大品牌排行

要想给我们的ipad配置一款电容笔&#xff0c;如果感觉苹果原装的电容笔价格远远超过预算。这时候平替电容笔是个非常值得入手的选择。试想一下购买一款苹果原装的电容笔的资金都够买整整四款平替电容笔了&#xff0c;平替电容笔价格便宜且功能跟苹果的电容笔相差无几。下面我来…

【设计模式】 - 结构型模式 - 迭代器模式

目录标题前言迭代器模式概述结构实现优缺点JDK源码解析前言 行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象…

ai绘画有哪些软件,盘点三款免费且超级好用的AI绘画工具

Ai绘画有哪些软件&#xff1f;不但可以免费使用&#xff0c;而且生成的画作精美&#xff0c;而且生成的图片速度还要很快&#xff1f; 不用急&#xff0c;今天小编给大家推荐的这三款ai绘画工具完全满足了上述条件&#xff01; 第一款&#xff0c;重磅级产品&#xff0c;数画…

内存 地址转换、分段、空闲空间管理

目录 1. 地址转换 1.1 动态重定位 1.1.1 基址寄存器&#xff08;虚拟地址 -> 物理地址) 1.1.2 界限寄存器&#xff08;提供访问保护&#xff09; 1.2 操作系统的工作 2. 分段 2.1 分段&#xff1a;泛化的基址/界限 2.2 引用哪个段 2.3 代码和堆的地址转换举例 2.4…

Java#23(常见API--1)

目录 一.Math Math是一个帮助我们用于进行数学计算的工具类 工具类的特点: Math类中的常用方法 二.System System是一个工具类,为我们提供一些与系统相关的办法 一.Math Math是一个帮助我们用于进行数学计算的工具类 工具类的特点: 私有化构造方法,所有的方法都是静态的 M…

[附源码]java毕业设计医院预约挂号管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

web网页设计期末课程大作业 我的美丽家乡盐城 HTML+CSS+JavaScript

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

Linux C应用编程-2-Makefile编写

1.基本规则 #规则格式 target ... : prerequisites ... command1command2#例如 main: main.o stack.o maze.ogcc main.o stack.o maze.o -o main main是规则的目标&#xff08;Target&#xff09;&#xff0c;main.o、stack.o和maze.o是规则的条件&#xff08;Prerequisite&am…

贴地气的安卓UI自动化工具4399AT全面更新了~

4399AT是 一款兼容多设备运行并实现全自动化的测试的安卓UI工具&#xff0c;全自动化测试是指从apk的安装到按钮点击&#xff0c;密码输入到安装完成&#xff0c;不需要人工介入&#xff0c;兼容android5.0-12.0系统大部分品牌&#xff0c;至于开始测试&#xff0c;启动apk后&a…

(十)笔记.net学习Lambda和Linq表达式

1.lambda表达式的演变 Lambda表达式的本质是“匿名方法”&#xff1a; C#的Lambda 表达式都使用 Lambda 运算符 >&#xff0c;该运算符读为“goes to”。语法如下&#xff1a; (object argOne, object argTwo) > {; /*Your statement goes here*/} 函数体多于一条语句…

一次Actuator未授权访问利用

目录 介绍 复现 Actuator目录下可能利用泄漏信息的路径 利用 思考 处理意见 介绍 事先得到同意对朋友公司的网站进行了扫描&#xff0c;扫出了一个Actuator未授权&#xff0c;于是开始复现并记录一下&#xff0c;最后获取了redis的密码 复现 这里是请求包 响应包成功返回…

qt 虚拟键盘中的几个瑕疵

最近使用了下面楼主的虚拟键盘&#xff0c;总体还是挺好用的&#xff0c;只是有几个地方&#xff0c;需要完善下。 基于Qt的可用于嵌入式的虚拟键盘_偷段代码的博客-CSDN博客_qt 嵌入式虚拟键盘这几天完成了一个基于Qt的虚拟键盘的编写&#xff0c;记录一下过程与感受&#xf…

Python操作Numpy模块库

14天学习训练营导师课程&#xff1a; 杨鑫《Python 自学编程基础》 杨鑫《 Python 网络爬虫基础》 杨鑫《 Scrapy 爬虫框架实战和项目管理》 Python操作Numpy模块库 文章目录Python操作Numpy模块库1.Numpy介绍2.Numpy安装3.Numpy模块练习3.1 创建数组3.2 获取数组3.3 切割数组…

二叉树路径问题+递归+有关题目

一、分类 1、自顶向下 顾名思义&#xff0c;就是从某一个节点(不一定是根节点)&#xff0c;从上向下寻找路径&#xff0c;到某一个节点(不一定是叶节点)结束&#xff0c;具体题目如下&#xff1a;而继续细分的话还可以分成一般路径与给定和的路径 二叉树的所有路径面试题 04…

Qt 利用UDP进行通信

一、UDP的特点 UDP&#xff08;用户数据报协议&#xff09;是一种简单轻量级、不可靠、面向数据报&#xff0c;无连接的传输层协议。而TCP/IP协议却是有连接的 二、UDP适合应用的几种情况 1、网络数据大多为短消息 2、拥有大量客户端 3、对数据安全性无特殊要求 4、网络负…

pmap gdb 分析堆外内存泄露情况

一、查看内存分部 pmap -x 8 | sort -k3 -n -r | more ---- 8 是 PID 最大的肯定是堆内存。 其他的就需要看情况来分析了。 二、cat /proc/8/smaps | grep 7fad64000000 -- 8 是 PID , 地址的前4个0需要去掉。查到起止内存地址。 7fad64000000-7fad68000000 r…

Bioinformatics2019 | FP2VEC+:基于新分子特征的分子性质预测

论文标题&#xff1a;FP2VEC&#xff1a;a new molecular featurizer for learning molecular properties 代码&#xff1a; GitHub - wsjeon92/FP2VEC 预测化合物性质最成功的方法之一是定量结构-活性关系(QSAR)方法。 Mol2vec使用分子子结构表将分子结构表示为类似于分子指…

甘露糖-聚乙二醇-CY5 Cy5-PEG-mannose

甘露糖-聚乙二醇-CY5 Cy5-PEG-mannose 中文名称&#xff1a;甘露糖-菁染料CY5 英文名称&#xff1a;mannose-Cyanine5 别称&#xff1a;CY5标记甘露糖&#xff0c;CY5-甘露糖 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 外观:固体或粘性液体&#xff0c;取…

设计模式之美——实战MVC的意义

对于一个工程师来说&#xff0c;如果要追求长远发展&#xff0c;你就不能一直只把自己放在执行者的角色&#xff0c;不能只是一个代码实现者&#xff0c;你还要有独立负责一个系统的能力&#xff0c;能端到端&#xff08;end to end&#xff09;开发一个完整的系统。这其中的工…

《机械工程基础》复习题

一、填空题&#xff1a; 1. 构件由于受力不同&#xff0c;会产生不同的变形。基本形式有以下五种&#xff1a;1. 弯曲 &#xff1b;2. 扭转 &#xff1b; 3. 剪切 &#xff1b;4. 轴向拉伸 &#xff1b;5. 轴向压缩 。 2. 在机器中&#xff0c;运动的基本单元称之为__机构_ ___…