文章目录
- 1. 参数融合概念介绍
- 2. 参数融合详细推导
- 3. 参数融合代码实现
这篇文章是想要记录yolov5在模型搭建过程中的一个融合模块,就是把卷积与批归一化的参数进行融合,想卷积带有批归一化的性质,使得推理过程中可以加快模型推理速度,简化整个模型结构,实现训练与推理两个阶段的解耦。
1. 参数融合概念介绍
我最早接触参数重结构化这个词是看见了大佬丁霄汉发表的几篇论文:RepVGG,RepMLP,RepLKNet,这些构建新backbone的论文无一例外的全部使用了参数重结构化的思想。
RepVGG将3x3,1x1,identity分支的残差结果利用数学计算方法等价为一个3x3的卷积结构,实现训练与推断过程的解耦;RepMLP将局部的CNN先验信息加进了全连接层,使得其与MLP相结合等等。这里需要注意,重结构化层MLP结构也不是说变成Linear层,而是简化为1x1的卷积。(后续有机会把这几篇文章介绍一下,或者直接看大佬的知乎:https://www.zhihu.com/people/ding-xiao-yi-93/posts)
BN(批归一化)层常用于在卷积层之后,对feature maps进行归一化,从而加速网络学习,也具有一定的正则化效果。训练时,BN需要学习一个minibatch数据的均值、方差,然后利用这些信息进行归一化。而在推理过程,通常为了加速,都会把BN融入到其上层卷积中,这样就将两步运算变成了一步,也就达到了加速目的。
那么这里yolov5所实现的,是参数重结构化的一个小内容,就是把卷积与批归一化进行融合,变成一个新的卷积,但是包含BN层的特性。所以相比之下,算是参数重结构化系列的一个小小idea,可以稍微的加快推理速度。因为使用的是csp结构,所以没有涉及多并联分支的卷积模块(所以这一点其实也可以魔改下yolov5试试)。
2. 参数融合详细推导
在yolov5的注释中给了一个推导的参考资料:Fusing batch normalization and convolution in runtime,代码也是基于这篇文章来稍微修改的。
其实现的主要思想就是将bn层转化为一个1x1的卷积:
然后就变成了两个卷积层的迭代处理,公式为:
f ^ i , j = W B N ⋅ ( W c o n v ⋅ f i , j + b c o n v ) + b B N = ( W B N ⋅ W c o n v ) ⋅ f i , j + ( W B N ⋅ b c o n v + b B N ) = W ⋅ f i , j + b \begin{aligned} \hat{\mathrm{f}}_{\mathrm{i,j}}& =\mathrm{W_{BN}\cdot(W_{conv}\cdot f_{i,j}+b_{conv})+b_{BN}} \\ &\mathrm{=(W_{BN}\cdot W_{conv})\cdotp f_{i,j}+(W_{BN}\cdot b_{conv}+b_{BN})} \\ &=\mathrm{W\cdot f_{i,j}+b} \end{aligned} f^i,j=WBN⋅(Wconv⋅fi,j+bconv)+bBN=(WBN⋅Wconv)⋅fi,j+(WBN⋅bconv+bBN)=W⋅fi,j+b