Coder Social home page Coder Social logo

tanluren / yolov3-channel-and-layer-pruning Goto Github PK

View Code? Open in Web Editor NEW
1.5K 26.0 447.0 1.55 MB

yolov3 yolov4 channel and layer pruning, Knowledge Distillation 层剪枝,通道剪枝,知识蒸馏

License: Apache License 2.0

Shell 4.45% Python 94.30% Dockerfile 1.25%

yolov3-channel-and-layer-pruning's Introduction

yolov3-channel-and-layer-pruning

本项目以ultralytics/yolov3为基础实现,根据论文Learning Efficient Convolutional Networks Through Network Slimming (ICCV 2017)原理基于bn层Gmma系数进行通道剪枝,下面引用了几种不同的通道剪枝策略,并对原策略进行了改进,提高了剪枝率和精度;在这些工作基础上,又衍生出了层剪枝,本身通道剪枝已经大大减小了模型参数和计算量,降低了模型对资源的占用,而层剪枝可以进一步减小了计算量,并大大提高了模型推理速度;通过层剪枝和通道剪枝结合,可以压缩模型的深度和宽度,某种意义上实现了针对不同数据集的小模型搜索。

项目的基本工作流程是,使用yolov3训练自己数据集,达到理想精度后进行稀疏训练,稀疏训练是重中之重,对需要剪枝的层对应的bn gamma系数进行大幅压缩,理想的压缩情况如下图,然后就可以对不重要的通道或者层进行剪枝,剪枝后可以对模型进行微调恢复精度,后续会写篇博客记录一些实验过程及调参经验,在此感谢行云大佬的讨论和合作!

稀疏


更新

1.增加了对yolov3-spp结构的支持,基础训练可以直接使用yolov3-spp.weights初始化权重,各个层剪枝及通道剪枝脚本的使用也和yolov3一致。
2.增加了多尺度推理支持,train.py和各剪枝脚本都可以指定命令行参数, 如 --img_size 608 .
3.2019/12/06更改了层剪枝的选层策略,由最大值排序改为均值排序。
4.2019/12/08重要更新,增加了知识蒸馏策略。蒸馏是用高精度的大模型指导低精度的小模型,在结构相似的情况下效果尤为明显。而剪枝得到的小模型和原模型在结构上高度相似,非常符合蒸馏的应用条件。这里更新了一个参考Hinton大神Distilling the Knowledge in a Neural Network的蒸馏策略,原策略是针对分类模型的,但在这里也有不错的表现。调用只需要在微调的时候指定老师模型的cfg和权重即可:--t_cfg --t_weights。最近会更新第二种针对yolo检测的知识蒸馏策略。
5.2019/12/10交流的小伙伴比较多,回答不过来,可以加群734912150
6.2019/12/14增加了针对蒸馏的混合精度训练支持,项目中各项训练都可以使用apex加速,但需要先安装。使用混合精度可以加速训练,同时减轻显存占用,但训练效果可能会差一丢丢。代码默认开启了混合精度,如需关闭,可以把train.py中的mixed_precision改为False.
7.2019/12/23更新了知识蒸馏策略二,并默认使用二。策略二参考了论文"Learning Efficient Object Detection Models with Knowledge Distillation",相比策略一,对分类和回归分别作了处理,分类的蒸馏和策略一差不多,回归部分会分别计算学生和老师相对target的L2距离,如果学生更远,学生会再向target学习,而不是向老师学习。调用同样是指定老师的cfg和权重即可。需要强调的是,蒸馏在这里只是辅助微调,如果注重精度优先,剪枝时尽量剪不掉点的比例,这时蒸馏的作用也不大;如果注重速度,剪枝比例较大,导致模型精度下降较多,可以结合蒸馏提升精度。
8.2019/12/27更新了两种稀疏策略,详看下面稀疏训练环节。
9.2020/01/02修正各剪枝版本多分辨率推理test问题,主要是把命令行参数img_size传递给test函数。
10.2020/01/04补了个博客分享无人机数据集visdrone案例,演示如何压缩一个12M的无人机视角目标检测模型(标题党)。
11.2020/04/10增加了yolov3-tiny的剪枝支持,稀疏照旧,剪通道用slim_prune.py,不可剪层。
12.2020/4/24增加支持yolov4剪枝.
13.2020/4/30在datasets.py 592行添加了支持负样本训练,默认注释掉.
14.2020/7/8更新支持yolov4-tiny剪通道.

基础训练

环境配置查看requirements.txt,数据准备参考这里,预训练权重可以从darknet官网下载。
用yolov3训练自己的数据集,修改cfg,配置好data,用yolov3.weights初始化权重。

python train.py --cfg cfg/my_cfg.cfg --data data/my_data.data --weights weights/yolov3.weights --epochs 100 --batch-size 32

稀疏训练

