yolov5剪枝复现

1、github

本项目基于tanluren/yolov3-channel-and-layer-pruning实现,将项目扩展到yolov5上。

项目的基本流程是,使用ultralytics/yolov5训练自己的数据集,在模型性能达到要求但速度未达到要求时,对模型进行剪枝。首先是稀疏化训练,稀疏化训练很重要,如果模型稀疏度不够,剪枝比例过大会导致剪枝后的模型map接近0。剪枝完成后对模型进行微调回复精度。

yolov5_prune:GitHub - ZJU-lishuang/yolov5_prune: yolov5 prune,Support V2, V3, V4 and V6 versions of yolov5

yolov3-channel-and-layer-pruning:GitHub - tanluren/yolov3-channel-and-layer-pruning: yolov3 yolov4 channel and layer pruning, Knowledge Distillation 层剪枝,通道剪枝,知识蒸馏

yolov5-v6:https://github.com/ZJU-lishuang/yolov5-v6

 看起来还不错的博客:YOLOv5s 剪枝_m0_53608998的博客-CSDN博客_yolov5s剪枝

2、复现提纲

  • 原来yolov5的速度是多少(推理的帧率,训练的速度,数据加载的速度)
  • 原来权重的大小(剪枝率)
  • 精度的变化(在剪枝和微调的过程中精度的变化)
  • 参数的选择
  • 不同的剪枝方法选择
  • 设备:RTX3060 12GB

3、调试记录(先整体跑一遍剪枝,从yolov5开始)

(1)作者是根据yolov3-pruning改的,详细的介绍在yolov3-prune的readme里面有,作者把前面基础训练和稀疏训练的代码放在另一个yolov5-v5的仓库里面

yolov5剪枝复现_第1张图片

 (2)基础训练是根据coco_hand数据集训练50个epoch

数据集的构建

-------------这部分是我的操作,不太正确但能行,正确的结构在“实际的数据集位置结构”中-----------

要单独下载数据集,然后用提供的脚本converter.py转换成可训练格式

把脚本放在yolov5-v6文件夹下,把路径指向data,把里面复制进去的hand_dataset文件夹转换成yolov5-v6文件夹下的images和labels.

把脚本生成的train.txt和valid.txt放到文件夹hand_data下

--------------------------------------------------------------------------------------------------------------------------------

实际的数据集位置结构

  • 下载得到的数据集解压之后的hand_dataset要放在data文件夹下面,利用converter.py脚本转换在data文件夹中得到images和labels,同时还会得到train.txt和valid.txt这是在coco_hand.yaml中用来索引训练集和测试集图片的。
  • train.py通过coco_hand.yaml索引训练集和测试集图片,在总目录下面创建一个hand_data用来放train.txt和valid.txt,后面生成的缓存文件也会放在这个文件夹下面。(这是因为train.py中的数据配置文件是coco_hand.yaml,而coco_hand.yaml的path直接指向“hand_data”,这里其实也不是很清楚是在哪个文件夹路径下面的索引,或者说是项目里面的索引,因为train.py直接在总目录下, 所以把hand_data文件夹也放在同一个目录下)
  • images和labels应该放在data文件夹下面,也就是说,converter.py本来应该是在data文件夹里面的某个位置,指向data,通过索引hand_dataset里面的内容来
  • yolov5剪枝复现_第2张图片coco_hand.yaml的内容
  • yolov5剪枝复现_第3张图片 data文件夹的结构

然后报错找不到权重文件weights/yolov5s_v6.pt,懒得操作了,直接复制了比较近的yolov5的权重yolov5s.pt来训练

error:Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.

用下面的方法解决了

import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"

成功开始训练:

训练集中4096张图片,一个epoch 2min左右

yolov5剪枝复现_第4张图片

训练50epoch结果;

yolov5剪枝复现_第5张图片

跑一下推理

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXBpY19MaW4=,size_20,color_FFFFFF,t_70,g_se,x_16

每张图片在 0.005到0.007之间波动(这个应该是推理我感觉),全过程取7.5ms一张图片,大概是130-145帧左右。

