位置: IT常识 - 正文

Repvgg详解及其实现(pytorch)(rep p)

编辑:rootadmin
Repvgg详解及其实现(pytorch)

推荐整理分享Repvgg详解及其实现(pytorch)(rep p),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:rep p,rep p,rep l,rep+,rep l,rep vgg,repli-g,rep+,内容如对您有帮助,希望把文章链接给更多的朋友!

论文下载地址:https://arxiv.org/abs/2101.03697

官方源码(Pytorch实现):GitHub - DingXiaoH/RepVGG: RepVGG: Making VGG-style ConvNets Great Again

写这边博客也是为了做一个记录,如果有错误或者不足,请各位大佬提出。

repvgg参考了博主:太阳花小绿豆的博客地址如下:

(19条消息) RepVGG网络简介_太阳花的小绿豆的博客-CSDN博客

在开始前简单说一下我的理解repvgg到底再做什么,我用简单的话来说就是设计了一个可融合的网络,在模型的推理的时候将含有多分支的模型转化为单分支的结构,加快推理的速度。

 再论文中作者给出了一个对比,repvgg的网络再imagenet上表现不错,而且在相同准确率下推理速度已经接近Efficientnet的三倍,这就得益于它的多分支融合的技术,听上去高大上其实还是很简单的。

废话不多说直接上图:

原论文中的结构图很直观的展示了repvgg到底是什么意思,对比Resnet它仍然有着类似残差的结构,就是在3*3的卷积基础上弄了一个1*1的分支和一个identity分支(在步长不等于2且输入输出通道相等的情况下),这样除了方便推理过程的融合,似乎还有多分支的好处,因为有丰富的梯度信息(狗头保命),但是这好像会在训练时增加参数量,但是推理速度快就ok了。

具体融合的过程结合论文中给出来的图去讲解:

假设你的输出和输入通道都是2,那么对于3*3的卷积就有两个通道为2的3*3的卷积核,1*1也一样,就像图中四个绿色的方框和四个橙色的方框,对于BN层来说,里面有,这几个参数具体来说就是均值,方差,权重,偏置,他们也和通道的输入维度保持一致,融合的步骤就是卷积操作和BN层分别进行融合,主要需要改变的还是1*1的卷积如何变成3*3的卷积,identity分支怎么转换成3*3的模样。到这里可能会有质疑这种融合后能和以前一样吗,那么我们从公式入手:

Repvgg详解及其实现(pytorch)(rep p)

图中我们以2*2卷积为例,为了保持输入与输出同尺寸,黑色的一圈为padding,我们只计算出第一个特征点的值对于第一个特征点,我们将值带入BN的计算公式:

这里是一个极小的数防止分母为0将BN公式转变一下就变成:

那么我们如果不要融合conv和bn是不是就可以把参数项直接乘到卷积核的权重里去,我们普通卷积是没有偏执的,然后剩下的作为偏执加载到融合后的conv中:

                       

这样我们就将conv与bn融合,接下来让我们看看代码中是怎么完成的:

def _fuse_bn_tensor(self, branch): if branch is None: return 0, 0 if isinstance(branch, nn.Sequential): kernel = branch[0].weight running_mean = branch[1].running_mean running_var = branch[1].running_var gamma = branch[1].weight beta = branch[1].bias eps = branch[1].eps else: assert isinstance(branch, nn.BatchNorm2d) if not hasattr(self, "id_tensor"): input_dim = self.in_channels // self.groups kernel_value = np.zeros( (self.in_channels, input_dim, 3, 3), dtype=np.float32 ) for i in range(self.in_channels): kernel_value[i, i % input_dim, 1, 1] = 1 self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device) kernel = self.id_tensor running_mean = branch.running_mean running_var = branch.running_var gamma = branch.weight beta = branch.bias eps = branch.eps std = (running_var + eps).sqrt() t = (gamma / std).reshape(-1, 1, 1, 1) return kernel * t, beta - running_mean * gamma / std

 这里函数接收的是一个nn.Sequential(),里面是一个卷积操作以及一个bn层,我们依次取出卷积的weight,以及bn层的各个参数,然后在下面放回计算后的weight,bias,这里代码中else是当传入的是identity分支时,也就是只有BN层的时候,我们要构造出一个3*3的卷积,这里不像1*1的卷积我们只需要padding一圈0就可以了,identity分支需要特殊的构造方式,要求卷积操作后,输入不变,文中作者是这样做的:

设计卷积核只有中间为1,其余一圈0,这样卷积完成后和输入特征值没有发生变化,在代码中是这样实时的:

else: assert isinstance(branch, nn.BatchNorm2d) if not hasattr(self, "id_tensor"): input_dim = self.in_channels // self.groups kernel_value = np.zeros( (self.in_channels, input_dim, 3, 3), dtype=np.float32 ) for i in range(self.in_channels): kernel_value[i, i % input_dim, 1, 1] = 1 self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device)

 先构造一个全为0的卷积核然后在相应位置复值1.

