位置: 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实现)

  • 淘宝新卖家如何推广(淘宝新卖家如何发货)

    淘宝新卖家如何推广(淘宝新卖家如何发货)

  • 怎样利用QQ空间单身在线应用日引流几百好友(如何用qq空间)

    怎样利用QQ空间单身在线应用日引流几百好友(如何用qq空间)

  • 不打扰好友的清粉(不打扰好友清理僵尸粉)

    不打扰好友的清粉(不打扰好友清理僵尸粉)

  • 抖音粉丝不够1000怎么开橱窗(抖音粉丝不够1000可以卖货吗)

    抖音粉丝不够1000怎么开橱窗(抖音粉丝不够1000可以卖货吗)

  • 苹果手机通讯记录只保存一周(苹果手机通讯记录怎么查询以前的)

    苹果手机通讯记录只保存一周(苹果手机通讯记录怎么查询以前的)

  • 步步高家教机h8s开不了机(步步高家教机h8s破解成平板)

    步步高家教机h8s开不了机(步步高家教机h8s破解成平板)

  • cdr导不出来图怎么办(cdr导不出图片)

    cdr导不出来图怎么办(cdr导不出图片)

  • 打开天正只显示cad(图纸用天正打开显示不全)

    打开天正只显示cad(图纸用天正打开显示不全)

  • 华为充电指示灯怎么设置(华为充电指示灯设置在哪里设置)

    华为充电指示灯怎么设置(华为充电指示灯设置在哪里设置)

  • 苹果6s plus长度是多少厘米(iphone6s plus长度)

    苹果6s plus长度是多少厘米(iphone6s plus长度)

  • 手环连接不上手机怎么办(手环连接不到手机)

    手环连接不上手机怎么办(手环连接不到手机)

  • 带上耳机打电话,对方能听见外面的声音吗(带上耳机打电话别人听见声音了吗)

    带上耳机打电话,对方能听见外面的声音吗(带上耳机打电话别人听见声音了吗)

  • 淘宝种草达人怎么申请(淘宝种草达人怎么赚钱)

    淘宝种草达人怎么申请(淘宝种草达人怎么赚钱)

  • 微信聊天窗口在哪里(微信聊天窗口在哪里打开)

    微信聊天窗口在哪里(微信聊天窗口在哪里打开)

  • xr声音小怎么解决(xr声音小怎么办)

    xr声音小怎么解决(xr声音小怎么办)

  • 华为p40pro支持谷歌吗(华为p40支持谷歌服务吗)

    华为p40pro支持谷歌吗(华为p40支持谷歌服务吗)

  • 淘宝退款的话淘金币会不会退还(淘宝退款后会退到哪里)

    淘宝退款的话淘金币会不会退还(淘宝退款后会退到哪里)

  • ics文件怎么打开(ics文件怎么打开手机)

    ics文件怎么打开(ics文件怎么打开手机)

  • ipad笔有什么用(ipad笔有什么功能)

    ipad笔有什么用(ipad笔有什么功能)

  • 玩抖音合拍合唱是怎么玩的(抖音合唱合拍视频)

    玩抖音合拍合唱是怎么玩的(抖音合唱合拍视频)

  • 手机淘宝抢红包在哪里(手机淘宝抢红包是真的吗)

    手机淘宝抢红包在哪里(手机淘宝抢红包是真的吗)

  • 18pt发光是什么意思呢(蓝色18pt发光)

    18pt发光是什么意思呢(蓝色18pt发光)

  • 电脑买回来要做些什么(电脑买回来要做系统吗)

    电脑买回来要做些什么(电脑买回来要做系统吗)

  • ios9.0是苹果几(ios9.0以上是什么手机)

    ios9.0是苹果几(ios9.0以上是什么手机)

  • 苹果夜间模式怎么关闭(苹果夜间模式怎么添加到控制中心)

    苹果夜间模式怎么关闭(苹果夜间模式怎么添加到控制中心)

  • qq听筒模式怎么切换

    qq听筒模式怎么切换

  • 圣克鲁斯岛的查尔斯达尔文研究站内从卵中孵化出来的平松岛龟,厄瓜多尔加拉帕戈斯群岛 (© Pete Oxford/Minden Pictures)(圣克鲁斯岛战役)

    圣克鲁斯岛的查尔斯达尔文研究站内从卵中孵化出来的平松岛龟,厄瓜多尔加拉帕戈斯群岛 (© Pete Oxford/Minden Pictures)(圣克鲁斯岛战役)

  • 程序人生 | 与足球共舞的火柴人(致敬格拉利什,赋予足球更深的意义)(程序人是什么意思)

    程序人生 | 与足球共舞的火柴人(致敬格拉利什,赋予足球更深的意义)(程序人是什么意思)

  • 小规模纳税人企业所得税2023
  • 公账转法人私账的注意事项
  • 饭店发光板图片大全
  • 企业所得税免税项目
  • 开了农民工资金专户必须使用吗
  • 母子公司间借款利息交税吗
  • 员工工资占公司收入比例怎么算
  • 自己申报个人所得税需要补缴,必须自己申报自己补缴吗
  • 固定资产成本包括包装费吗
  • 商品折扣促销方式的会计处理如何做?
  • 以旧换新会计处理金银首饰
  • 银行贷款利息支出汇算清缴需要调整吗
  • 变更银行手机号需要去银行吗
  • 个人营业税是什么意思
  • 工资薪金支出税收金额怎么算
  • 三证合一的税号变了,法人怎么重新绑定企业
  • 保税区内企业出口
  • 多计提的社保费,可否计入营业外收入
  • 收到场地租赁费用计入什么科目
  • 上年的一张服务费的发票能否做账到今年?
  • 红字发票是销货单据吗
  • 滴滴开的发票能否抵扣进项税
  • 发票失联企业不处理的后果
  • 应收账款贷方余额重分类到哪
  • windows11怎么回到桌面
  • 汇算清缴退税怎么调整金额
  • 如何编制处置固定资产
  • 收到其他公司的投资款计入什么科目
  • 企业间贴现手续费怎么记账?
  • 进货折扣是怎么计算
  • 总分类账和明细账
  • 发票是自己买的吗
  • vue3项目打包
  • mmtraylsi.exe是什么进程 有什么作用 mmtraylsi进程查询
  • 应收账款转让的限制约定
  • 限售股交易征税是多少
  • 猿人知乎
  • img标签铺满div
  • php 替换字符
  • html代码form
  • 行政事业性收费是什么意思
  • 劳动仲裁支付的赔偿金怎么入账
  • 社保费用可以提前从工资扣吗
  • 材料采购成本计算表
  • 财政拨款结余明细科目编码
  • 长期待摊费用是非流动资产吗
  • 增值税发票价税合计不能超过多少
  • 揭秘如何投屏纽约时代广场
  • 可以直接申请一个微信吗
  • 宣告分配现金股利和股票股利的区别
  • 出口货物做免税处理
  • 国有控股企业和国有参股企业的区别
  • 旅行社开具的发票抵扣
  • 进项转出转到哪里去
  • 业务招待费税前扣除标准2020
  • 建筑企业收挂靠公司的管理费如何做账?
  • 公司与公司之间人与人之间最大的区别
  • 收到预付卡结算款怎么入账
  • 普票丢失可以以照片入账么
  • 去年的账科目记错了怎么办
  • 教育费返还款计入收入吗
  • 资本金与注册资本的关系
  • ubuntul
  • SQLServer Execpt和not in 性能区别
  • dwm.exe占用内存过高怎么办
  • Win7自带的扫雷怎么都打不开
  • opengl绘制图形旋转
  • ie浏览器登录多个账号
  • 瀑布流软件
  • jquery常用选择器种类
  • jQuery Ajax 异步加载显示等待效果代码分享
  • python登陆代码
  • js实现物体移动
  • jqueryfilter
  • 登陆界面android
  • 个体工商户税务年报网上怎么申报
  • 退休个人所得税专项附加扣除减免
  • 小规模纳税人利润如何缴税
  • 山东地域分布
  • 郑州地方税务局网站官网
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设