Open tfwn opened 3 years ago
环境:yolov5 是刚刚从github 拉取的最新版本 + yolov5prune 部分文件。 因为在 yolov5prune 工程中测试,发现无法运行。所以复制 train_sparsity.py prune.py prune_utils.py 到 最新的 yolov5 工程中测试。
- 在 yolov5 工程中修改 data/yolov5ss.yaml 使用自己的数据训练。 在 models/yolov5ss.yaml 中修改 depth_multiple:0.01 width_multiple:0.01 使用 train_sparsity.py 进行训练,最终可以得到非常小的参数文件。 python train.py --adam --epochs 100 python train_sparsity.py --st --sr 0.0001 --weights runs/train/exp/lest.pt --adam --epochs 100
- 训练完成后进行剪枝 python prune.py --weights runs/train/exp1/weights/last.pt --percent 0.3
到这里无法进行下去了。 问题:
- 在 models/yolov5ss.yaml 中修改 depth_multiple:0.01 width_multiple:0.01 这里是否影响后面的剪枝?以及是不是能够这样修改
- 请问你的yolov5prune 是基于哪个版本的 yolov5 ? 为啥使用自己的数据无法进行训练 能否和最新的yolov5 进行一下同步呢 非常感谢!
引入后然后通过https://github.com/ultralytics/yolov5/blob/daab682b06f8416319c99bdf25aec56616bf6ac1/models/yolo.py#L249
控制C3模块的深度和宽度,可以详细看看:https://github.com/ultralytics/yolov5/blob/daab682b06f8416319c99bdf25aec56616bf6ac1/models/yolo.py#L234
的实现。 对于yolov5s.yaml给出的: depth_multiple: 0.33 # model depth multiplewidth_multiple: 0.50 # layer channel multiple 设置,例如第一个focus模块参数: [[-1, 1, Focus, [64, 3]], # 0-P1/2 计算出来的实际参数: [[-1, 1, Focus, [32, 3]]
代码中应该有一些判断。
在yolov5 V4.0 上训练了自己的数据集。前几天重新拉取了 yolov5 v5.0, 重新训练了一次,也没有问题。 不过我确实没有仔细看过yolov5 的代码,只是跟着一些文档跑了一下试了试效果。
另外,拉取yolov5prune 并使用自己的数据集训练出现下面的问题
- 设置 depth_multiple :0.166 和 width_multiple:0.007, 训练自己的数据,使用 yolov5 依然可以正常训练并得到有效的参数,精度会有损失挺多。
代码中应该有一些判断。
- 在yolov5 V4.0 上训练了自己的数据集。前几天重新拉取了 yolov5 v5.0, 重新训练了一次,也没有问题。 不过我确实没有仔细看过yolov5 的代码,只是跟着一些文档跑了一下试了试效果。 另外,拉取yolov5prune 并使用自己的数据集训练出现下面的问题
git pull一下最新代码
btw,如果你设计的新模型yolov5xs: depth_multiple :0.166 和 width_multiple:0.007 那么可以随便看看某一层,例如: https://github.com/midasklr/yolov5prune/blob/b20bafd23cbe2761fa6d194a660aecd7baead9b3/models/yolov5s.yaml#L21 这个C3模块: [-1, 9, C3, [512]], 根据https://github.com/midasklr/yolov5prune/blob/b20bafd23cbe2761fa6d194a660aecd7baead9b3/models/yolo.py#L562 计算得到C3的 n = max(round(n gd), 1) if n > 1 else n = max(round(90.166),1) = ... = 1 也即是C3有一个bottleneck结构; 然后根据https://github.com/midasklr/yolov5prune/blob/b20bafd23cbe2761fa6d194a660aecd7baead9b3/models/yolo.py#L567 算出c2 = make_divisible(c2 gw, 8) = make_divisible(c2 gw, 8) = make_divisible(3.584, 8) = 8 这样设计出来的模型本身效果会非常差,而且需要你把backbone在imagenet上训练然后提取出来权重做后面检测的预训练权重才会有效果的。
btw,如果你设计的新模型yolov5xs: depth_multiple :0.166 和 width_multiple:0.007 那么可以随便看看某一层,例如: https://github.com/midasklr/yolov5prune/blob/b20bafd23cbe2761fa6d194a660aecd7baead9b3/models/yolov5s.yaml#L21
这个C3模块: [-1, 9, C3, [512]], 根据 https://github.com/midasklr/yolov5prune/blob/b20bafd23cbe2761fa6d194a660aecd7baead9b3/models/yolo.py#L562
计算得到C3的 n = max(round(n gd), 1) if n > 1 else n = max(round(90.166),1) = ... = 1 也即是C3有一个bottleneck结构; 然后根据 https://github.com/midasklr/yolov5prune/blob/b20bafd23cbe2761fa6d194a660aecd7baead9b3/models/yolo.py#L567
算出c2 = make_divisible(c2 gw, 8) = make_divisible(c2 gw, 8) = make_divisible(3.584, 8) = 8 这样设计出来的模型本身效果会非常差,而且需要你把backbone在imagenet上训练然后提取出来权重做后面检测的预训练权重才会有效果的。
非常感谢您的说明和解答。 因为之前想要做使用最少资源的一个检测,只需要检测几种物体,如人脸口罩手势等。 在知道 yolov5 时试了一下,又单纯的想着缩减资源消耗,就使用了 depth_multiple :0.166 和 width_multiple:0.007 。感觉效果没有特别差,资源的消耗也特别少,就先留着了。
谢谢,我再试一下能不能跑通流程。
我现在遇到和这位兄弟一样的问题;我用的是yolov5m6,你prune.py中pruned_yaml={}的内容我换为yolov5m6中的结构。还是遇到下面的问题,请大佬帮忙看下:
Fusing layers...
Model Summary: 396 layers, 35439396 parameters, 0 gradients, 51.4 GFLOPS
model.module_list: <generator object Module.named_children at 0x7fb461068cf0>
prune module : dict_keys([])
model_list: {}
bn_weights: tensor([])
prune.py:382: UserWarning: This overload of nonzero is deprecated:
nonzero()
Consider using one of the following signatures instead:
nonzero(*, bool as_tuple) (Triggered internally at /opt/conda/conda-bld/pytorch_1603729066392/work/torch/csrc/utils/python_arg_parser.cpp:882.)
percent_limit = (sorted_bn == highest_thre).nonzero()[0, 0].item() / len(bn_weights)
Traceback (most recent call last):
File "prune.py", line 818, in
Fusing layers...
你这里可能是进行了conv bn融合,导致没有了bn层,无法基于bn层进行剪枝. 另外yolov5m6模型结构和yolov5模型结构不一样,后者有24个模块, 如果要对yolov5s/m/l/x6进行剪枝,需要做一些细微的修改.
感谢你的解答: conv bn融合?我就是直接稀疏化训练,这块不知道是哪里融合的? 你说的修改是指prune.py中pruned_yaml={}的内容的修改? 方便加qq?我的qq是1632401541
感谢你的解答: conv bn融合?我就是直接稀疏化训练,这块不知道是哪里融合的? 你说的修改是指prune.py中pruned_yaml={}的内容的修改? 方便加qq?我的qq是1632401541
model.fuse()会进行conv bn层融合,进而不会有bn层. 无论是yolov5 还是yolov56 ,稀疏训练的关键都在这段 https://github.com/midasklr/yolov5prune/blob/f981e8e21220da0dafbc12bda2761691dd104ca1/train_sparsity.py#L325
注意观察训练时候bn层的随着epoch分布变化是否变得稀疏. 剪枝的时候,字典model_list是所有需要剪枝的bn层,但是你这里为空,应该是: https://github.com/midasklr/yolov5prune/blob/f981e8e21220da0dafbc12bda2761691dd104ca1/prune.py#L350 这部分获得需要剪枝的bn层有问题,需要调试看看.
大佬你好,我重现下载你最新的代码,复现你的yolov5s剪枝:
1 我模型稀疏化训练时,没稀疏化训练的模型是54.63M,稀疏化训练变成了81.66M
2 用稀疏的模型进行剪枝,剪枝0.5
Traceback (most recent call last):
File "prune.py", line 803, in
是因为我的model.4.cv3.bn,model.17.cv1.bn ,model.17.m.0.cv1.bn值为0的缘故,剪枝不了? 那为何的稀疏化模型会变大呢?
del.0.conv.bn | 32 | 32 | | model.1.bn | 64 | 64 | | model.2.cv1.bn | 32 | 32 | | model.2.cv2.bn | 32 |
原始的yolov5s模型大概28M; 剪枝时,每层bn至少要保留1个channel,所以剪枝比例不能随意设置.你这里模型为什么会是54M?
这块我也不是很清楚,我就是根据你的步骤进行操作: 1 训练命令:python train.py --data models/ql_infrared/voc_infrared.yaml --cfg models/ql_infrared/yolov5s.yaml --weights pretain_weights/yolov5s.pt --batch-size 8 --cache-images --device 0,1 --sync-bn 2 稀疏化训练:python train_sparsity.py --st --sr 0.001 --data models/ql_infrared/voc_infrared.yaml --cfg models/ql_infrared/yolov5s.yaml --weights runs/train/exp/weights/best.pt --batch-size 8 --cache-images --device 0,1 --sync-bn 3 剪枝 : python prune.py --weights runs/train/exp7/weights/best.pt --data models/ql_infrared/voc_infrared.yaml --percent 0.5
这块我也不是很清楚,我就是根据你的步骤进行操作: 1 训练命令:python train.py --data models/ql_infrared/voc_infrared.yaml --cfg models/ql_infrared/yolov5s.yaml --weights pretain_weights/yolov5s.pt --batch-size 8 --cache-images --device 0,1 --sync-bn 2 稀疏化训练:python train_sparsity.py --st --sr 0.001 --data models/ql_infrared/voc_infrared.yaml --cfg models/ql_infrared/yolov5s.yaml --weights runs/train/exp/weights/best.pt --batch-size 8 --cache-images --device 0,1 --sync-bn 3 剪枝 : python prune.py --weights runs/train/exp7/weights/best.pt --data models/ql_infrared/voc_infrared.yaml --percent 0.5
54.63M应该是你的last.pt,除了保存模型,还保存了其他训练中参数,见:https://github.com/midasklr/yolov5prune/blob/f981e8e21220da0dafbc12bda2761691dd104ca1/train.py#L396 实际未剪枝模型大概28M(fp32, no model.half()). 正常训练map多少?稀疏训练map多少?
我的看了下train.py没有问题。保存其它 我是用自己数据集训练的,map还行。 之前直接看这个连接操作:https://blog.csdn.net/jacke121/article/details/117250264 在稀疏训练时模型就减少了一半。感觉很奇怪。
环境:yolov5 是刚刚从github 拉取的最新版本 + yolov5prune 部分文件。 因为在 yolov5prune 工程中测试,发现无法运行。所以复制 train_sparsity.py prune.py prune_utils.py 到 最新的 yolov5 工程中测试。
在 yolov5 工程中修改 data/yolov5ss.yaml 使用自己的数据训练。 在 models/yolov5ss.yaml 中修改 depth_multiple:0.01 width_multiple:0.01 使用 train_sparsity.py 进行训练,最终可以得到非常小的参数文件。 python train.py --adam --epochs 100 python train_sparsity.py --st --sr 0.0001 --weights runs/train/exp/lest.pt --adam --epochs 100
训练完成后进行剪枝 python prune.py --weights runs/train/exp1/weights/last.pt --percent 0.3
到这里无法进行下去了。
问题: