针对yolo的轻量化第二阶段 打算对fpn下手 (暂时放一下)
Yolov5现在的Neck和Yolov4中一样,都采用FPN+PAN的结构,但在Yolov5刚出来时,只使用了FPN结构,后面才增加了PAN结构。
在YOLOv4中,Neck的PAN结构是没有引入CSP结构的,但在YOLOv5中作者在PAN结构中加入了CSP。
![](https://i-blog.csdnimg.cn/blog_migrate/9d26f0a20d55731fd92f2b33470ed02c.png)
RepVGG
VGG式”指的是:
没有任何分支结构。即通常所说的plain或feed-forward架构。
仅使用3x3卷积。
仅使用ReLU作为激活函数。
structural re-parameterization technique方法,即结构重参数化。实际上就是在训练时,使用一个类似ResNet-style的多分支模型,而推理时转化成VGG-style的单路模型。如下图所示,图(B)表示RepVGG训练时所采用的网络结构,而在推理时采用图(C)的网络结构。
![](https://i-blog.csdnimg.cn/blog_migrate/8a6147f9f0e583c0eed6935ac4ef8078.png)
训练时RepVGG Block并行了三个分支:一个卷积核大小为3x3的主分支,一个卷积核大小为1x1的shortcut分支以及一个只连了BN的shortcut分支。
为什么训练时要采用多分支结构。像Inception系列、ResNet以及DenseNet等模型,我们能够发现这些模型都并行了多个分支。至少根据现有的一些经验来看,并行多个分支一般能够增加模型的表征能力。所以你会发现一些论文喜欢各种魔改网络并行分支。在论文的表6中,作者也做了个简单的消融实验,在使用单路结构时(不使用其他任何分支)Acc大概为72.39,在加上Identity branch以及1x1 branch后Acc达到了75.14。
为什么推理时作者要将多分支模型转换成单路模型。根据论文3.1章节的内容可知,采用单路模型会更快(有的分支计算的快,有的分支计算的慢,而计算快的分支计算完后只能干等着,等其他分支都计算完后才能做进一步融合)、更省内存并且更加的灵活(模型剪枝)。
![](https://i-blog.csdnimg.cn/blog_migrate/c0106c0f5232296dcb309f5b951effc0.png)
结构重参数化主要分为两步
第一步主要是将Conv2d算子和BN算子融合以及将只有BN的分支转换成一个Conv2d算子,
3x3和bn层融合成 3x3卷积层
1x1先 转化成3x3卷积层 再和bn融合
bn 构造一个3x3的恒等映射 再和bn融合
第二步将每个分支上的3x3卷积层融合成一个卷积层。关于参数具体融合的过程可以看图中右侧的部分,
合并的过程其实也很简单,直接将这三个卷积层的参数相加即可
RepGhost
Concat特征复用虽然是无参、无FLOPs,但其计算耗时却不能忽视,如下图,随着batch_size增大,Concat与Add的运行延时差距越来越大。
是否可以考虑用Re-parameterization代替Concatenation操作。
![](https://i-blog.csdnimg.cn/blog_migrate/228504f10156930212ab22a8d2492d7b.png)
(a) 原始的 Ghost 模块(原作者激活函数好像是silu),这里省去了第一步的 1×1 卷积。
(b) 把原始的 Ghost 模块的 Concat 操作换成 Add 操作,以求更高的效率。
(c) 把 ReLU 移到 Add 操作之后,这种移动使得模块满足结构重新参数化规则,从而可用于快速推理。
(d) 在恒等映射 Identity Mapping 分支中添加 BN 操作,使得在训练过程中带来非线性,并且可以被融合用于快速推断。
(e) 模块 (d) 可以被融合成模块 (e),用于快速推断。RepGhost 模块有一个简单的推理结构,它只包含规则的卷积层和ReLU,这使得它具有较高的硬件效率。特征融合的过程是在权重空间,而不是在特征空间中进行,然后把两个分支的参数进行融合产生快速推理的结构。
与 Ghost 模块的对比
作用:
Ghost 模块提出从廉价的操作中生成更多的特征图,因此可以以低成本的方式扩大模型的容量。
RepGhost 模块提出了一种更有效的方法,通过重参数化来生成和融合不同的特征图。与 Ghost 模块不同,RepGhost 模块去掉了低效的 Concat 操作,节省了大量推理时间。并且信息融合过程由 Add 操作以隐含的方式执行,而不是留给其他卷积层。
RepGhostNet
Bottleneck改进主要体现在通道数,这是因为Concat到Add的过渡会导致通道数发生变换。作者主要是针对中间通道数进行调整,而输入与输出通道数相同。
,(a) GhostNet 网络的一个 Block。(b) RepGhost 网络训练时的一个 Block。(c) RepGhost 网络推理时的一个 Block。这里值得注意的是 RepGhost 网络的维度问题。对于一个 RepGhost 模块,输出维度等于输入维度;但是对于原来的 Ghost 模块,输出维度是输入维度的2倍。因此为了维持 RepGhost 网络和原始 GhostNet 的维度一致,有个变化需要注意下:
![](https://i-blog.csdnimg.cn/blog_migrate/deb2e724437221e7b5566269dbb5ccbf.png)
![](https://i-blog.csdnimg.cn/blog_migrate/47559fc4b73e66ee5d899db15d154cb1.png)
yolov5-5.0的csp在backbone和neck中两种结构 neck中没有残差边
6.0的c3同理 在neck中残差结构也没有残差边
初步想法 在我的模型中也使用这种重参数化 训练的时候 有残差边 而在推理的时候取消
吸取原版yolov5、GC+Slim-neck、 RepVGG(RepVggGhost)
自己的创新点: 对于使用RepVggGhost的残差模块使用结构重参数化
设计实验:
yolov5s(baseline ) exp yolov5s_hat.yaml
![](https://i-blog.csdnimg.cn/blog_migrate/e6065b8d28f4060fcfa84f820b04813d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e3118fd65422f2477f042d7207352781.png)
![](https://i-blog.csdnimg.cn/blog_migrate/038c14b2c05665c494e7935efa4df078.png)
2、 yolov5s+ GhostConv 待做
3、 yolov5s+ GhostConv +C3Ghost helmet_ghost.yaml
stride ==1
![](https://i-blog.csdnimg.cn/blog_migrate/256437bfb51e6aef836fbfcb9027b369.png)
![](https://i-blog.csdnimg.cn/blog_migrate/bef1eac23a4d8e9f40df0946eaf56c67.png)
![](https://i-blog.csdnimg.cn/blog_migrate/997b48b460e0d41a42b94a0f307fb665.png)
![](https://i-blog.csdnimg.cn/blog_migrate/8d87fdc5f81d05432a7f25ff2a6bc8bf.png)
4、 yolov5s + GSConv
5、 yolov5s + GSConv +C3GS
---------------------------以上是Slim(一) 之前的训练recall有问题---------------------------------
6、 yolov5 +repvgg (repvggblock替换conv) 也可以延伸到c3(dg68668是这样做的) 用法很多
我先替换了全部的Conv 共8处 (一开始的不算) 但是会报错 (为啥报错尚不清楚)
改为了仅替换backbone中的 共4处 可以跑 helmet_repvgg.yaml
![](https://i-blog.csdnimg.cn/blog_migrate/b5b0594d64a8599fccbcc72e2f73f4e9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d7a2b2203ffbb873f5e4264b9b9afbac.png)
![](https://i-blog.csdnimg.cn/blog_migrate/09d6fd28cb54e341552951e66160edd5.png)
6.1补充一个实验 像yolov5-lite 那样 替换全文的RepVggBlock helmet_repvgg2.yaml
----------------------------以上是repvgg 下面才是正题------------------------------------------
7、 yolov5 + RepGhost helmet_repghost2.yaml 效果很不错!
可以正确switch_to_deploy!(debug测试过了)
![](https://i-blog.csdnimg.cn/blog_migrate/591e79f39213e1c92aab938a82fc475a.png)
exp4
![](https://i-blog.csdnimg.cn/blog_migrate/30b45a1a8f1adf9d6b35c9f1ce24def9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d011b1628a5a57b8718f79109d47038d.png)
8、 yolov5 + C3RepGhost helmet_repghostC3.yaml
C3RepGhost中用到了 RepGhostBottleneck , RepGhostBottleneck用到了RepGhostModule, 而RepGhostModule配置了switch_to_deploy。 不知道能否正确转化 可以
![](https://i-blog.csdnimg.cn/blog_migrate/7f8330c445e6d1d539a20667937a2796.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d582de9aefea6842c1370e056170728d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/652a87406553126ca4f1a03ee42a2e8b.png)
9. yolov5 + RepGhost + C3RepGhost helmet
![](https://i-blog.csdnimg.cn/blog_migrate/8a98be96367d52455d7909846357acb6.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6a5bd1ebe8d4ef68a24a8a1c5f4f2504.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2111ec265b2dc9b72caac0dc9beee583.png)
10、 yolov5 + RepGHost + C3MyRepGhost (我自己设计的)
尚未写代码实现
GhostNet v2