2019百度之星之各种踩坑
收藏
快速回复
2019百度之星之各种踩坑
收藏
快速回复

各位参赛的小伙伴们,你们模型都训好了吗?都用的什么呀?现在都多少分了呀?带着这几天踩坑经历,挥泪记录一下(踩坑过程中多谢另一位参赛者的帮助和交流,帮助我少走了不少弯路,这里暂不透露该参赛者姓名)

1. SSD分支?YoloV3分支?还是PaddleDetection?

    我前几天写过一个关于到底用PaddleDetection里面哪个框架的帖子。然而,在真正搞起来之后,我才发现我真的是太naive了...首先PaddleDetection封装的过于复杂,不利于改动,初学者看的话真的是一头雾水;这时SSD和YoloV3的分支显得友好许多,至少很多东西修改起来得心应手,没有那么多封装。由于YoloV3模型较大,所以...最终我还是选择了官方推荐的SSD。而且baseline_model用的也是SSD,大家可以用这个分支验证一下。

2. 竟然全是SSD的预处理?难怪官方推荐SSD

   有一定经验的小伙伴一定会很快就发现,测评工具score.py里面的数据预处理默认就是SSD的那一套,300x300,均值127.5。所以,使用其他框架的小伙伴一定要注意,预处理要一致,否则本地验证一时爽,先上测评....我就不多说了。

3. COCO到底有多少类?91 or 81?

   如果你使用PaddleDetection,你会发现它和score.py一样,都是81类:80类目标和1类背景。但是如果你用SSD这个分支,会发现,怎么是91类呢?这不对啊。解释如下:COCO除去背景确实有90类,但是这90类分为了两个level,其中80类相当于子类,就是我们经常训练的,另外10类为父类,是包含那80类的。所以在使用SSD分支时,一定要在reader那里将10个父类去掉,否则结果会不正确的。具体修改方法可以参见:https://github.com/PaddlePaddle/models/blob/develop/PaddleCV/PaddleDetection/ppdet/data/source/coco_loader.py

4. 训练好的模型怎么在score中无法加载呢?_model_ 这个文件在哪里?

   如果你将train完的model直接丢进score中,一定会报错的,这是因为train保存的是vars,而我们最终要提交的模型是inference,而且也只有在inference中才会有_model_这个文件。所以呢,写个脚本,把模型load进来,再存成inference。

5. 模型能加载了,可视为什么结果不对呀?或者计算score时出错?

   这个问题就更有意思了,不论使用PaddleDetection、SSD、还是YOLO,直接存成inference都不行,为什么呢?详见本次比赛提交格式说明:【模型的输出包含bbox、score和background_label】等等等,然后思考一下如何来存inference吧。

6. 想自己搞点新模型怎么办?

   很多期待拿好成绩的参赛者都会想要复现一些最近比较好的模型,这是在所难免的,但同时带来的问题就是,预训练模型没有怎么办。这几天我测了两个模型(模型保密,哈哈),预训练是我自己在imagenet上做的,top1在0.65-0.68左右。同样使用两块1070Ti显卡,在coco2017上同样训练30epochs,有预训练的模型map达到了0.15,而没有预训练的只有0.13多点。从这个角度简单看一下,如果真要想自己搞点事情,最好还是在imagenet上训一波,然后再拿过来训练检测网络比较好。

7. 量化训练

   关于使用compressor进行量化训练的问题,官方提供了demo【https://aistudio.baidu.com/aistudio/projectdetail/86232】,小伙伴们可以去参考一下。不过在我使用量化脚本训练时,我并没有使用compressor,而是使用了量化的low api,这样做主要是能够更加方便的调试,也可以更加直观的把控训练情况。PS. 有小伙伴说量化训练训着训着就nan的事儿,我确实也遇到过,而且概率还不低,这个情况是谁的锅现在还无法确定。

8. 剪枝训练

   相比于量化的巨大收益,剪枝也是不甘示弱的。我这里使用的是compressor进行的剪枝训练,我设定了0.4的剪枝比例,成功地将madds降低了40%,这一点paddle做的还是不错的。不过剪枝训练加保存模型这里有很多的坑,小伙伴们可要注意了。继续说剪枝,我使用剪枝训练了15个epochs,map降低了0.014,madds降低了40%,其实最终计算,整体收益并不是很大。也许再多训一些可能会提升吧,也有可能剪枝对于检测网来说没有backbone那样稳定,who knows。

9. 蒸馏训练

  蒸馏训练在这里应该是非常的难了(至少我研究了好久),而且配置起来也相当的复杂,代码改动量也是相当的大,这里先不描述了。。。等我有了效果再来更新。

【踩坑未完,待续......】

 

10
收藏
回复
全部评论(38)
时间顺序
AngleKing.Yang
#22 回复于2019-08

anns = coco_api.loadAnns(annIds)

如果读取的是annotations那就只有81个类了,就像demo的reader那样,因为category_id就是子类id,里面有个categories描述了对应的父类和父类的名字

0
回复
Seigato
#23 回复于2019-08
anns = coco_api.loadAnns(annIds) 如果读取的是annotations那就只有81个类了,就像demo的reader那样,因为category_id就是子类id,里面有个categories描述了对应的父类和父类的名字
展开

映射是按照81类映射的,但是读出去的时候是按照的91类,训练时候还是要处理一步,以防止出错。github上官方曾给出答复,ssd分支只支持91类,所以需要自行修改。具体有多大的影响,我还没有测试。

