点击下方卡片,关注「AI计算机视觉CV深度学习DL」公众号
选择星标,最新技术干货每日准时送达
AI|图像处理|计算机视觉CV|机器学习ML|深度学习DL
前言
科研中经常需要面对的问题是,针对同一个任务,需要同时使用多个模型做多种实验,并在同一个模型上进行多种尝试,在这一过程中,如果不注意管理,就会越来越乱。。。
整理自丨知乎
链接丨https://www.zhihu.com/question/269707221
问题:深度学习科研,如何高效进行代码和实验管理?
深度学习模型结构变化程度大,参数多,如何高效的进行代码和实验管理?可能的方面有:
-
代码包 -
目录创建原则 -
优秀的管理软件 -
好的个人习惯等
回答1
我之前在北美奔驰落地时,曾有段时间为了测试不同的结构和参数,一周能训练一百来个不同的模型,为此我结合公司前辈们的做法和自己的一点思考总结了一套高效的代码实验管理方法,成功帮助了项目落地, 现在在这里分享给大家。
使用Yaml文件来配置训练参数
我知道很多开源repo喜欢用import argparse来传输一大堆训练和模型相关的参数,其实非常不高效。一方面,你每次训练都需要手动输入大量参数会很麻烦,如果直接改默认值又要跑到代码里去改,会浪费很多时间。这里我推荐大家直接使用一个Yaml file来控制所有模型和训练相关的参数,并将该yaml的命名与模型名字和时间戳联系起来。
我从上方给的链接截了该yaml文件部分内容,如下图所示,这个配置文件涵盖了如何预处理点云,classification的种类,还有backbone各方面的参数、optimzer和loss的选择(图中未展示,完整请看上方链接)。也就是说,基本所有能影响你模型的因素,都被涵括在了这个文件里,而在代码中,你只需要用一个简单的 yaml.load()就能把这些参数全部读到一个dict里。更关键的是,这个配置文件可以随着你的checkpoint一起被存到相同的文件夹,方便你直接拿来做断点训练、finetune或者直接做测试,用来做测试时你也可以很方便把结果和对应的参数对上。
代码模块化非常重要
有些研究人员写代码时喜欢把整个系统写的过于耦合,比如把loss function和模型写到一起,这就会经常导致牵一发而动全身,你改动某一小块就会导致后面的接口也全变,所以代码模块化做的好,可以节省你许多时间。一般的深度学习代码基本可以分为这么几大块(以pytorch为例):I/O模块、预处理模块、可视化模块、模型主体(如果一个大模型包含子模型则应该另起class)、损失函数、后处理,并在训练或者测试脚本里串联起来。代码模块化的另一好处,就是方便你在yaml里去定义不同方面的参数,便于阅览。另外很多成熟代码里都会用到importlib神库,它可以允许你不把训练时用哪个模型或者哪个子模型在代码里定死,而是可以直接在yaml里定义。
Tensorboard, tqdm用起来
这两个库我基本上每次必用。Tensorboard可以很好的追踪你训练的loss曲线变化,方便你判断模型是否还在收敛、是否overfit,如果你是做图像相关,还可以把一些可视化结果放在上面。很多时候你只需要看看tensorboard的收敛状态就基本知道你这个模型怎么样,有没有必要花时间再单独测试、finetune. Tqdm则可以帮你很直观地跟踪你的训练进度,方便你做early stop.
记录实验结果
我一般会保存一个总的excel来记录实验结果,第一列是模型对应的yaml的路径,第二列是模型训练epoches, 第三列是测试结果的log, 我一般会把这个过程自动化,只要在测试脚本中给定总excel路径,利用pandas可以很轻松地搞定。
回答2
其实成熟的软件已经挺多了,包括Weights&Biases, MLFlow, Neptune等,解决实验管理以及其他问题,只需要添加几行代码就可以系统地区分和管理实验结果。个人版是免费的,很值得学习尝试。
自己的个人或者Lab环境的话,也可以选用开源library自己整合,推荐如下:
-
代码包: git是必须的,尽量用venv/conda管理virtual env,如果熟悉的话,docker也可以用上。 -
目录创建原则:尽量根据model backbone或者模型的任务分开,这样可以尽量复用代码同时保证一定的modularity;其余就可以根据dataset/models/logger/app分开。 -
优秀的管理软件:这里分为不同方面的管理了,目标可以定位可复现能力reproducibility。 -
参数管理:YAML针对简单情况,更复杂情况目前最优方案组合应该是Hydra+OmegaConf。 -
实验管理:MLFlow/WandB/TensorBoard。 -
版本管理(包括数据集/checkpoint):git+DVC+CML等。 -
依赖包管理:pip/conda/docker。
好的个人习惯: 比较宽泛了,能想到的是:
-
用好git, venv等; -
处理好实验的random seed; -
用好IDE;可以使用tmux避免一些实验错误中断; -
用好logger, debug mode和运行训练分开成不同mode,快速切换; -
使用实验管理软件同时,使用spreadsheet记录好实验结果;可以根据模型/数据集/模型版本/模型参数/超参数这样的结构管理实验结果; -
可以多注意dataloader的效率,或许num_workers修改就可以加速不少;
回答3
代码管理一定是要用 github 的。学生可以申请学生大礼包。
实验一定要有报告,要带有所用代码的 commit id (SHA1 hash value),如果数据不多,可以直接把数据塞进来,做一个submodule或者单独的repo(单独的话也得记录预处理过的数据的commit id)。报告主要是记得每个实验的目的,方法,和结果。实验做多了,忘了做哪个实验,或者忘了实验的目的是什么的,比比皆是。
其实,最好论文、报告使用overleaf,写作工具是 latex,然后可以与 github repo或者本地 git repo 同步。这样,论文进度、实验进度、定期汇报、代码版本、数据,都有了统一的版本管理。具体根据情况,可以用 submodule,也可以就是分开几个 repo。
论文、报告中的图表,尽量使用自动生成的(有点类似函数式编程的概念)。当然,实验太漫长的还是没办法。这个实现,可以使用 R 系的 knitr 实现,也可以简单的,实验代码(Matlab 或者Python)输出 csv,绘图或者列表直接使用 latex 去读取。优点是,实验确保能够重复。同时,数据更新后,报告和论文直接重新编译,也跟着一起更新了。不推荐在实验代码中嵌入绘图输出,前端展示与后端计算,还是分离比较合适。这样不会遇到图片分辨率不够高的问题。同时图片和表格 也容易根据环境调整。
当然,latex 本身支持 input 和 include,还有功能更强大的 import包,可以充分利用。可以复用 一些写过的小段。
参考文献,如果中文的比较少,就还是推荐 mendeley,毕竟被 elsevier 收了,还主导了开源 ref的标准,然后 bib 可以直接同步到 overleaf。如果中文比较多,那还是得用 noteexpress。
—THE END—
一个专注于开放知识分享的公众号,努力将分享变成一种习惯!
后台回复「加群」加入互助群,可在公众号【菜单】中获取完整关键词清单。
回复:图像处理丨计算机视觉丨机器学习丨深度学习丨Python丨C/C++丨PyTorch丨CVPR2024丨ECCV2024 获取相应资料(不定期更新)。
点这里👇关注我,记得标星哦~
文章仅做学术分享,如有侵权请联系删除,非常感谢!