scale参数默认0.001,根据数据集,mAP,BN分布调整,数据分布广类别多的,或者稀疏时掉点厉害的适当调小s;-sr用于开启稀疏训练;--prune 0适用于prune.py,--prune 1 适用于其他剪枝策略。稀疏训练就是精度和稀疏度的博弈过程,如何寻找好的策略让稀疏后的模型保持高精度同时实现高稀疏度是值得研究的问题,大的s一般稀疏较快但精度掉的快,小的s一般稀疏较慢但精度掉的慢;配合大学习率会稀疏加快,后期小学习率有助于精度回升。
注意:训练保存的pt权重包含epoch信息,可通过python -c "from models import *; convert('cfg/yolov3.cfg', 'weights/last.pt')"转换为darknet weights去除掉epoch信息,使用darknet weights从epoch 0开始稀疏训练。

python train.py --cfg cfg/my_cfg.cfg --data data/my_data.data --weights weights/last.weights --epochs 300 --batch-size 32 -sr --s 0.001 --prune 1

  • 稀疏策略一:恒定s

这是一开始的策略,也是默认的策略。在整个稀疏过程中,始终以恒定的s给模型添加额外的梯度,因为力度比较均匀,往往压缩度较高。但稀疏过程是个博弈过程,我们不仅想要较高的压缩度,也想要在学习率下降后恢复足够的精度,不同的s最后稀疏结果也不同,想要找到合适的s往往需要较高的时间成本。

bn_module.weight.grad.data.add_(s * torch.sign(bn_module.weight.data))

  • 稀疏策略二:全局s衰减

关键代码是下面这句,在epochs的0.5阶段s衰减100倍。前提是0.5之前权重已经完成大幅压缩,这时对s衰减有助于精度快速回升,但是相应的bn会出现一定膨胀,降低压缩度,有利有弊,可以说是牺牲较大的压缩度换取较高的精度,同时减少寻找s的时间成本。当然这个0.5和100可以自己调整。注意也不能为了在前半部分加快压缩bn而大大提高s,过大的s会导致模型精度下降厉害,且s衰减后也无法恢复。如果想使用这个策略,可以在prune_utils.py中的BNOptimizer把下面这句取消注释。

# s = s if epoch <= opt.epochs * 0.5 else s * 0.01

  • 稀疏策略三:局部s衰减

关键代码是下面两句,在epochs的0.5阶段开始对85%的通道保持原力度压缩,15%的通道进行s衰减100倍。这个85%是个先验知识,是由策略一稀疏后尝试剪通道几乎不掉点的最大比例,几乎不掉点指的是相对稀疏后精度;如果微调后还是不及baseline,或者说达不到精度要求,就可以使用策略三进行局部s衰减,从中间开始重新稀疏,这可以在牺牲较小压缩度情况下提高较大精度。如果想使用这个策略可以在train.py中把下面这两句取消注释,并根据自己策略一情况把0.85改为自己的比例,还有0.5和100也是可调的。策略二和三不建议一起用,除非你想做组合策略。

#if opt.sr and opt.prune==1 and epoch > opt.epochs * 0.5:
# idx2mask = get_mask2(model, prune_idx, 0.85)

通道剪枝策略一

策略源自Lam1360/YOLOv3-model-pruning,这是一种保守的策略,因为yolov3中有五组共23处shortcut连接,对应的是add操作,通道剪枝后如何保证shortcut的两个输入维度一致,这是必须考虑的问题。而Lam1360/YOLOv3-model-pruning对shortcut直连的层不进行剪枝,避免了维度处理问题,但它同样实现了较高剪枝率,对模型参数的减小有很大帮助。虽然它剪枝率最低,但是它对剪枝各细节的处理非常优雅,后面的代码也较多参考了原始项目。在本项目中还更改了它的阈值规则,可以设置更高的剪枝阈值。

python prune.py --cfg cfg/my_cfg.cfg --data data/my_data.data --weights weights/last.pt --percent 0.85

通道剪枝策略二

策略源自coldlarry/YOLOv3-complete-pruning,这个策略对涉及shortcut的卷积层也进行了剪枝,剪枝采用每组shortcut中第一个卷积层的mask,一共使用五种mask实现了五组shortcut相关卷积层的剪枝,进一步提高了剪枝率。本项目中对涉及shortcut的剪枝后激活偏移值处理进行了完善,并修改了阈值规则,可以设置更高剪枝率,当然剪枝率的设置和剪枝后的精度变化跟稀疏训练有很大关系,这里再次强调稀疏训练的重要性。

python shortcut_prune.py --cfg cfg/my_cfg.cfg --data data/my_data.data --weights weights/last.pt --percent 0.6

通道剪枝策略三

策略参考自PengyiZhang/SlimYOLOv3,这个策略的通道剪枝率最高,先以全局阈值找出各卷积层的mask,然后对于每组shortcut,它将相连的各卷积层的剪枝mask取并集,用merge后的mask进行剪枝,这样对每一个相关层都做了考虑,同时它还对每一个层的保留通道做了限制,实验中它的剪枝效果最好。在本项目中还对激活偏移值添加了处理,降低剪枝时的精度损失。