我们依次将三个分支卷积层和BN层的参数全部取出来然后相加:

def get_equivalent_kernel_bias(self): kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense) kernel1x1, bias1x1 = self._fuse_bn_tensor(self.rbr_1x1) kernelid, biasid = self._fuse_bn_tensor(self.rbr_identity) return ( kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasid, )

这样我们就获得了融合后的3*3卷积的bias和weight,最后先创建一个3*3卷积但是bias要设置为Ture,然后我们将准备好的weight和bias加载到这个3*3卷积层中:

def fuse_conv_bn(self, conv, bn): kernel, bias = self.get_equivalent_kernel_bias() conv = nn.Conv2d(in_channels = conv.in_channels, out_channels = conv.out_channels, kernel_size = conv.kernel_size, stride=conv.stride, padding = conv.padding, dilation = conv.dilation, groups = conv.groups, bias = True, padding_mode = conv.padding_mode) conv.weight = torch.nn.Parameter(kernel) conv.bias = torch.nn.Parameter(bias) return conv

这样我们就将三个分支融合成了一个分支,这样的在推理的时候就会非常快,而且很省内存

更快的话主要就是像这种最后要有一个add操作,1*1和这个identity分支肯定是率先完成的,但是就算它完成了也要等3*3卷积操作结束后才能释放当前算力,如果融合后就只需要通过一个3*3卷积就可以了,还有一种解释是每当此启动kernel都是需要消耗时间的,相比之下一条路直接下来显然更快。

 原文中的意思是像这残差分支,会一直占用1x的内存,直到add操作后才会释放,所以repvgg提出的参数重构化就很好的解决了推理时的内存占用和推理速度等方面。目前repvgg的结构已经被应用与很多任务中,就拿今年的目标检测任务中,从PP-YOLOE,到yolov6和yolov7都应用这种结构,让部署更容易,检测效果间接提升,相信在以后的任务中repvgg依然可以发光。

本文链接地址:https://www.jiuchutong.com/zhishi/297370.html 转载请保留说明!

上一篇:SwinIR实战:详细记录SwinIR的训练过程

