2018 年终总结——科研生活初体验后的碎碎念

两次动笔想要写 2018 年的年终总结,但是很快又停笔。2018 年于我来说确实是转折性的一年,我从一个刷着算法上着课、整天忧心忡忡未卜的前途的本科生,机缘巧合将在西湖大学开始至少五年博士生生涯。但是这一年内总结写的太多,再想写点年终总结总感觉写不出什么有价值的新东西。不过从十月底作为访问学生来到西湖大学开始,四个多月的科研生活初体验也有一些感悟和反思,在此随意聊聊,权当今年的年终总结。

论文阅读和理解

作为研究生,平日大部分的时间要花在阅读文献上。大千论文自然有好有坏,想要将宝贵的时间尽可能留给高质量的论文,需要逐渐在阅读中锻炼出好的品味,以期能够在最短的时间内分辨出一篇论文对自己有用还是无用、写得好还是差。但是对于自己认为有价值的论文,需要静心仔细品读。这是我觉得自己现在做的不好的一点,在需要仔细读的时候往往过于囫囵吞枣,经常忽略一些细节,导致理解不够全面和透彻。到需要复现或者在其之上进行修改时,又要把论文找出来重新读上不止一遍。虽说过些时日重新阅读有时也能有些新 idea,但是缺少较为深层次的理解容易导致自己想出的 idea 实际不正确,最后枉费时间和精力(我的惨痛经验:对一个 idea 花了两天写代码+训练,最后发现建立在错误的理解上,全部推翻)。因此,对于有价值的论文,最好看一篇就是一篇,将争取理解每个细节作为每一次阅读的目标。有必要的时候,可以借助源码或者别人的阅读笔记来帮助理解。

我目前觉得要理解论文最主要的几点是:

  1. 理解要研究的领域/问题,前人已经解决了什么,还存在什么问题,这篇文章旨在解决/改进什么。以上内容基本在 Abstract 和 Introduction,如果对该领域不太熟悉,就需要仔细阅读为后续章节的理解打下基础。
  2. 理解假设。ML/DL 的论文一般都会预先抛出一些假设,一般就是 idea 产生的契机,然后再建立模型后再通过实验去验证。因此理解这些假设,就能更好地理解这个 idea。
  3. 理解模型每个部分的设置。粗颗粒地来看,模型每个部分用了什么结构,这样的选择能够解决/改善什么问题;细颗粒地来看,一些小的细节,例如超参数的设置等,都包含着学问。至于看得要多细,取决于文章的重要度。像是 Attention is all you need 这种级别的,当然看的越细越好。有些文章基本把每个结构的作用弄清楚也就足够了。

文献管理和整理

我现在在用 Mendeley 来管理电子文献,有 Windows、Mac 和 Android 版本的。到目前为止感觉还是很好用的,包括云服务器同步等功能都有,推荐一下。据说免费空间有限额,但是我现在似乎还没用完。

对于需要仔细去读的论文,我还是习惯打印出来读纸质的,因为在纸上标记或者写批注的感觉还是不一样,实验室里打印也方便。当然,随着读的论文越来越多,我桌上的论文也堆起来了,已经明显有不好分类和查找的趋势了。我觉得还是要去尝试习惯直接阅读电子档。

我现在还面临的一个困惑是,如何去总结一篇读完的论文。如果不对读过的论文进行精华的浓缩,那么时间长了想要重新了解论文的内容,除非记忆足够好,否则得重新将全文阅读一遍实在费时。另外,总结也是逼迫自己仔细阅读和思考的一种手段,也有助于锻炼写 Introduction 和 Related Works 的能力。去年自学尝试读论文时,我尝试过用中文总结放到博客上。而现在可能会考虑用英文写来锻炼自己。我在知乎上看到很多在国外读研究生的同学,导师会要求定期交论文阅读报告并批改。我觉得这种方式对研究生的提升有很大帮助,可惜在国内(包括我所在的实验室)好像很少看到。今年的一个任务是在知乎和 Github 学习别人怎么总结论文,并摸索出自己的一条流水线,整理出属于自己的论文宝库

Idea 的产生和成熟

我觉得目前自己想出的一些 idea 主要基于以下两种思维:

  • 批判思维:建立在透彻理解一篇论文的基础上,会对论文提出一些自己的质疑:这篇文章有哪些 contribution 是真正有价值的;哪些文章认为自己解决的问题实际上解决得不够好;模型中有哪个部分可以进行替换和改良;是否有缺少哪些实验来证明文章的结论,等等。在这种思维下,你既看到了论文的不足,也会看到论文的闪光,从而更好地吸收。
  • 迁移思维:机器学习包含的子领域很多,大部分在某个领域初次提出的 idea 在或多或少的改良后都可以迁移到其他领域。例如 CV 的 CNN 迁移到 NLP 就有了 CNN for Sentence Classification,Attention 从 NLP 迁移到 CNN 也有很多应用。当然,这种领域迁移的应用也不难想到,因此可能会遇到 idea 撞车的问题,如何迁移地快、迁移地好也是学问。