python slim_prune.py --cfg cfg/my_cfg.cfg --data data/my_data.data --weights weights/last.pt --global_percent 0.8 --layer_keep 0.01

层剪枝

这个策略是在之前的通道剪枝策略基础上衍生出来的,针对每一个shortcut层前一个CBL进行评价,对各层的Gmma均值进行排序,取最小的进行层剪枝。为保证yolov3结构完整,这里每剪一个shortcut结构,会同时剪掉一个shortcut层和它前面的两个卷积层。是的,这里只考虑剪主干中的shortcut模块。但是yolov3中有23处shortcut,剪掉8个shortcut就是剪掉了24个层,剪掉16个shortcut就是剪掉了48个层,总共有69个层的剪层空间;实验中对简单的数据集剪掉了较多shortcut而精度降低很少。

python layer_prune.py --cfg cfg/my_cfg.cfg --data data/my_data.data --weights weights/last.pt --shortcuts 12

同时剪层和通道

前面的通道剪枝和层剪枝已经分别压缩了模型的宽度和深度,可以自由搭配使用,甚至迭代式剪枝,调配出针对自己数据集的一副良药。这里整合了一个同时剪层和通道的脚本,方便对比剪枝效果,有需要的可以使用这个脚本进行剪枝。

python layer_channel_prune.py --cfg cfg/my_cfg.cfg --data data/my_data.data --weights weights/last.pt --shortcuts 12 --global_percent 0.8 --layer_keep 0.1

微调finetune

剪枝的效果好不好首先还是要看稀疏情况,而不同的剪枝策略和阈值设置在剪枝后的效果表现也不一样,有时剪枝后模型精度甚至可能上升,而一般而言剪枝会损害模型精度,这时候需要对剪枝后的模型进行微调,让精度回升。训练代码中默认了前6个epoch进行warmup,这对微调有好处,有需要的可以自行调整超参学习率。

python train.py --cfg cfg/prune_0.85_my_cfg.cfg --data data/my_data.data --weights weights/prune_0.85_last.weights --epochs 100 --batch-size 32

tensorboard实时查看训练过程

tensorboard --logdir runs

tensorboard
欢迎使用和测试,有问题或者交流实验过程可以发issue或者加群734912150

案例

使用yolov3-spp训练oxfordhand数据集并剪枝。下载数据集,解压到data文件夹,运行converter.py,把得到的train.txt和valid.txt路径更新在oxfordhand.data中。通过以下代码分别进行基础训练和稀疏训练:
python train.py --cfg cfg/yolov3-spp-hand.cfg --data data/oxfordhand.data --weights weights/yolov3-spp.weights --batch-size 20 --epochs 100

python -c "from models import *; convert('cfg/yolov3.cfg', 'weights/last.pt')"
python train.py --cfg cfg/yolov3-spp-hand.cfg --data data/oxfordhand.data --weights weights/converted.weights --batch-size 20 --epochs 300 -sr --s 0.001 --prune 1

训练的情况如下图,蓝色线是基础训练,红色线是稀疏训练。其中基础训练跑了100个epoch,后半段已经出现了过拟合,最终得到的baseline模型mAP为0.84;稀疏训练以s0.001跑了300个epoch,选择的稀疏类型为prune 1全局稀疏,为包括shortcut的剪枝做准备,并且在总epochs的0.7和0.9阶段进行了Gmma为0.1的学习率衰减,稀疏过程中模型精度起伏较大,在学习率降低后精度出现了回升,最终稀疏模型mAP 0.797。
baseline_and_sparse
再来看看bn的稀疏情况,代码使用tensorboard记录了参与稀疏的bn层的Gmma权重变化,下图左边看到正常训练时Gmma总体上分布在1附近类似正态分布,右边可以看到稀疏过程Gmma大部分逐渐被压到接近0,接近0的通道其输出值近似于常量,可以将其剪掉。
bn
这时候便可以进行剪枝,这里例子使用layer_channel_prune.py同时进行剪通道和剪层,这个脚本融合了slim_prune剪通道策略和layer_prune剪层策略。Global perent剪通道的全局比例为0.93,layer keep每层最低保持通道数比例为0.01,shortcuts剪了16个,相当于剪了48个层(32个CBL,16个shortcut);下图结果可以看到剪通道后模型掉了一个点,而大小从239M压缩到5.2M,剪层后mAP掉到0.53,大小压缩到4.6M,模型参数减少了98%,推理速度也从16毫秒减到6毫秒(tesla p100测试结果)。
python layer_channel_prune.py --cfg cfg/yolov3-spp-hand.cfg --data data/oxfordhand.data --weights weights/last.pt --global_percent 0.93 --layer_keep 0.01 --shortcuts 16

prune9316
鉴于模型精度出现了下跌,我们来进行微调,下面是微调50个epoch的结果,精度恢复到了0.793,bn也开始呈正态分布,这个结果相对于baseline掉了几个点,但是模型大幅压缩减少了资源占用,提高了运行速度。如果想提高精度,可以尝试降低剪枝率,比如这里只剪10个shortcut的话,同样微调50epoch精度可以回到0.81;而想追求速度的话,这里有个极端例子,全局剪0.95,层剪掉54个,模型压缩到了2.8M,推理时间降到5毫秒,而mAP降到了0,但是微调50epoch后依然回到了0.75。