下一篇:Vue3中使用hooks,hooks究竟是个啥?如何理解(vue3 hooks实现)

  • 激光打标机厂家直销(激光打标机多少钱)(31度激光打标机厂家)

    激光打标机厂家直销(激光打标机多少钱)(31度激光打标机厂家)

  • 海星模拟器怎么连接手柄(海星模拟器怎么用)

    海星模拟器怎么连接手柄(海星模拟器怎么用)

  • 苹果11ios13黑夜模式怎么开(苹果十一黑夜模式)

    苹果11ios13黑夜模式怎么开(苹果十一黑夜模式)

  • 手机视频看不到对方是怎么回事(手机视频看不到自己的头像怎么办)

    手机视频看不到对方是怎么回事(手机视频看不到自己的头像怎么办)

  • 荣耀20新机充电几小时(荣耀新机充电怎么充)

    荣耀20新机充电几小时(荣耀新机充电怎么充)

  • 微机中控制器的基本功能(微机控制器的工作原理)

    微机中控制器的基本功能(微机控制器的工作原理)

  • 语音与数据打开volte有什么用(为什么我的语音与数据不能用)

    语音与数据打开volte有什么用(为什么我的语音与数据不能用)

  • 淘宝评价删除后还能再评价吗(淘宝评价删除后商家能查到吗)

    淘宝评价删除后还能再评价吗(淘宝评价删除后商家能查到吗)

  • 华为p20刷新率(华为p20刷新率选项不见了)

    华为p20刷新率(华为p20刷新率选项不见了)

  • 苹果x和xs显示屏一样吗(苹果x和xs显示屏一样大吗)

    苹果x和xs显示屏一样吗(苹果x和xs显示屏一样大吗)

  • 华为荣耀20和20s的区别(华为荣耀20和20s屏幕一样吗)

    华为荣耀20和20s的区别(华为荣耀20和20s屏幕一样吗)

  • 手机qq如何隐藏性别(手机QQ如何隐藏情侣黄钻)

    手机qq如何隐藏性别(手机QQ如何隐藏情侣黄钻)

  • 手机无法获取root权限怎么办(手机无法获取摄像头数据怎么办)

    手机无法获取root权限怎么办(手机无法获取摄像头数据怎么办)

  • 戴尔显示器如何调节(戴尔显示器如何调节高度)

    戴尔显示器如何调节(戴尔显示器如何调节高度)

  • iphone11怎么给软件上锁(iphone11怎么给软件夹上锁)

    iphone11怎么给软件上锁(iphone11怎么给软件夹上锁)

  • k8s和docker区别(k8s和docker比较的优势)

    k8s和docker区别(k8s和docker比较的优势)

  • 淘宝背景怎么设置(淘宝背景怎么设置原来的白色)

    淘宝背景怎么设置(淘宝背景怎么设置原来的白色)

  • 酷狗繁星号是什么意思(酷狗里的繁星号是什么)

    酷狗繁星号是什么意思(酷狗里的繁星号是什么)

  • 11promax双卡双待吗(ipone11promax 双卡双待)

    11promax双卡双待吗(ipone11promax 双卡双待)

  • 美团的外卖豆入口在哪里(美团的豆有什么用)

    美团的外卖豆入口在哪里(美团的豆有什么用)

  • qq相册回收站独立密码是什么(qq相册回收站独立密码多少)

    qq相册回收站独立密码是什么(qq相册回收站独立密码多少)

  • 抖音哈气怎么写字(抖音嗨的句子)

    抖音哈气怎么写字(抖音嗨的句子)

  • qq音乐怎么取消关注用户(qq音乐怎么取消其他设备登录)

    qq音乐怎么取消关注用户(qq音乐怎么取消其他设备登录)

  • iPhone耳机怎么播放音乐(苹果无线耳机怎么播放)

    iPhone耳机怎么播放音乐(苹果无线耳机怎么播放)

  • 一加是什么旗下品牌(一加是什么旗下的产品)

    一加是什么旗下品牌(一加是什么旗下的产品)

  • 华为nova5pro和nova5区别(华为nova5pro和nova5ipro有什么区别)

    华为nova5pro和nova5区别(华为nova5pro和nova5ipro有什么区别)

  • 如何安装win10和ubuntu14双系统 图文详解win10和ubuntu14双系统安装过程(window10安装教程u盘)

    如何安装win10和ubuntu14双系统 图文详解win10和ubuntu14双系统安装过程(window10安装教程u盘)

  • 如何配置无线路由器 无线路由器如何设置为无线AP(如何配置无线路由器参数)

    如何配置无线路由器 无线路由器如何设置为无线AP(如何配置无线路由器参数)

  • Markdown 使用语法(详细)(markdown语法是什么意思)

    Markdown 使用语法(详细)(markdown语法是什么意思)

  • 房产证,契税
  • 采购单是原始凭证吗
  • 发票替代票
  • 作废冲红的发票怎么做账处理
  • 发票能加盖公章吗
  • 准予在以后年度结转扣除的项目
  • 公司授权给公司有风险吗?
  • 异地学习期间产生的餐费住宿费怎么做账?
  • 母子公司往来款属于借款吗
  • 受托加工物资产包括哪些
  • 化工类资质建筑企业有哪些
  • 农场管委会是什么性质单位
  • 发票的受票方是什么
  • 税报完了可以撤销吗
  • 个体工商户如何给员工交社保
  • 个体工商户是否需要报税
  • 销售货物收入与租金收入的纳税区别
  • 通用日记账核算方法
  • 土地增值税清算后补缴税款如何帐务处理
  • 财产租赁所得的税率是多少
  • 什么叫固定资产的确认
  • 补交的所得税会计核算
  • 冲减管理费用的会计分录
  • 稿酬所得怎么纳税
  • 闲置设备怎么处理
  • 原材料进项税税率
  • mac系列电脑
  • php最新动态
  • 罚款应该计入营业所吗
  • 事业单位接受捐赠固定资产入账
  • 马瑙斯市
  • 本部借给分公司的钱用交印花税吗
  • “Property or method “***“ is not defined on the instance but referenced during render.”报错的原因及解决方案
  • php7数据库操作
  • 会计核算方法体系构成
  • 怎么给复选框赋值
  • 收到银行开的手续费发票怎么做分录
  • gparted 命令行
  • 结转销售成本的凭证需要附件吗
  • opengl 帧率
  • 汽车上牌照的费用计入什么会计科目
  • 暂估入库成本结转处理低于实际成本怎么办
  • vue如何实现路由跳转缓存
  • mysql分库分表实践
  • 安装和使用蓄能器应注意哪些问题
  • 公帐的钱可以转到其他人帐户吗
  • 交易性金融资产入账价值怎么计算
  • 入库单入账税务会查吗
  • 政府会计制度下基建账
  • 旅行社开具的发票
  • 计提附加税费是什么意思
  • 劳务费入什么费用
  • 主营业务成本工资写什么部门
  • 承兑汇票兑现怎么填写
  • 模具报价成本核算方法
  • 买房定金转给销售有效吗
  • 公司员工报销油费
  • 特定担保债权
  • 软件折旧从什么时候算
  • 销售费用进项税抵扣
  • 失控发票进项税转出企业无法承担所得税怎么办
  • 会计总账怎么登账
  • 汇总帐凭证处理
  • 外帐和内帐区别
  • 重新组织是什么意思
  • windows10的xbox如何录制视频
  • Windows Server 2008之数据安全保护
  • ubuntu复制文件到当前文件夹
  • 哪款系统重装软件比较好
  • exeploer.exe
  • xp系统快捷启动按哪个
  • linux常用命令kill
  • win7系统点击图标没反应
  • Following the pipeline
  • 3d引擎开发
  • JS 中document.write()的用法和清空的原因浅析
  • 测试下载速度很快,实际下载很慢
  • jstree异步加载
  • 中国税务手机版
  • 出口退税函调管理办法
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设