各位参赛的小伙伴们,你们模型都训好了吗?都用的什么呀?现在都多少分了呀?带着这几天踩坑经历,挥泪记录一下(踩坑过程中多谢另一位参赛者的帮助和交流,帮助我少走了不少弯路,这里暂不透露该参赛者姓名)
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. 蒸馏训练
蒸馏训练在这里应该是非常的难了(至少我研究了好久),而且配置起来也相当的复杂,代码改动量也是相当的大,这里先不描述了。。。等我有了效果再来更新。
【踩坑未完,待续......】
anns = coco_api.loadAnns(annIds)
如果读取的是annotations那就只有81个类了,就像demo的reader那样,因为category_id就是子类id,里面有个categories描述了对应的父类和父类的名字
映射是按照81类映射的,但是读出去的时候是按照的91类,训练时候还是要处理一步,以防止出错。github上官方曾给出答复,ssd分支只支持91类,所以需要自行修改。具体有多大的影响,我还没有测试。
训练肯定是要训练所有图片呀,所以读取是要91个类的图片,比如张图里有主分类和子分类,不可能你把主分类图扣掉传人网络呀,只是在网络训练损失的时候y值一定要映射到81类的onehot这样才能学到81类的模型吧
score.py里有几行是把81类映射回91类的,实际上不是类别多少的问题,都是81类,而是coco的id号是不连续的,训练时要把不连续的id映射成连续的id,评测的时候为了调用coco的API又要把id变为不连续的
基线模型可以拿来直接预测吗
赛题说明里是:包括boundingbox([x0,y0,x1,y1])、类别信息和分数。到底以哪个为准呢?
同问
来来来大家一起把坑填好。
请问数据集没有问题吗?在aistudio上的数据集创建的项目为什么解压出来跟说明的不一样?好像是之前的
https://aistudio.baidu.com/aistudio/datasetdetail/7122
在这个上面创建项目后解压出来是有 person——keypoint什么的…………
不知道为什么加载 pretrained_model 之后,训练着训练着 loss 就 Nan 了,然后看了一下记录,最好的 test map 是 0.3 左右,但实际测试只有 0.02。。。reader.py 已经将类别转成 81 类了
有人遇到类似问题吗
这个真没发
目前没哟遇到这个情况
有个问题想请教一下大家~
经过剪枝+量化保存后的模型,能够测出mAP,但是在计算参数量的时候会出错,请问有人遇到过吗?
报错的意思好像是,剪枝去掉了部分卷积核,导致实际生成的下一步特征图的通道数,与原本应生成的特征图的通道数不一致。
去掉 assert c_out == c_out_, 'shape error!' 以后,可以正常计算得分,但是服务器上的评测工具没法改呀~
我现在改怎么办呢?
麻烦问下reader.py里面怎么修改成81类啊,看了链接GIT上的 没太看懂
谢谢这些坑 哈哈
这个问题其实是比较典型的,原因是你做了剪枝之后,模型权重的保存已经按照新的维度进行了,但是_model_文件下的网络结构还是未剪裁的,所以提交到score中就会出错。建议你把剪枝后的模型结构打印出来,然后重新生成一个符合结构的_model_文件,这样就不会出问题了。
回答的真专业
看看