(2)稀疏化训练

 报错:error: ambiguous option: --s could match --sparsity-regularization, --scale, --single-cls, --sync-bn, --save-period

解决:应该是没有 -- s这个参数,在train_sparsity.py里面找到比较对应的参数应该是scale了,默认设置是0.001和参数配置的要求一样,所以把 --s 0.001去掉就可以跑了

另外,在这里同样也出现了上面训练一样的Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.问题,用一样的方法解决

训练命令

python train_sparsity.py --img 640 --batch 32 --epochs 50 --data data/coco_hand.yaml --cfg models/yolov5s.yaml --weights runs/train/s_hand13/weights/last.pt --name s_hand_sparsity -sr  --prune 1

 稀疏化训练,有一点掉点:

yolov5剪枝复现_第6张图片

 ps:

scale参数默认0.001,根据数据集,mAP,BN分布调整,数据分布广类别多的,或者稀疏时掉点厉害的适当调小s;-sr用于开启稀疏训练;--prune 0适用于prune.py,--prune 1 适用于其他剪枝策略。稀疏训练就是精度和稀疏度的博弈过程,如何寻找好的策略让稀疏后的模型保持高精度同时实现高稀疏度是值得研究的问题,大的s一般稀疏较快但精度掉的快,小的s一般稀疏较慢但精度掉的慢;配合大学习率会稀疏加快,后期小学习率有助于精度回升。 

接下来的关键任务:

1、查看--prune 1稀疏训练结果

2、熟悉查看各种剪枝策略,不同稀疏化方法对应不同剪枝方法

3、能不能或者需不需要像yolov3-prune一样采用不同的s进行稀疏化训练,如果需要的话s的衰减怎么设置

4、Tensorboard中bn层的图像怎么看,看不懂

5、看train_sparsity.py中的稀疏化训练的部分

6、查看剪枝部分代码,看看yolov5这种BN层和卷积层没有一环套一环的结构怎么进行剪枝。

7、查看不同剪枝策略的实现,比如有shortcut和无shortcut分别怎么操作

8、像yolov3-prune中说的那样.py文件中含有epoch信息,在yolov5中有没有这种情况,什么时候是恢复训练,什么时候是从头开始训练。如果想要恢复训练可不可以先停下来调整一下s再继续训练,这能不能实现

整体效果还可以:

yolov5剪枝复现_第7张图片

 附上yolov5的结构图

 prune 1,50epoch结果:(s_hand_sparsity4)

yolov5剪枝复现_第8张图片

yolov5剪枝复现_第9张图片 yolov5剪枝复现_第10张图片

 prune 0,50epoch的结果:(s_hand_sparsity5)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXBpY19MaW4=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAZXBpY19MaW4=,size_20,color_FFFFFF,t_70,g_se,x_16

yolov5剪枝复现_第11张图片 (红色是prune 1的结果,蓝色是prune 0,灰白色是原训练)

prune 1+100epoch+s=0.001:(s_hand_sparsity11)

yolov5剪枝复现_第12张图片

yolov5剪枝复现_第13张图片 yolov5剪枝复现_第14张图片

yolov5剪枝复现_第15张图片

yolov5剪枝复现_第16张图片

 prune 1+120epoch+s=0.001:

parameter:lr0=0.01, lrf=0.1, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.5, cls_pw=1.0, obj=1.0, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, fl_gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv
_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0

 命令:

 python train_sparsity.py --img 640 --batch 32 --epochs 200 --data data/coco_hand.yaml --cfg models/yolov5s.yaml --weights runs/train/s_hand13/weights/last.pt --name s_hand_sparsity -sr  --prune 1

结果:s_hand_sparsity13,跑到120左右的时候停电了

train.py+epoch 140:

s_hand14:     140epoch手动停掉了,跟50epoch的时候基本一致,而且精度上升的速度还比50epoch的时候慢了一点,猜测是训练schedule的原因 

 

 

(3)尝试进行剪枝:

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(深度学习,计算机视觉)