python train.py --cfg cfg/prune_16_shortcut_prune_0.93_keep_0.01_yolov3-spp-hand.cfg --data data/oxfordhand.data --weights weights/prune_16_shortcut_prune_0.93_keep_0.01_last.weights --batch-size 52 --epochs 50
finetune_and_bn
可以猜测,剪枝得到的cfg是针对该数据集相对合理的结构,而保留的权重可以让模型快速训练接近这个结构的能力上限,这个过程类似于一种有限范围的结构搜索。而不同的训练策略,稀疏策略,剪枝策略会得到不同的结果,相信即使是这个例子也可以进一步压缩并保持良好精度。yolov3有众多优化项目和工程项目,可以利用这个剪枝得到的cfg和weights放到其他项目中做进一步优化和应用。
这里分享了这个例子的权重和cfg,包括baseline,稀疏,不同剪枝设置后的结果。

License

Apache 2.0

yolov3-channel-and-layer-pruning's People

Contributors

tanluren avatar zbyuan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yolov3-channel-and-layer-pruning's Issues

UnboundLocalError: local variable 'labels' referenced before assignment

yolov3改进:4层shortcuts
基础训练命令:python3 train.py --cfg /usr/cx/darknetalexeyAB/darknet-master/names_data/yolo-obj.cfg --data /usr/cx/darknetalexeyAB/darknet-master/names_data/voc.data --weights /usr/cx/darknetalexeyAB/darknet-master/yolov3.weights --epochs 100 --batch-size 20

两类目标检测,精度为0

单类目标检测没问题,效果很好,但是同一个数据集,我检测两个类之后,刚开始训练精度非常低,0.008,经过几个epoch就降到0了, 尝试过调小学习率,增大batch,还是这样。请问有大佬碰到过吗。
Screenshot from 2019-12-05 14-14-27

剪枝mAP=0?inference没变?正确的流程应该怎样?

我使用如下命令进行剪枝
`python train.py --cfg cfg/yolov3.cfg --data data
--weights weights/last.pt
--epochs 100 --batch-size 16 -sr --s 0.001 --prune 1

python shortcut_prune.py --cfg cfg/yolov3.cfg --data data
--weights weights/last.pt
--percent 0.6`

稀疏训练没有100epochs就停止了。
然后结果非常糟糕
image
请问有何建议?
是需要更多的稀疏训练?然后需要fine tune吗。剪枝之后,不训练,map也可以正常吗?
inference没变?是因为我使用了显卡吗。本来很快?所以剪枝加速不明显?(使用的1080ti单卡)

关于shortcut_prune的bn剪枝规则有些疑问

十分感谢大佬贡献代码,让我们有学习的机会。
不好意思。我又来提问了。十分感谢您的回答。
有两点疑问
1,代码里面,L307,如果是shortcut前一层conv,使用from的conv层的mask。但是这个mask 不能代表 “shortcut前一层conv” 这层的卷积的重要顺序了。

我想了一个规则,不知道是否可行:
使用“from的conv层的mask”中剪枝的数量,再造一个mask2,使sum(mask2)=sum(mask);然后对“shortcut前一层conv”这层的卷积排序,取最大的。
但是随之带来的问题是,两个mask 相加之后通道数就不一样了。所以后面可能要修改创建网络的规则。

第2个疑问
虽然我们使用用bn的剪枝规则与《Learning Efficient Convolutional Networks Through Network Slimming》论文中是一样的。但是不知道您是否有思考过。
剪枝的阈值是通过 所有bn的weight排序得到的。这真的公平吗?
①网络最前面的数值,更靠近图像像素值,最后一层更靠近类别概率。bn的weight不一定分布相同
②在网络中间有shortcut,两个卷积像素值叠加后,weight参数变大。可能会影响bn的weight。
不知道是否存在①②的现象。

issues35
期待您的回复。十分感谢

compact_conv.weight.data = tmp[out_channel_idx, :, :, :].clone()报错

你好,我在执行layer_channel_prune.py时出现了报错:
/pytorch/aten/src/ATen/native/cuda/IndexKernel.cu:60: lambda ->auto::operator()(int)->auto: block: [32,0,0], thread: [87,0,0] Assertion index >= -sizes[i] && index < sizes[i] && "index out of bounds" failed.
请问有人知道原因吗

AssertionError: No labels found. Recommend correcting image and label paths.

loaded weights from weights/yolov3.weights
Reading labels: 100%|████████████████████████| 20/20 [00:00<00:00, 78251.94it/s]
Traceback (most recent call last):
File "train.py", line 497, in
train() # train normally
File "train.py", line 239, in train
cache_images=False if opt.prebias else opt.cache_images)
File "/home/nvidia/yolov3-channel-and-layer-pruning-master/utils/datasets.py", line 373, in init
assert nf > 0, 'No labels found. Recommend correcting image and label paths.'
AssertionError: No labels found. Recommend correcting image and label paths.