对于勤奋阅读论文(不是我)、了解最新研究进展(我没有),同时智商在线的人(这个我好像还达标),想出一些 idea 不是很难。但是俗话说得好,

Idea is cheap, show me the paper!

能否将不成熟的 idea 快速转化为成熟的论文,是衡量研究生优秀与否的标杆。因此灵光一现产生 idea 的瞬间,首先要及时记录,避免贵人多忘事,事后两行泪的情况发生;然后要拥有快速编码实现并实验的能力,来验证 idea 的可行性;在对 idea 和代码进行反复改良,和导师等合作者充分交流后,可以开始痛苦憋文啦!目前我手上这片 paper 对应的模型前前后后有将近 20 个版本,最后才得到一个较为理想的实验结果,一是研究的常态,二也说明自己在某些中间阶段还可以优化,比如在实现和实验前对 idea 进行充分推敲,减少代码的迭代版本等等。

机器学习的实验工程化

为了产出自己的第一篇 paper,我也是自己摸索着开始做实验。在实验过程中有一个深刻的感受:写代码简单,写好代码难。三年的软件工程专业学习和项目及开源经验作祟,编码和运行时就总觉得有很多可以改进和固定成流水线的地方。知乎上也有很多人讨论如何高效地进行机器学习相关领域的实验,大家针对各个方面有不同的经验和看法,毕竟各行各业的标准都是摸索出来的,而机器学习又是较为活络的领域。这里简单聊一聊我对实验工程化的一些问题和经验。我也是刚开始探索,希望这些个人选择可以作为参考。

  • 版本控制:但凡有过工程项目的都知道版本控制的重要性。Git 当然是首选,我们实验室自己搭了一个 Git 服务器,另外现在 Github 的小型私有项目也免费了,多种方式可供选择。在进行版本控制的同时,也要注意标明足够清晰的 commit 信息。我在目前的项目里还放了一个 CHANGELOG 文件 来记录每次更新内容。尽可能的细粒度的 commit 也有助于帮助非编程人员分辨每个版本的更新。不过,和其他目的性明确的项目不同,机器学习实验的版本控制存在的一个问题是,可能有很多模型等待实验(或者说试错),这些模型可能只有一些非常细微的更改,但是还必须全部独立保留,并且在历史记录上要能够清晰地分辨。这一点容易导致代码量膨胀、模型分辨与查找麻烦以及历史记录含糊不清等问题,有待考虑优化。
  • 结果可视化:如何知道一个模型训练效果好不好?最好的方法当然是将损失函数以及其他结果可视化来辅助决策。我目前使用的深度学习框架是 Pytorch,搭配的可视化工具是 tensorboardX。缺点是,迭代次数增加导致记录的结果变得太多时,有些卡。更多玩法正在锐意探索中。
  • 超参设置:机器学习是有超参的。实验室超参的设置有几种方法,写死在代码中自然是最蠢的那种。有些人会推荐专门写一个配置文件,然后在代码中读取。但是我目前的工作方式是在本地编码,上传 Git,然后在实验室公用的四张 1080Ti 的服务器上运行。这样想要修改文件也挺麻烦的,至少我不喜欢用 vim。因此我的方案是:命令行设定参数。通过import argparse,在parseradd_argument来设定在命令行运行 python 文件时可以设定哪些参数或者强制输入哪些参数,再分情况处理。这也是很多开源代码中的做法了,我觉得挺方便,但是也有一些其他的问题,例如不同模型拥有的超参可能不同,怎么办?接着往下看。
  • 模块拆分:在机器学习中,当我们在选择不同模型解决同一问题时,有一些部分通常是不变的,例如数据读取、训练、测试、评估、模型存储等等。这些部分可以单独拆成函数,存储到一个文件中,以复用来加速实验迭代。剩下的部分,一是模型本身,二是main函数。一开始我也想让所有模型共用一个main函数,但是后来发现不同模型拥有的超参可能不同,很难做到在一个main函数中自由切换模型并做到在命令行内指定超参(除非增加很多对于单个模型无关的代码),另外还要考虑到 grid search。因此,现在我在每个模型对应的文件里有独立的main函数,这样在这个文件夹可以随时修改模型架构和对应超参,以及更改 grid search 的范围。当然,每次创建新模型时需要将main函数复制并修改,不过相应的工作量不算太多,在可以接受的范围内。
  • 实验结果及模型的保存:有时候实验结果和模型需要保存,需要保存与否可以同样通过命令行参数进行设置。对于分析好的结果建议用 excel 保存,记录数值、对应模型名与文件名、相应 git commit 的 id 以及其他信息,便于后续查证。
  • README:最后一点,好的 README 有助于刚接触该项目的同学快速上手,若是需要开源的代码更是必备。你的 README 应该至少包含以下内容:一个好的项目名字、一行简介来描述项目、用法展示、API 清单、安装方法,以及 License。