0
回复
AngleKing.Yang
#24 回复于2019-08
Seigato #23
映射是按照81类映射的,但是读出去的时候是按照的91类,训练时候还是要处理一步,以防止出错。github上官方曾给出答复,ssd分支只支持91类,所以需要自行修改。具体有多大的影响,我还没有测试。

训练肯定是要训练所有图片呀,所以读取是要91个类的图片,比如张图里有主分类和子分类,不可能你把主分类图扣掉传人网络呀,只是在网络训练损失的时候y值一定要映射到81类的onehot这样才能学到81类的模型吧

1
回复
小青年CAI
#25 回复于2019-08
训练肯定是要训练所有图片呀,所以读取是要91个类的图片,比如张图里有主分类和子分类,不可能你把主分类图扣掉传人网络呀,只是在网络训练损失的时候y值一定要映射到81类的onehot这样才能学到81类的模型吧
展开

score.py里有几行是把81类映射回91类的,实际上不是类别多少的问题,都是81类,而是coco的id号是不连续的,训练时要把不连续的id映射成连续的id,评测的时候为了调用coco的API又要把id变为不连续的

0
回复
w
wangwei8638
#26 回复于2019-08

基线模型可以拿来直接预测吗

0
回复
w
wangwei8638
#27 回复于2019-08

赛题说明里是:包括boundingbox([x0,y0,x1,y1])、类别信息和分数。到底以哪个为准呢?

0
回复
w
wangwei8638
#28 回复于2019-08
求教保存inference的api中,`fluid.io.save_inference_model`里面`feeded_var_names`和`target_vars`这两个参数应该如何设置~

同问

0
回复
r
rose20135188
#29 回复于2019-08

来来来大家一起把坑填好。

0
回复
i
invincible0o0
#30 回复于2019-08

请问数据集没有问题吗?在aistudio上的数据集创建的项目为什么解压出来跟说明的不一样?好像是之前的

https://aistudio.baidu.com/aistudio/datasetdetail/7122

在这个上面创建项目后解压出来是有 person——keypoint什么的…………

0
回复
598127577
#31 回复于2019-08

不知道为什么加载 pretrained_model 之后,训练着训练着 loss 就 Nan 了,然后看了一下记录,最好的 test map 是 0.3 左右,但实际测试只有 0.02。。。reader.py 已经将类别转成 81 类了

有人遇到类似问题吗

0
回复
l
liguanghui2588
#32 回复于2019-08
请问数据集没有问题吗?在aistudio上的数据集创建的项目为什么解压出来跟说明的不一样?好像是之前的 https://aistudio.baidu.com/aistudio/datasetdetail/7122 在这个上面创建项目后解压出来是有 person——keypoint什么的…………
展开

这个真没发

0
回复
r
rose20135188
#33 回复于2019-08
598127577 #31
不知道为什么加载 pretrained_model 之后,训练着训练着 loss 就 Nan 了,然后看了一下记录,最好的 test map 是 0.3 左右,但实际测试只有 0.02。。。reader.py 已经将类别转成 81 类了 有人遇到类似问题吗
展开

目前没哟遇到这个情况

0
回复
欧耶我是废物
#34 回复于2019-08

有个问题想请教一下大家~

经过剪枝+量化保存后的模型,能够测出mAP,但是在计算参数量的时候会出错,请问有人遇到过吗?

报错的意思好像是,剪枝去掉了部分卷积核,导致实际生成的下一步特征图的通道数,与原本应生成的特征图的通道数不一致。

去掉 assert c_out == c_out_, 'shape error!' 以后,可以正常计算得分,但是服务器上的评测工具没法改呀~

我现在改怎么办呢?

0
回复
张呓语
#35 回复于2019-08
598127577 #31
不知道为什么加载 pretrained_model 之后,训练着训练着 loss 就 Nan 了,然后看了一下记录,最好的 test map 是 0.3 左右,但实际测试只有 0.02。。。reader.py 已经将类别转成 81 类了 有人遇到类似问题吗
展开

麻烦问下reader.py里面怎么修改成81类啊,看了链接GIT上的 没太看懂

0
回复
大手拉小手0123
#36 回复于2019-09

谢谢这些坑 哈哈

0
回复
Seigato
#37 回复于2019-09
有个问题想请教一下大家~ 经过剪枝+量化保存后的模型,能够测出mAP,但是在计算参数量的时候会出错,请问有人遇到过吗? 报错的意思好像是,剪枝去掉了部分卷积核,导致实际生成的下一步特征图的通道数,与原本应生成的特征图的通道数不一致。 去掉 assert c_out == c_out_, 'shape error!' 以后,可以正常计算得分,但是服务器上的评测工具没法改呀~ 我现在改怎么办呢?
展开

这个问题其实是比较典型的,原因是你做了剪枝之后,模型权重的保存已经按照新的维度进行了,但是_model_文件下的网络结构还是未剪裁的,所以提交到score中就会出错。建议你把剪枝后的模型结构打印出来,然后重新生成一个符合结构的_model_文件,这样就不会出问题了。

0
回复
大手拉小手0123
#38 回复于2019-09
Seigato #37
这个问题其实是比较典型的,原因是你做了剪枝之后,模型权重的保存已经按照新的维度进行了,但是_model_文件下的网络结构还是未剪裁的,所以提交到score中就会出错。建议你把剪枝后的模型结构打印出来,然后重新生成一个符合结构的_model_文件,这样就不会出问题了。
展开

回答的真专业

0
回复
l
luckyToMe2
#39 回复于2020-01

看看

0
回复
在@后输入用户全名并按空格结束,可艾特全站任一用户