Research
- 参考《CogVideo: Large-scale Pretraining for Text-to-Video Generation via Transformers》,用 Anonymous GitHub 发布匿名代码仓,可能是用于审稿时交代码验证。
- paper with code 查 state-of-the-art(SOTA):Browse State-of-the-Art。
- Hugging Face 找预训练模型参数,尤其一些没有对应文章、但可能已经很多人用的改进模型,如 runwayml/stable-diffusion-v1-5。
- 彭思达的经验:pengsida/learning_research,尤其是《如何找到实验不work的原因》;公开课:GAMES003-图形视觉科研基本素养。
- 一个教如何科研的免费短课:科研加速计划2.0。
- 韩晓光老师的分享:科研那些事。
- GAMES 好导师在线:《好导师在线》第一期-导师彭思达,李冠彬, 主持:韩晓光
- 开完组会之后,把后续实验思路重新捋一次,重新组织语言写成文档,预期输出、实验目的也写上,再发出来跟导师 / 合作者对一次,防止无效实验。中途有改变的,也及时提出,把差异直接体现在文档中方便别人(和过两天之后忘记细节的自己)看懂。
- 参考顶会的审稿意见,帮助建立科研价值观:iTomxy/openreview。
- 用 Connected Papers 找相关重要文章,参考《connected papers 让注册,怎么办呢》。
- 可在 arXiv 某篇文章的 TeX 源码中学习其 LaTeX 技巧,如排版、有意思的符号等。
- 及时反馈,无论是对带你的人(导师、前辈)还是对自己。其中一个表现是及时出结论,比如:
- 将 idea 形成初版(粗糙的)故事(场景,挑战、卖点列表)、实验方案,就再次小讨论、调整,再实施;
- 跑实验前预想可能的结果,分别意味着什么(能得什么结论),用 ppt / markdown 记下,等结果出来再补结论;
- 跑实验如果两天都没跑完,要测中间结果(checkpoint)、看 loss 曲线等;或先用小模型、小数据集用 overfit(training set = validation set = test set)测试实验方案作为初步、快速验证,能 work 再 scal。
- 学术会议交际建议:Tips on How to Connect at Academic Conferences(汉译:i人如何在学术会议有效社交?滑铁卢大学教授Gautam Kamath亲授心得)。
- 期刊 cover letter 署 corresponding author 的名。老板说信尾签名那不用放手写签名图,太正规。
- 配色:中国色、中國傳統色彩
- 期刊审稿、返修时要交的文件可能不同,如返修可能要加收 .tex 和 .bib 文件、Credit Author Statements。所以要提前过一次交稿流程,看这次要交哪些文件。交稿系统(如 Editorial Manager)可能只准 correspond author(很可能是导师)操作投稿流程,自己没法操作。
- 提前看好交稿限期(精确到小时)、时区:1) 换成 UTC 方便算出交稿系统与本地时间的时差;2) 注意冬、夏令时,可能在时区时差之外引起另一时差;3) 校日程、闹钟提醒。
- 一些 LaTeX 公具、模板:iTomxy/ml-template/latex。
Programming / Experiment
- 记结果记得舍入,如 numpy.ndarray 用
round
,或者 pandas.DataFrame.to_excel 写入 excel 时指定float_format
,参考:pandas写excel简例。 - (参考 mmdetection)命令行参数、配置文件可以备份一份到 log 目录。
- python 显示进度除了用 tqdm、手写进度条,如果只是想打点东西,确保程序不是在卡住,也可以简单利用
\r
实现,如:for i, data in enumerate(dataloader): print(i, end='\r') # 就不会一直换行刷爆终端 # do something ...
- (续 training/1)续断不仅限于 training,其它如数据处理、下载也可以加:
- 如输出是文件夹,可以用临时文件夹(如加后缀
.tmp
),处理完再改名。这样程序意外停掉要重新运行时,就可以略过已经存在的文件夹; - 输出是文件也类似。
- 如输出是文件夹,可以用临时文件夹(如加后缀
- 及时手动释放显存,即
del
+ torch.cuda.empty_cache() 有用。试过跑生成模型时,为算 loss 生成的中间结果(image)可能挺大的,显存占用续渐变大,而且可能未及时自动释放,累积到下个 epoch 导致 OOM,用上手动释放显存之后解决了。- 后来发现 OOM 好像是因为别人也在跑,撞了……
- 如果参数有很多,也可以考虑用 yaml 文件装参数,命令行参数用个 --cfg 指明参数文件,不然调用命令会很长,参考《python用yaml装参数并支持命令行修改》。
- python 装包能用 conda 就用 conda,conda 装不了才用 pip(如 cv2)。考虑先执行 pip 的安装命令,然后执行 conda 的。可能因为 conda 解决版本问题比 pip 好?
- 记时间戳可用
time.asctime(time.gmtime())
统一用 UTC 时区时间,而不是time.asctime()
的本地时间。统一时区可避免由服务器所在地不同带来的时间错乱(如同时用国内、外的服务器)。
data
如果是运行时动态随机生成 dataset splitting(training / val / test),而不是事先生成静态 splitting,就保存一下 splitting indices,后面可能 case study 的时候会用到。数据集足够大的时候,用事先生成的 splitting 也挺好。还是预先划分好一点,即类似 COCO 官方给的 train/val/test 划分一样,自己模型和所有 baseline 都用相同的划分,这样才能做 case study,主要是要用相同的 test set 做。就算要 k-fold,也可以预处理好几份划分 indices。- 保存数据、结果时可以优先用 .mat / .h5 / .pth(PyTorch) 而不是 .npy,前三者每个数据都有名,这样就算一篇文被拒几次、很久之后还要面对旧代码时友好很多。numpy 存数据可以考虑 .npz 格式,也是字典形式存,压缩效果同 scipy.io.savemat,参见《numpy用savez_compressed压缩数据》。
- 保存结果时,可以顺便记些元信息,如保存时间,可以帮助分辨这是旧代码、还是新代码的结果,这些都可以在存 .mat / .pth 时放进 dict 里(.h5 未试过但估计也可以?)。
- 用 .mat / .h5 还有个好处是:python、matlab 都可读、写,如果同时用到两者(如 baselines 有 python 又有 matlab 的)会比较方便。
- 处理数据、论文画图的时候保留必要的中间结果,比如 bbox、seg mask 这种处理大批量模型的时候很耗时,数据清洗的逻辑可能会改几次;论文画图可能也要调几次样式,留了必要的中间结果就不用每次都重跑。
- 自己划分数据集时,可将划分用 json、csv 之类随工程一齐用 git 跟踪,这样可保证在各服务器上用的划分一致,保证可复现。
training
- training 要写 resuming,因为不知道几时、缘何会中断,可以每个 epoch(epoch-based)、每 n 个 iterations(iteration-based)、每 y 分钟存一次。PyTorch 可以同时保存 optimizer 和 lr scheduler 的 state_dict、epoch、global step,以便断点续炼,参考《PyTorch: What’s the purpose of saving the optimizer state?》。
- (参考 mmdetection)用
timeit.default_timer()
记录训练时间,比如每 z 个 iterations、每个 epoch,并估计剩余训练时间。可参考《python手写简易进度条》的计时进度条。(Q:不知道 mmdetection 在多卡训练的时候是怎么计时的,是不是只要在 rank = 0 的进程计时就行?) - 如果不知道什么样的 loss 曲线、收敛范围是正常的(如在自己数据集上跑 GAN 的时候),也许可以用原文代码、在原文数据集上跑一次,用它的 loss 信息做参照。
(续 training/1)如每个 epoch 都存 checkpoint(epoch-wise checkpoint),同时(每隔一段时间)用 val 测 best model 保存(best checkpoint),可能会同一个 epoch 重复存两次 checkpoint,可用软链接,参考《python软链接、相对路径》。而如果用软链接,应先存 best checkpoint,再为 epoch-wise checkpoint 创软链接指向 best checkpoint,避免后续(为省硬盘)删旧 epoch-wise checkpoint 时丢失 best checkpoint。epoch ckeckpoint、best checkpoint 分别存,存重了也占不了多少(磁盘不够就及时删 checkpoint 就行)。而且 epoch checkpoint 可另外存 epoch、optimizer 等其它东西以 resume,而 best checkpoint 里则另存 epoch、best metrics 等。- (续 training/1)checkpoint 考虑记录 global step,方便 resume training 时续写 tensorboard,参考《pytorch续写tensorboard》。
- (续 training/1)当用某个 metric 确定 best checkpoint(如 validation set 的某指标、loss 等)时,checkpoint 应同时记录此 best metric(如 0.6),而 resume 时也 resume 此 best metric,否则 resume 时 best metric 无脑初次化成一个差值(如初始化时 best_acc = 0),后续训练的 “best”(如 0.4)可能不如 resume 前的 best(前文 0.6),却因好于初始 “best(前文 0)覆盖了 resume 前的 best checkpoint,就出错了。
- 考虑将算 loss 和写 tensorboard 记录封装在一个类中,方便 training 和 validation 调用,如:
这个类似乎没有通用写法,只是可以在 training 和 validation 时都复用,不用写两份。# from torch.utils.tensorboard import SummaryWriter class WrapLoss: def __init__(self, writer): self.writer = writer self.criterion1 = LossFn1() self.criterion2 = LossFn2() def __call__(self, phase, epoch, global_step, *, pred, y): loss = self.criterion1(pred, y) self.writer.add_scalar("loss/{}/1".format(phase), loss.item(), global_step) if epoch > 20: loss2 = self.criterion2(pred, y) self.writer.add_scalar("loss/{}/2".format(phase), loss2.item(), global_step) loss += loss2 self.writer.add_scalar("loss/{}/sum".format(phase), loss.item(), global_step) return loss if "__main__" == __name__: # ...model & data loader definition... global_step = global_step_val = 0 writer = SummaryWriter(log_path) criterion = WrapLoss(writer) for epoch in range(N_EPOCH): # training for x, y in train_loader: pred = model(x) loss = criterion("train", epoch, global_step, pred=pred, y=y) # ...optimisation global_step += 1 # validation for x, y in val_loader: with torch.no_grad(): pred = model(x) loss = criterion("val", epoch, global_step_val, pred=pred, y=y) # ...calculate metrics global_step_val += 1
- 算指标的代码也可以封在一个类里,如《医疗图像分割指标》。
- 测试时不要只记 overall performance,也要记下每个 datum 的 performance、画出分布图,方便找 bad cases。
- 记 training dynamic(loss、validation metrics)入 log file(如每行一条 json 记录),而不仅是画到 tensorboard,因为文章可能要用到里面的数据画 convergence 曲线。
readability
- (参考 detectron2)python 函数返回多个结果时,可以用 dict 而不是 tuple / list,避免搞错顺序、typo 等。
- (参考 mmdetection)记录结果的 log 用 json / csv 等结构化的文件格式,而不是自己写 .txt,就不用自己解析 log 的格式。json 可以一行一条 json 对象(python 的
json.dumps
),也能方便解析,不必墨守一个 .json 文件只记一个 json 对象的语法。pythonlogging
的格式也可设成 json 格式。
Miscellaneous
- zotero 可放心删本地 pdf 而不用担心丢失笔记:若已正确设置同步(如坚果云),某篇文(如 r-cnn)用 link to file 加入 zotero,且写了笔记(划线、文字 notes,等),此时删掉本地 r-cnn 之 pdf,坚果云上也会同步删除此 pdf,但并不影响:1) zotero 中 r-cnn 之条目;2) zotero 同步的在 r-cnn pdf 上做的笔记。若再次下载 r-cnn 的 pdf,并放回正确位置,使 zotero 能找到,则能看到笔记尚在。参考《Zotero同步论文、笔记》。
- 找个邮箱配置一下,使得能在 python 用它发邮件,在命令、程序结束时发邮件通知,及时调度,参考《内网python smtplib用ssh隧道通过跳板机发邮件》。
- 自律从控制作息开始。如果对茶敏感(饮茶提神效果明显),就不要下午饮茶,不然可能失眠,同时警惕各类奶茶类饮料,也可能提神成份。