Ylisar 发表于 2022-1-1 14:09

复现算法的踩坑总结

参考文章:
文章作者博客:
目录:

一、熟悉数据
二、算法选型
三、基于已有实现来优化算法
四、一些有用的训练建议
一、熟悉数据

对于一个新任务,第一件事是需要熟悉数据。拿检测任务来说,可以写个可视化代码查看标注是否合理,查看一下待检测物体的大小分布情况(例如anchor的预设),查看一下图片大小,查看类别分布情况(例如是否有极端的分布)等等。如果有需要,要对数据集进行一系列的预处理。
二、算法选型

接触新领域、新任务后,首先需要调研相关领域算法,对该领域的发展有个大概的了解,掌握一些关键算法(比如历年的SOTA)的思路。
虽然调研需要花费一些时间,但是这样在算法选型上可以少做一些实验,性价比是很高的。站在他们的肩膀上就好了。
一些不可取的思路:
1、在指标上钻牛角尖。
指标在自己数据集效果不太好的情况时,立马换别的算法,或者立马换个backbone,或者立马换个loss去做实验。需要认真分析为什么效果不好,是自己训练有问题,还是当前数据不太适合该算法,是评测指标不合理,还是评测指标实现有问题。
2、不进行相关调研,直接上SOTA算法。
这样做会有一些不太理想的问题,比如SOTA可能没有针对自己场景的数据做优化,比如当前任务是小目标居多(通过分析数据得到),虽然SOTA的总的mAP很高,但是small mAP比之前算法还低,那就要慎用 。比如SOTA用的是很重的网络,但是任务是速度快,或者速度与效果兼顾,那也应该慎用。(可以基于SOTA针对自己场景的数据进行改进。)三、基于已有实现来优化算法

对于某个任务在选择好合适的算法以后,如果有相应的效果比较好的开源实现,最好用开源项目进行算法的复现。
这样做的原因:
1、更方便深入的理解算法的具体细节。
比如可能代码在文章没有提到的某些层上偷摸的加了一个shift操作,比如文章提到的一些trick代码根本没有实现,比如代码用了额外的数据训练但文章没有提到,比如文章描述的数据增强方式与代码的实现不一样等。(这些可能发生在开源复现者没有“一比一”复现论文的情况,也可能发生在论文作者自己没有实现的情况)
2、能快速掌握算法的基础性能。
比如复现算法大概的运行速度(特别是文章没给出的时候)和达到的效果。
3、不用自己做一些无用功。
重写和调试一份新的模型不仅费时费力,可能还因为文章没有写清楚一些细节,导致你几乎无法复现到相应的结果。基于已有算法改进的思路:
1、代码是否实现了文章一些涨点的trick,如果没有可以尝试。
2、文章一般会分析实验结果,后面会有作者自己的一些观点,他们可能会说明为什么有些情况文章的算法效果较差。
3、有些文章会写他们将来可能的工作,这也是一个改进思路。
4、需要可视化查看实验结果(特别是跑自己的数据集),结果可能与作者在公开数据集展示出的问题不一样,分析效果差的原因。四、一些有用的训练建议

1、保证数据是可靠的。
2、有预训练模型最好用上。
3、通常学习率参数小于1e-5基本没啥用了,比如cosine或者step操作,最后的学习率到1e-5就好了。当然特殊任务不一样。
4、bn在训练时记得打开更新(特别是tf的小伙伴,容易漏),不然可能出现的问题是训练时loss下降很快,测试感觉模型就没收敛。
5、sgd是很棒的,但是实验用adam或许收敛速度更好。
6、如果想要很好的压榨出一个算法的性能,请先保证当前模型能到达相应的性能再去压榨。而不是盲目的换模块,疯狂调参,那样可能只是浪费时间。
7、不要太相信自己的调参技术,在没有一个较好的baseline情况下,调参不会有质的飞跃(除非是之前参数造成了某种bug)。
8、数据小时,使用了预训练模型记得固定前几层的模型参数,还可以用小点的学习率。
9、loss balance有时候很有用。
10、重复训练可能可以提升点数,将一个模型训练好后,用训练好的模型做预训练模型载入,继续用同一套参数训练。有点像CyclicLR。
11、DL没有像机器学习有那么多公式支撑,很多都是make sense就做个实验来验证,所以尽量多阅读论文,看看别人的实验,这样就可以减少不必要的实验。

pc8888888 发表于 2022-1-1 14:18

很有道理

stonstad 发表于 2022-1-1 14:28

loss balance是啥?
页: [1]
查看完整版本: 复现算法的踩坑总结