极市导读
本文总结了作者自身炼丹过程中的一些经验,包括了一些方法论以及技巧,帮助小白正确入坑。 >>加入极市CV技术交流群,走在计算机视觉的最前沿
炼丹入坑三年多,来总结一些经验,本文旨在帮助小白少走弯路,大佬轻喷:
本文源于一个旧回答:你有哪些deep learning(rnn、cnn)调参的经验?(https://www.zhihu.com/question/41631631/answer/859040970)我的工作可以参见 我的 Github(https://github.com/hzwer),一股浓浓调参风,所以感觉能来说点小经验。另,旷视研究院目前在春招实习生,欢迎大家投递。
大部分情况下,我们的工作应该站在巨人的肩膀上,切忌空中楼阁和徒手造轮子。在实践中建议琢磨以下两问:a. 目前的问题是否可能用神经网络学习?b. 是否有人做过类似的工作?
a. 即使有数据,神经网络不是万能求解器。在视觉任务中的经验规律是,神经网络的水平普遍高于普通人,弱于专家。理解“不能被神经网络学习”的任务比较困难,通常可以把问题做分解和规约。举例,因为神经网络可以做图片一千类别分类,那么训练分类器分类一个人有没有戴口罩很可行;因为让神经网络生成一张高分辨率图片比较难,所以让神经网络端到端生成抖音短视频会非常难。
b. 最令人心态崩溃的事情有:开始写了一半论文才发现别人早就发表过了;搞了个把月的项目,不如人家 git clone 下来一键生成水平。通过文献调研和 paperswithcode,可以避免这类问题发生。有一个高的起点非常重要,做学校的课程项目时,同学们往往喜欢用一个很差的基准,跑一些不强的对比实验,但正经的研究工作,往往要从一个很强的基准开始着手改进。尽量不要在玩具级别的数据集或任务上做研究,比如 MNIST(有少数例外)。
以下总结了这几年对我影响较大的几个方法论。a. 可复现性。b. 高效实验。c. 防呆实验。
a. 有的朋友在炼丹的时候从头到尾只维护若干份代码,每次载入前一次的训练参数,改一下代码再炼,俗称 老丹 。这样会有很多问题:某次引入一个 bug,过了很久才发现,不知道影响范围;得到一个好模型,但是没人知道它是怎么来的;忘了自己的 baseline 长什么样,不知道改动是正向还是负向。
我们要尽可能确保每一个模型有可复现性,实践上建议固定随机种子,且不在训练过程中再改动训练代码。训练新的模型时,把旧的代码复制一遍。得到的实验结果要开个文档记下来以便日后总结,避免遗忘。后续总结回顾实验记录,往往能获得灵感。
b. 不是每一个实验都要出一个好模型, 实验是为了验证结论的 。如果每个实验都要 8 张卡跑两个星期,人力物力都耗不起。尽力把实验控制在单卡一天以内,理想状态是半天得一次结论。理论上来说,水多加面面多加水(加数据加计算量)的做法无限涨点。建议先设一个目标,比如说就是在半天的训练时间下做对比实验。等到实验比较成熟以后再做大实验。
我的实践经验是,优先选用小骨干网络 + 更小的输入,直到消除了大部分 bugs;用 cProfile 来找找性能瓶颈(训练工程写的不够好时,常常有一大半时间耗费数据传输,我曾经发现某个工程数据处理中一大半时间在调用 numpy 的 round 函数,还有某个工程大部分的时间开销在线程锁上),解决这些问题能让之后工作事半功倍。
c. 介绍几种经典的防呆实验。首先可以只拟合一张图片或者若干张图片来观察视觉效果,看看能不能正常过拟合。还可以把标签直接喂进网络中,看看网络是否能够快速学到 trivial 解。在训练过程中绘制训练集和验证集的损失函数曲线,看是否有合理的 gap。
不迷信调参,如果发现一个模型对各种超参数都非常敏感,每天在各种组合上试的不亦乐乎,通常是有地方出了问题,包括测试脚本写错,任务定义不合理,数据太脏等。举个例子,以前大家会非常注意一些细节,比如模型初始化,输入归一化等,原因是当时各种框架和算法实现不成熟。现在的框架通常在这些细节上都默认是比较鲁棒的设置,不建议特别关注。
我个人的经验是,优化器用 AdamW(少数地方用 SGD with Momentum),学习率推荐 cosine learning rate,初始值选 3e-4(SGD 可以选 0.1),激活函数选 PReLU。Batchsize 取 64,尽量用多卡,如果用 torch 的话记得用 DistributedDataParallel。用上这些基本不出错,唯一比较玄学的是 BatchNormalization,有的任务上用了就是会变差(比如超分辨率,光流估计),有的任务不用 BatchNormalization 就是不好调。不要迷信公众号的“即插即用”方法,各种魔改优化器、激活函数、魔幻注意力不建议碰(除非研究这个),尽量用大量研究者验证过的方法。
如果感觉模型依然有 bugs,建议检查以下几条。a. 检查模型是否正确开关了 eval 和 train 模式。b. 检查模型每个模块的输入输出范围是否符合预期。c. 可视化带增广的训练数据,看看是否符合预期(顺便提一下 imgaug,这个开源库用来做数据增广性能很好,不容易踩坑)。
祝读到这里的各位模型涨点!
参考文献
公众号后台回复“项目实践”获取50+CV项目实践机会~
“
点击阅读原文进入CV社区
收获更多技术干货