这个路径该怎么设置,我的数据没有问题,之前用darknet跑过,现在是放在本项目的路径下报这个错,放在darknet那边也是这样。
大神,下一步怎么处理?

训练异常中断,弹出“Python已停止工作”的窗口

Reading labels (8952 found, 0 missing, 0 empty for 8967 images): 100%|███████████▉| 8952/8967 [00:37<00:00,
Reading labels (8967 found, 0 missing, 0 empty for 8967 images): 100%|████████████| 8967/8967 [00:37<00:00, 237.71it/s]
Model Summary: 222 layers, 6.1626e+07 parameters, 6.1626e+07 gradients
Starting training for 273 epochs...

 Epoch   gpu_mem      GIoU       obj       cls     total      soft   targets  img_size

0%| | 0/561 [00:00<?, ?it/s]learning rate: 1e-06

(Pytorch) F:\DeepLearning\YOLO优化\yolov3-channel-and-layer-pruning-master>

你好,我训练开始不久程序就崩溃了,然后弹出了“Python已停止工作”的窗口。请问这是什么原因呢,该如何解决?

大佬您好,detect.py调用摄像头没有识别结果

u版的输入如下命令python detect.py --cfg cfg/yolov3.cfg --weights weights/yolov3.weights --source 0 --conf-thres 0.1可以调用摄像头且正常识别。
没看到您有介绍如何test或detect的教程,所以我在这里也这么使用,但是无法识别,如下图,cfg也改成test模式了。请问什么原因。
image

训练的时候维度出错。。

File "train.py", line 499, in
train() # train normally
File "train.py", line 327, in train
pred = model(imgs)
File "/home/112831/anaconda3.6/lib/python3.6/site-packages/torch/nn/modules/module.py", line 494, in call
result = self.forward(*input, **kwargs)
File "/home/112831/code/yolov3/models.py", line 244, in forward
x = module(x, img_size)
File "/home/112831/anaconda3.6/lib/python3.6/site-packages/torch/nn/modules/module.py", line 494, in call
result = self.forward(*input, **kwargs)
File "/home/112831/code/yolov3/models.py", line 149, in forward
p = p.view(bs, self.na, self.nc + 5, self.ny, self.nx).permute(0, 1, 3, 4, 2).contiguous() # prediction
RuntimeError: shape '[5, 3, 12, 52, 52]' is invalid for input of size 243360

yolov3检测OCR字符,精度很低

作者大神好!我能复现了您的hand数据集检测,但是在训练自己数据集时遇到了精度问题。我
正在用自己制作的ocr火车票数据集训练yolov3剪枝模型,数据预处理也是按照您给的那个链接来的,可是在第一步基础训练时就遇到了精度很低的情况,mAP只有0.135左右,测试了下漏检很多。我尝试过增大batchsize和减小学习率lr0,都没有改善,请问作者大神有什么好的建议?
111

开启prebias选项训练出错

步骤:稀疏化训练

ssh://[email protected]:8026/usr/local/bin/python -u /project/pytorch-yolov3/train_prune.py --data=data/person_1cls.data --batch-size=4 --cfg=cfg/yolov3-spp-1cls-a2.cfg --weights=weights/yolov3-spp.weights --device=0 --prebias -sr --s=0.001 --prune=0
Namespace(accumulate=2, adam=False, arc='defaultpw', batch_size=4, bucket='', cache_images=False, cfg='cfg/yolov3-spp-1cls-a2.cfg', data='data/person_1cls.data', device='0', epochs=273, evolve=False, img_size=416, img_weights=False, multi_scale=False, name='', nosave=False, notest=False, prebias=True, prune=0, rect=False, resume=False, s=0.001, sr=True, t_cfg='', t_weights='', transfer=False, var=None, weights='weights/yolov3-spp.weights')
Using CUDA device0 _CudaDeviceProperties(name='GeForce GTX 1660', total_memory=5941MB)

loaded weights from weights/yolov3-spp.weights 

normal sparse training 
Model Summary: 225 layers, 6.25733e+07 parameters, 54 gradients
Starting prebias for 1 epochs...

     Epoch   gpu_mem      GIoU       obj       cls     total      soft    rratio   targets  img_size
  0%|                                                  | 0/1524 [00:00<?, ?it/s]learning rate: 1e-06
Traceback (most recent call last):
  File "/project/pytorch-yolov3/train_prune.py", line 537, in <module>
    prebias()  # optional
  File "/project/pytorch-yolov3/train_prune.py", line 484, in prebias
    train()  # transfer-learn yolo biases for 1 epoch
  File "/project/pytorch-yolov3/train_prune.py", line 380, in train
    BNOptimizer.updateBN(sr_flag, model.module_list, opt.s, prune_idx, idx2mask)
  File "/project/pytorch-yolov3/utils/prune_utils.py", line 148, in updateBN
    bn_module.weight.grad.data.add_(s * torch.sign(bn_module.weight.data))  # L1
AttributeError: 'NoneType' object has no attribute 'data'
  0%|                                                  | 0/1524 [00:02<?, ?it/s]

Process finished with exit code 1

关掉prebias后可以训练,请问大家有没有这个问题?

yolov3-spp剪枝

我想做yolov3-spp的剪枝,(就是不同网络的剪枝),有哪些参数要修改呢?
yolov3-spp只比yolov3多几个maxpooling

目前我修改了ignore_idx

def parse_module_defs(model):
    if hasattr(model, 'module'):
        print('muti-gpus sparse')
        module_defs = model.module.module_defs
    else:
        print('single-gpu sparse')
        module_defs = model.module_defs
    CBL_idx = []
    Conv_idx = []
    for i, module_def in enumerate(module_defs):
        if module_def['type'] == 'convolutional':
            if module_def['batch_normalize'] == '1':
                CBL_idx.append(i)
            else:
                Conv_idx.append(i)
    ignore_idx = set()
    ##不裁剪shortcut之前的两个layer
    for i, module_def in enumerate(module_defs):
        if module_def['type'] == 'shortcut':
            ignore_idx.add(i-1)
            identity_idx = (i + int(module_def['from']))
            if module_defs[identity_idx]['type'] == 'convolutional':
                ignore_idx.add(identity_idx)
            elif module_defs[identity_idx]['type'] == 'shortcut':
                ignore_idx.add(identity_idx - 1)
    #上采样层前的卷积层不裁剪,yolov3的CBL_idx[-1]==104,可判断是否为yolov3-spp
    if CBL_idx[-1]==104:
        print('sparse: yolov3')
        ignore_idx.add(84)
        ignore_idx.add(96)
    else:
        print('sparse: yolov3-spp')
        #spp前后两层都不剪枝(77,84)
        ignore_idx.add(77)
        ignore_idx.add(84)
        ignore_idx.add(91)
        ignore_idx.add(103)

    prune_idx = [idx for idx in CBL_idx if idx not in ignore_idx]

    return CBL_idx, Conv_idx, prune_idx

layer-keep

channel keep percent per layer 0.01这个参数太小了把

bn_weights/hist

image

请问bn_weights要训练到多少代表稀疏化完全,看示例图中是300+epoch 值在0.2以下?

shape '[512, 256, 3, 3]' is invalid for input of size 357392

你好, 我训练自己的数据,经过基础训练,稀疏训练, 和shortcut_prune剪枝, tensorboard 和 剪枝结果都是正常的, 但是最后我用剪枝后的权重跑detect.py 时候报错了,shape '[512, 256, 3, 3]' is invalid for input of size 357392.. 请问经过shortcut_prune剪枝之后得到的权重是否还要处理?...

RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one.

我在进行sparsity时,遇到了如下报错,请问是什么原因导致的呢?谢谢。
Error LOG:
Reading labels (14363 found, 0 missing, 9 empty for 14372 images): 100%|████████████████████████████████████████████| 14372/14372 [02:20<00:00, 102.01it/s]
Model Summary: 225 layers, 6.42767e+07 parameters, 6.42767e+07 gradients
Starting training for 120 epochs...

 Epoch   gpu_mem      GIoU       obj       cls     total      soft    rratio   targets  img_size

0%| | 0/450 [00:00<?, ?it/s]learning rate: 1e-06
0/119 6.96G 1.54 1.88 0.968 4.38 0 0 101 416: 100%|██████████████| 450/450 [06:35<00:00, 1.14it/s]
Class Images Targets P R mAP F1: 100%|██████████████████████████████████| 113/113 [02:52<00:00, 1.53s/it]
all 3.59e+03 1.01e+05 0.322 0.453 0.365 0.363

 Epoch   gpu_mem      GIoU       obj       cls     total      soft    rratio   targets  img_size

0%| | 0/450 [00:00<?, ?it/s]learning rate: 0.0011625
Traceback (most recent call last):
File "train.py", line 542, in
train() # train normally
File "train.py", line 348, in train
pred = model(imgs)
File "/devdata/liqm/Tools/miniconda3/lib/python3.7/site-packages/torch/nn/modules/module.py", line 541, in call
result = self.forward(*input, **kwargs)
File "/devdata/liqm/Tools/miniconda3/lib/python3.7/site-packages/torch/nn/parallel/distributed.py", line 459, in forward
self.reducer.prepare_for_backward([])
RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. This error indicates that your module has parameters that were not used in producing loss. You can enable unused parameter detection by (1) passing the keyword argument find_unused_parameters=True to torch.nn.parallel.DistributedDataParallel; (2) making sure all forward function outputs participate in calculating loss. If you already have done the above two steps, then the distributed data parallel module wasn't able to locate the output tensors in the return value of your module's forward function. Please include the loss function and the structure of the return value of forward of your module when reporting this issue (e.g. list, dict, iterable). (prepare_for_backward at /opt/conda/conda-bld/pytorch_1573049387353/work/torch/csrc/distributed/c10d/reducer.cpp:518)
frame #0: c10::Error::Error(c10::SourceLocation, std::string const&) + 0x47 (0x7f0d6836f687 in /devdata/liqm/Tools/miniconda3/lib/python3.7/site-packages/torch/lib/libc10.so)
frame #1: c10d::Reducer::prepare_for_backward(std::vector<torch::autograd::Variable, std::allocatortorch::autograd::Variable > const&) + 0x7b7 (0x7f0d6de68667 in /devdata/liqm/Tools/miniconda3/lib/python3.7/site-packages/torch/lib/libtorch_python.so)
frame #2: + 0x7cfca1 (0x7f0d6de56ca1 in /devdata/liqm/Tools/miniconda3/lib/python3.7/site-packages/torch/lib/libtorch_python.so)
frame #3: + 0x2065e6 (0x7f0d6d88d5e6 in /devdata/liqm/Tools/miniconda3/lib/python3.7/site-packages/torch/lib/libtorch_python.so)
frame #4: _PyMethodDef_RawFastCallKeywords + 0x254 (0x55be4fe14744 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #5: _PyCFunction_FastCallKeywords + 0x21 (0x55be4fe14861 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #6: _PyEval_EvalFrameDefault + 0x52f8 (0x55be4fe806e8 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #7: _PyEval_EvalCodeWithName + 0x2f9 (0x55be4fdc4539 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #8: _PyFunction_FastCallDict + 0x1d5 (0x55be4fdc5635 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #9: _PyObject_Call_Prepend + 0x63 (0x55be4fde3e53 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #10: PyObject_Call + 0x6e (0x55be4fdd6dbe in /devdata/liqm/Tools/miniconda3/bin/python)
frame #11: _PyEval_EvalFrameDefault + 0x1e42 (0x55be4fe7d232 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #12: _PyEval_EvalCodeWithName + 0x2f9 (0x55be4fdc4539 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #13: _PyFunction_FastCallDict + 0x1d5 (0x55be4fdc5635 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #14: _PyObject_Call_Prepend + 0x63 (0x55be4fde3e53 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #15: + 0x16ba3a (0x55be4fe1ba3a in /devdata/liqm/Tools/miniconda3/bin/python)
frame #16: _PyObject_FastCallKeywords + 0x49b (0x55be4fe1c8fb in /devdata/liqm/Tools/miniconda3/bin/python)
frame #17: _PyEval_EvalFrameDefault + 0x4a96 (0x55be4fe7fe86 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #18: _PyEval_EvalCodeWithName + 0xac9 (0x55be4fdc4d09 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #19: _PyFunction_FastCallKeywords + 0x387 (0x55be4fe13f57 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #20: _PyEval_EvalFrameDefault + 0x416 (0x55be4fe7b806 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #21: _PyEval_EvalCodeWithName + 0x2f9 (0x55be4fdc4539 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #22: PyEval_EvalCodeEx + 0x44 (0x55be4fdc5424 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #23: PyEval_EvalCode + 0x1c (0x55be4fdc544c in /devdata/liqm/Tools/miniconda3/bin/python)
frame #24: + 0x22ab74 (0x55be4fedab74 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #25: PyRun_FileExFlags + 0xa1 (0x55be4fee4eb1 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #26: PyRun_SimpleFileExFlags + 0x1c3 (0x55be4fee50a3 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #27: + 0x236195 (0x55be4fee6195 in /devdata/liqm/Tools/miniconda3/bin/python)
frame #28: _Py_UnixMain + 0x3c (0x55be4fee62bc in /devdata/liqm/Tools/miniconda3/bin/python)
frame #29: __libc_start_main + 0xf0 (0x7f0d71697830 in /lib/x86_64-linux-gnu/libc.so.6)
frame #30: + 0x1db062 (0x55be4fe8b062 in /devdata/liqm/Tools/miniconda3/bin/python)

为什么prune.py跑出的map和之前train顺便跑出来的不一样?

train里的精度
image
prune显示的精度,p下降了好多。

image
+------------+----------+----------+
| Metric | Before | After |
+------------+----------+----------+
| mAP | 0.882270 | 0.881940 |
| Parameters | 61523734 | 7517869 |
| Inference | 0.0431 | 0.0219 |
+------------+----------+----------+

yolov3-spp-pan-scale.cfg

想问一下,目前项目支持yolov3和yolov3-spp。如何修改使用yolov3-spp-pan-scale.cfg? 基础训练和稀疏训练可以支持yolov3-spp-pan-scale.cfg,在层和通道剪枝运行layer_channel_prune.py 时AttributeError: 'NoneType' object has no attribute 'reshape',如何修改这部分剪枝代码?

训练结束后,程序无法退出的问题

作者您好,我制作了一个很小的数据集,尝试把程序跑通,运行了如下指令:
python train.py --cfg cfg/yolov3-nameplate.cfg --data data/nameplate.data --weights weights/darknet53.conv.74 --epochs 2 --batch-size 4
训练过程正常(checkpoint、TensorBoard都正常),但程序运行到最后无法退出,不知道是什么问题?
我在windows cpu环境下跑的,pytorch1.3,训练集16张图,测试集4张图

which anchor match the groudtruth box?

hello ,author,i use your code to detect the object but occur some problems ,there are two box arround head and cant deal with it by nms。
i want to detect person hand head 。 i think groudtruth match the anchor which has largest IOU with groudtruth between different yolo layer ,the code may do this by matching the groudtruth with anchor in every yolo layer and this make some problem in the detection result,hope answer,thx。

源码实现有问题啊?

torch安装需要python64位,但是报错OSError: [WinError 193] %1 不是有效的 Win32 应用程序。
改正32位的python版本,torch又会报错,报错为找不到torch._C

激活值的特殊处理

在prune_utils.py中,对激活值的处理中,这一句next_bn.running_mean.data.sub_(offset),这里为什么用的是sub,这里有点不明白?running_mean不应该是对数据统计的均值吗?

剪枝时FileNotFoundError: [Errno 2] No such file or directory: '/prune_0.15_keep_0.01_3_shortcut_usr/prune_0.15_keep_0.01_3_shortcut_cx/prune_0.15_keep_0.01_3_shortcut_darknetalexeyAB/prune_0.15_keep_0.01_3_shortcut_darknet-master/prune_0.15_keep_0.01_3_shortcut_names_data/prune_0.15_keep_0.01_3_shortcut_yolo-obj.cfg

剪枝命令:
python layer_channel_prune.py --cfg /usr/cx/darknetalexeyAB/darknet-master/names_data/yolo-obj.cfg --data /usr/cx/darknetalexeyAB/darknet-master/names_data/voc.data --weights weights/best.pt --global_percent 0.85 --layer_keep 0.01 --shortcuts 16

FileNotFoundError: [Errno 2] No such file or directory: '/prune_0.15_keep_0.01_3_shortcut_usr/prune_0.15_keep_0.01_3_shortcut_cx/prune_0.15_keep_0.01_3_shortcut_darknetalexeyAB/prune_0.15_keep_0.01_3_shortcut_darknet-master/prune_0.15_keep_0.01_3_shortcut_names_data/prune_0.15_keep_0.01_3_shortcut_yolo-obj.cfg

通道剪枝错误, get_mask2 未找到..

 Epoch   gpu_mem      GIoU       obj       cls     total      soft   targets  img_size

0%| | 0/309 [00:00<?, ?it/s]Traceback (most recent call last):
File "train.py", line 534, in
train() # train normally
File "train.py", line 313, in train
idx2mask = get_mask2(model, prune_idx, 0.95)
NameError: name 'get_mask2' is not defined
0%| | 0/309 [00:00<?, ?it/s]
请问是不是 命名有问题?
我改成 get_mask之后也报错

这种剪枝只对单目标检测有效?

用官方yolo跑的自己数据集香烟和手机的目标检测,mAp大概在70多
然后进行稀疏训练,第一个epoch的mAp就变成0了?
请问是不是只对单目标检测效果较好啊?

请教下关于VOC数据集稀疏化训练的问题

VOC数据集稀疏化训练map很低,使用的yolov3.weights,训练100步map只有10几,loss也在震荡,是不是稀疏化训练只适合单一目标,例如:手的数据集

在不用稀疏化训练时,就能保证很高的map,大佬请教下

IndexError: index -1 is out of bounds for axis 0 with size 0

训练自己的数据集,同样的配置在darknet下面可以正常训练,但使用本项目跑完一轮就报错
Corrupt JPEG data: 2 extraneous bytes before marker 0xd9
0/99 8.39G 1.26 1.18 8.95 11.4 0 162 416: 100%|████████████████████████████████████████████████████████████████████████████| 1228/1228 [07:18<00:00, 2.80it/s]
Traceback (most recent call last):
File "train.py", line 527, in
train() # train normally
File "train.py", line 404, in train
save_json=final_epoch and epoch > 0 and 'coco.data' in data)
File "/home/work/deep_learning/yolov3-channel-and-layer-pruning/test.py", line 50, in test
dataset = LoadImagesAndLabels(test_path, img_size, batch_size)
File "/home/work/deep_learning/yolov3-channel-and-layer-pruning/utils/datasets.py", line 270, in init
nb = bi[-1] + 1 # number of batches
IndexError: index -1 is out of bounds for axis 0 with size 0
进入报错位置,打印了n和bi的值,分别为0和[]
请问有人碰到过吗

local variable 'labels' referenced before assignment

你好, 为什么 我运行时 会报这个错误
img, labels = load_mosaic(self, index)
File "O:\Deep_Learning\Dataset\YOLOv3\yolov3-channel-and-layer-pruning-master\utils\datasets.py", line 607, in load_mosaic
labels4.append(labels)
UnboundLocalError: local variable 'labels' referenced before assignment

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.