虽然以上说了这么多,但是实际情况下,高速的迭代压力、急剧膨胀的代码量等因素还是容易导致项目最终成为难以解读的天书,只能尽可能做到更好。另外我还想学习一些新的玩法,例如根据实时的可视化结果改变学习率等参数等等。最后,机器学习的实验工程化的经验贴确实难找,个人感觉最好的学习途径就是高质量的开源项目了。

论文写作

昨天我导和我聊未来研究计划时说了一句,你是我遇到的在论文写作上最有天赋的中国学生,让我有点受宠若惊。我个人感觉要提升英文论文写作水平和成文质量,一还是要多看,看看同方向优秀的论文都是怎么写的,有哪几个板块,整体逻辑怎么串起来的。包括一些觉得写的好的地方可以标记一下,借鉴吸收;二还是靠英语水平,自己写和修改的时候感觉语感帮了很多忙。不过我也好久没有主动学英语了(不算被动读英语文献的话),很多时候也要靠翻译软件帮忙,个人感觉对于机器学习领域,百度翻译的准确率要高于谷歌和有道;三当然是多写多改。我准备将手上这篇投出去后再将初稿和最终稿对比一下,学习一下哪些地方进行了修改,作为下次写作的经验。

制定计划自我提升

本科三年我比较自豪的一点是,除了保持很好的专业成绩外,我也持续在寻找学习方向并制定学习计划。虽然计划中的项目有些中途放弃了,但是自我驱动一直做的还不错。在来到西湖大学后觉得自己做的不好的一点是,没有维持制定学习计划的习惯。有第一次写 paper,很多事情要花心思探索的缘故,但其实在剩余的时间里很少专注于学习。从现在开始,应该把自己当作博士生对待,思考自己在博士毕业的时候应该具有怎样的能力和筹码,从而分阶段地安排自己的时间,去实现预定的目标。

增加产出

除开正式的论文外,产出还包括讲解、论文笔记、PPT 等。产出是我一直比较看重的一环,一是因为要求产出能够逼迫自己弄懂学习的内容,将知识真正吸收;二是能够锻炼讲解或者写作能力,需要考虑如何写或讲能让读者或听众感到内容新颖有价值并更好地理解;三是帮助克服遗忘带来的无效学习;四是可以增强个人影响力,和同行更好地交流。

2018 年的下半年,因为升学事务繁忙,我产出的频率降低了很多,博客很少更新,知乎更是没有发文章。新的一年,我希望能在学习之余提升产出的频率与质量,输入产出两开花,请大家多多关注。

健康生活

还想聊的一点是,过去的一年里。无意义的熬夜和膝伤后缺少锻炼导致我明显感受到身体健康状态的下降。这也影响了我的学习状态,有时候比较难保持专注。新的一年里,努力做到作息规律,保持锻炼,健康生活。

总结与期望

从 2018 年底开始,我开始第一次独立地将一套完整的科研流程走了一遍。从大方向的确定,查找阅读文献,发掘 idea,literatual review,编码搭建模型,实验调参,再到画插图和写作,整个过程只有 baseline 的编写和实验有其他同学协助。这是一条研究生不得不走的路,而能在本科生阶段就开始着手自然是更好。整个流程走下来,最难的其实是如何在 idea 反复被毙的情况下保持心态的平和,还好感到痛苦的时候可以守望先锋启动卢西奥选择一下。

总之,非常高兴现在为止,我算是扔出了科研之路的敲门砖。目前我的第一篇 paper 已经写完,再过两天就准备压着会议的 deadline 投递,希望能有个开门红。万事开头难,独立走完整个流程后,我相信之后虽然也会遇到一些新的困难,但是自己能够顺利克服。

对于整个 2019 年,我对自己的期许是首先能够中一篇高质量的会议论文,突破从零到一的门槛。之后先堆积数量,积累技巧(或者说套路),以期熟练掌握整个流程。我希望这一年能够走完量变的过程,尚不指望能够在短短一年突破质变,但是最终的目标一定是做高质量、有影响力的工作。读博是一段难得的能够沉心研究和思考的时间,也希望自己利用好这段时间找到人生后续的方向与目标。