关于Yolov7-tiny模型瘦身(param、FLOPs)碎碎念

优于模型落地需要,yolov7-tiny版本的参数量(Param)为6.2M,FLOPs在输入为320*320下为3.46G,想着还能不能再进行减少这两者或其中之一(精度方面还未做效果验证)。

于是翻遍了github,没有关于v7的剪枝方法,替换backbone也大部分是基于yolov5s的,眼花缭乱中看到yolov7的github官方作者的一句回复:

接着去看了一下什么是ELAN,相关细节知识不做复制粘贴了,可以去看各大神的代价解读。在yolov7-tiny.yaml中,就是这个在被stride为2的卷积下采样后,被Concat整合前的这四个连续卷积层。

这种结构在标准版和tiny版的backbone和head中都有,只是tiny中少了两个卷积层的堆叠,激活函数变成了LeakyReLU,每个branch的操作中,输入通道都是和输出通道保持一致,接下来就是小白改结构碰的壁了。

每层网络都有四个参数,[from, number, module, args],以Conv层为例,第一个from表示本层的输入来自哪一层的输出,-1表示上一层,-2表示上上层,以此类推,若是正数n则表示从头数的第n层;number表示本层堆叠几次;module表示该层的种类,在models.common中都能找到class;args则是相关参数,如Conv中是通道数、卷积核尺寸、步长、激活函数等。

当时由于不懂from的含义,就硬删ELAN中的某层卷积(from为-2的卷积不要删),然后train.py,结果可想而知。

根据log找到是构建网络时报的错,然后继续研究。。。因为网络各层是堆叠的,删除某层对后面的层数当然会有影响,所以from不为-1的值肯定要改,经过一系列小学数学的操作后,层和from对应上了,还是报错。。。 接着研究,在yolov7.yaml和v7-tiny.yaml中发现Concat层的from是[-1,-2,-3,-4,-5,-6]和[-1,-2,-3,-4]的区别,所以当from是数组时,表示上一层,上2层,上3层..以此类推。所以ELAN中删一层,[-1,-2,-3,-4]也要变成[-1,-2,-3],最后一层IDetect也需要修改,该层的from表示第[n,n+1,n+2]层的输出作为Detect模块的输入,接着run,成功!

 

solution2:简单粗暴,不用改网络结构,在yaml的第2、3行depth_multiple与width_multiple进行修改, 其中深度与网络层中的number相乘,得到实际网络深度,宽度与通道数相乘,所以这两者设置为0-1之间可以直接影响整体网络,但实际检测效果肯定会大受影响。

solution3: anchor大小的修改,可以根据自己数据集的特点进行特征图大小的修改,每一对数字是anchors的长宽大小。

原始yolov7-tiny的参数量为6.2M,320*320的输入下FLOPs为3.46G;在solution2中,比例为0.5时Param与FLOPs分别为1.5M 与 0.41G,模型大小为3.1M ;比例为0.8时分别为4.03M与1.21G,模型大小为8.3M,但具体效果。。见仁见智了

solution1还在训练

猜你喜欢

转载自blog.csdn.net/yjcccccc/article/details/128329579
今日推荐