如何复现一篇 SIGGRAPH 论文

09 Nov 2019 | thoughts

SIGGRAPH/SIGGRAPH Asia 作为计算机图形学领域的顶级会议,每年分别在北美/环太平洋地区举办一次。该会议近年来每年约接收到 300-500 篇投稿,录用率在 20-30% 之间波动,故一年两次加起来录用的文章大概有200余篇。SIGGRAPH 一直代表了图形学科研的最高水平,学届几乎所有里程碑式的发展都可以在该会议的论文中找到。

也正因 SIGGRAPH 的文章含金量高,对于浙江大学这样的中国图形学强校来讲,博士毕业的论文要求就限定于 SIGGRAPH/SIGGRAPH Asia(或者 Transaction of Graphic(TOG),而 TOG 论文一般会在会议上展示),而如果本科生能够作出一篇 SIGGRAPH 一作来,往往能直接敲开四大的大门,例如南开大学的 Pingchuan MaYunsheng Tian 就在 SIGGRAPH 2018 上发表了一篇使用强化学习做流体模拟的论文,顺利进入 MIT CSAIL 深造。

几乎每个图形学研究者都以做出能够发表在 SIGGRAPH 上的工作为目标,但要想做出这样的工作往往需要非常巧妙且深入的思考和非常扎实的实践。作为一个初入该领域的菜鸟,我自然也有这样的梦想,但自己无论是理论还是实践都有很大的欠缺,即使急于求成但也难以做出这样的工作。

另一方面,从头发表一篇 SIGGRAPH 论文是很难的,要从头复现一篇却并不复杂。举例来说,我非常敬佩的一位清华学长(目前在 MIT CSAIL 读博)Yuanming Hu 在东京大学交换期间,实现了多篇关于渲染、模拟的 SIGGRAPH 论文,最后整合成了 Taichi,是当时第一个图形学界开源的、渲染、模拟相关的基础设施项目,现在已经转变为一个编程语言(见论文)。再例如,许多学校开设的课程中都会有作业实现简单而有趣的 SIGGRAPH 论文如 GrabCut、Hybrid Images 之类。在过去的一年里,虽然我并没有能够从头做出一篇 SIGGRAPH 论文,但我成功的在两门课上从头复现了两篇 SIGGRAPH 论文:Video SnapCut: Robust Video Object Cutout Using Localized ClassifiersDeep High Dynamic Range Imaging of Dynamic Scenes.

Video SnapCut

在大三上学期,我选了周昆老师主讲,其他 CAD & CG 实验室老师辅助的《计算机图形学研究进展》课程。这门课每周会选取一个主题,分享四到五篇与其相关的论文。前半学期所选取的主题基本上都是周老师自己一路走来做过的题目,所以讲起来非常生动(吹起牛皮来也非常的有底气)。与之相关的,既然授课内容就是读论文分享论文为主,这门课的课程作业自然也就是选择一篇 SIGGRAPH 论文进行复现。

选题

首先要经历的是选题,我在选题上主要考虑的是三点:

  1. 创新度:这篇论文是否足够有新意,还是只是刷分的 incremental work
  2. 难度:在有限的时间里复现这篇论文是否有难以逾越的障碍,如:工程量巨大(5w 行以上代码量)、缺少数据
  3. 相关度:选择的论文是否与课程内容相关

最后我定下来的题目是来自 University of Minnesota 和 Adobe System 的 Video SnapCut,按照我的三个标准来看,这篇文章相应做到了:

  1. 这是一个 automatic video object cutout system,在论文发表的当时足够创新,且与之前尝试过解决这个问题的工作相比,这篇文章用了 local + global 的策略来提高系统的性能,这一点也相当有创新性。
  2. 这篇文章并没有任何的开源代码或者相关资源,唯一的教程就是论文本身,复现起来还是非常有挑战的。但同时,我粗略读过之后觉得并没有特别困难的地方,也迅速确定了相应的工具链。因此我认为,作为一个课程作业,复现这篇论文的难度是非常合适的。
  3. 我们在课程中花了一个专题来讲 image editing,尤其是 GraphCut, GrabCut, Lazy Snapping 这些经典而巧妙的方法, 而 Video SnapCut 很有将这些方法从图片推广到视频的风味,因此和课程本身也是非常相关的。

事实上,最后展示的时候我们发现,我们的选题是相当正统的。同学们的选题中包含了大量遵循“一份作业多次提交”理念的题目,例如:提交《计算摄影学》的 GrabCut、提交《人工智能》的 深度 3D 点云、提交《编译原理》的 Halide 子集。当然也有一些很有意思的选题,例如有一组做了 Flash/Non-flash photography,非常别致。

阅读与编程

选完题之后,我和我的队友 97littleleaf11 所做的第一件事就是开始反复读论文,确保我们理解了论文的每一个步骤。我觉得自己一个人埋头啃论文和与他人一起读然后讨论是个完全不一样的过程,后者可以让学习速度和深度都显著提高,几个人在一起良性的讨论真的可以迸发出思维的火花。之前在《程序设计方法学》读 PyPy 的论文时我就有过这样的感觉。

在觉得读的差不多,对整个系统有了粗略的把握后,我们就一边精读细节一边开始上手写代码。我们确定的工具链是 C++ 加上 OpenCV 和 QT,整个系统的前后端又可以非常好的分离,于是很自然的我去写 OpenCV 的后端,叶子去写 QT 的前端。为了防止图形学时令人崩溃的协作问题再次出现,我们终于走向了正轨,一人维护一个 branch,靠 PR + CI 来整合代码。特意提起这一点看起来非常可笑,但在一个大四了还有很多人不会用 Git 的学院,学会正确的协作开发课程设计的确是一件值得提起的事情。

SIGGRAPH 论文往往是需要从头搭建一个系统的,特别是渲染/模拟/动画相关的文章。这一点从某些角度上保证了论文的工作量,但另一方面又导致每篇文章都高度耦合,都需要重新造轮子,缺乏开源设施,阻碍了整个领域的良性发展。在这次复现中,我们最终从头开发了一个完整的系统,它做到了功能齐全、结构清晰,包括了论文中提到的每一个模块和细节,但同时它也停留在一个课程设计的简单程度,它的 UI 不够炫酷,它的性能也仅是可用级别。总的来讲,是一个很好的锻炼过程,在系统的构建方面,我们领略了 Adobe System 是怎么去思考并构建一个面向用户的系统的,在编程细节上,我们实践了一些之前听过但没有实际用过的软件工程知识。但另一方面,我们复现的这个 video object cutout system 中很难有可以抽象出来并且复用在下一个 video system 里的代码,这也反映了之前提到的 SIGGRAPH 论文往往耦合太高,难以模块化。

测试与评估

实现系统/算法只是一篇的论文的第一环节,另一个重要的环节是详尽的测试、评估与比较。我们复现的过程中,有两个主要的性能参考和比较对象,一是原文中报告的图片、数字以及补充资料中的视频,二是以文章为原型的 After Effects 中的 Rotobrush 工具。我们考虑到后者比较特殊,一是因为其是成熟商业产品中的一个工具,无论是运算性能还是用户体验都是经过仔细优化的,二是因为它实际还至少整合了另外一篇关于颜色模型的文章在其中(参考),因此可能将是一个非常不公平的比较,但我们认为如果我们实现的原型能够在放宽标准的情况下达到接近这个商业工具的性能的话,将是一个非常好的加分点。

在实现各个小模块的时候,我们的主要比较对象是论文,因为其中给出了每个中间环节的输出,这让我们能够定性的分析这一步是否实现正确。而整个系统实现完后,我们主要的比较对象是 Rotobrush,理由很简单,因为论文中用到的视频素材均是收版权费的,而使用本地安装好的 Rotobrush 的话我们可以做 side-by-side 比较。

开始做 side-by-side 之前我们其实近乎绝望,因为作为一个自动分割系统,我们分割的结果很不理想,初始帧很好的分割在几帧的传播后就乱七八糟,需要加大量的用户修正才能得到能接受的最终结果。好在叶子尝试了 Rotobrush 后发现主要问题可能并不是来自于我们的系统,而是我们选择的输入视频片段过于困难,比如大幅度的运动,难以分辨的前景/背景颜色,这导致即使成熟的商业工具也难以自动得到良好的分割结果,需要大量的人为校正。这给了我们不少信心,我们换用了一些简单的例子,发现我们的系统至少在简单的输入情况下能达到和论文/Rotobrush 相近的性能。随着测试的进一步深入(和 deadline 以小时为单位的逼近),我们检查出了一系列 bug,加上了包括 alpha matting 在内的一系列优化最终结果的方案。最终,我们在相近程度的用户介入下达到了和 Rotobrush 相近的分割效果。当然,在运行效率上我们朴素的、串行的实现显然难以比肩经过仔细优化的 Rotobrush,但和论文中同样朴素的实现相比,在考虑到 CPU 主频的提升后,可以说是在同一个水平上的。

我认为详尽的测试是一篇论文博取其评审和读者非常重要的环节,其受重视程度远不比一个 fancy 的 idea 要低。我认为我们在这次复现中系统、详细的测试、评估与比较是我们最后获得高分的重要原因。

展示与报告

展示自己复现的论文是一个很有意思的环节,很有一种 mock oral session 的感觉。在看了前一星期几组同学近乎灾难的展示后,我们总结了一下底下的评委老师主要关注的几个点,在自己的展示中注意。

准备展示的第一环节就是制作 slides,这是我非常享受的一个过程,可以把自己做的东西以简要的文字(主要是 bullet list)、图片、表格用简单但又吸引眼球的方式展示出来。更重要的是,自我初中以来,每次在制作展示用的 slides 时,我就已经会在脑海中模拟自己实际展示时的场景,斟酌展示时的词汇,尤其是开始读论文看展示后,会不自主的把别人用过的感觉很地道很高大的表达代入这个脑内模拟的过程,这也是非常享受的一个源头。在这次制作 slides 的过程中,叶子帮了非常大的忙,他和我两路开工,我做 beamer 的排版,他负责一遍又一遍运行程序给我提供必要的展示用图片,甚至,他还花时间制作了一个非常不错的 demo video,一瞬间感觉至少在架势上我们已经具备了投 workshop 的水平了。

当然,虽然我们在凌晨精心准备了展示,但课程上并不能给我们 20 分钟来一步一步从 introduction 讲到 limitation,尤其是当 12 个组挤在同一节课展示的时候,留给我们的时间只有 5 分钟,我们能做的基本就是展示 demo video,展示一下数据,讲解一下不足,不过,我们的结果在标题亮出来的一瞬间就得到了老师明显的反应,不知是老师对这篇文章很熟悉还是觉得这篇文章很有挑战/新意。

作为课程作业,自然要以报告收尾,由于这并非我们的原创工作,只是单纯的复现,因此在报告中我们并没有提出任何新的想法或者见解,更像是工程记录,把我们实现、测试中的每个环节以文字再叙述一遍,唯一能创新的地方就是在结果测试和比较后,能够总结出不少 limitations and future work。

总结

Video SnapCut 是我第一次系统的阅读进而复现一篇图形学相关的论文,我非常满意这一次的经历,在各种意义上我都收获颇丰。

有一个小插曲,在实现的过程中,论文中有一处文字描述和图片有疑似矛盾的地方,这直接导致我们在那一处选择了一个其他的实现,这门课结课一个月后,我写了邮件咨询了原作者 Xue Bai 和 Jue Wang,才发现他们已经从 Adobe Research 到 Megevii 去了,两位先肯定了我们的实现,然后针对我们的疑惑给出了非常详尽的解答。是一次非常不错的体验。

最后,这个课程作业可以在这里看到,demo video 也在 Google Drive 上。

Deep-HDR

本学期,我的老板吴鸿智老师开了一门新课《智能视觉信息采集》,其实主要内容就是计算摄影学但是由于名字已经被占用了所以起了一个这么新奇的名字。除了教授一些计算摄影学的基础知识外,这门课和浙大其他课程不太一样的地方在于要求大量实体实验,而不是处理现成的图像/视频。我们一周的理论课是 3 个课时,实验课从一开始的 2 个课时,增加到后来的 4 个课时,某些周甚至增加到了 4 + 4 个课时。每一组拿到的设备包括两个 basler machine vision camera,一个 LG 投影仪,然后还能额外申请 depth camera,可以编程调焦的罗技摄像头以及使用 3D 打印机。每一个实验中都要用到这些设备,最后的作业也鼓励我们充分围绕这些硬件来设计。

选题

这门课的课程作业选题范围很广,只要是和视觉信息相关的题目即可,且不一定要求是复现论文,更加鼓励原创题目。由于这门课很大程度上受了 EE367 的影响,因此我在选题时参考了很多这门课历年的 Project Ideas (很多 project 直接成为了 CVPR/SIGGRAPH 论文,非常厉害)。很快,我确定下来从头做一个原创的项目在离 deadline 仅有 4 周的情况下是很困难的,因此主要是围绕已有的论文/技术做复现和拓展。我的第一个想法是做 lightfield,因为在课上刚刚学过,又和我暑假做过的东西非常相似,又是一个非常 active 的 research area,但很快我就毙掉了这个想法,很简单,没设备让我能够拍这个 lightfield。随后我又想做 focal stack(如:Focal Stack Photography: High-Performance Photography with a Conventional Camera),但很快又发现我们的相机需要手动调焦,而那个可以编程调焦的罗技摄像头达不到实验的要求。最后,我把重心放在了 HDR 成像上。

我首先思考的是做 Google 在 SIGGRAPH 2016 上发表的 Burst Photography for High Dynamic Range and Low-Light Imaging on Mobile Cameras,乍一看上去还挺有可行性的。可当我仔细读下去后,发现有太多 Google 才能做的东西,比如他们拿一个巨大的数据库做 intensity quantization estimation,这根本不是我们能做到的,同时这个项目工程上也很有挑战。最后,我选择了 Deep High Dynamic Range Imaging of Dynamic Scenes 作为主要关注对象,这是上课时吴老师分享过的文章,有 MATLAB 代码,有数据,有新意也有可以拓展的地方,仔细读过一边论文后我觉得就是这个了。

实现

实现论文的过程往往大同小异,但是这一次有一些值得讲的事情。首先,我有两个队友,均来自竺院混合班,一位要考研,因此我也没有给他分配什么任务,一位精通 Python,于是我让他帮我处理一些数据,比如调用某份 MATLAB 实现来计算光流。我自己负责其他的编程。然而,我发现这位精通 Python 的同学缺乏解决问题的基本思维,他精通 Python 如何一行内完成很多事情,却把光流给算反了。好在最后我把他叫到我寝室来,在一旁盯着他正确完成每个环节。

不夸张的讲,这次的作业 99% 都是我实现的。我使用了新推出的 TF 2.0 作为深度学习框架,这也是我第一个认认真真写的深度学习应用。但实际上花在学习的时间并不多,我编程时间的一大部分都花在了预处理数据上,为了防止 Python 的动态类型给我造成麻烦,我遵循了 PEP484 给代码加上了类型提示,并且用 mypy 做检查,效果很不错,不会在复杂漫长的数据预处理环节中突然由于类型错误而报错了。深度学习的代码也非常直白,我觉得 TF 2.0 并没有大家说的那么不堪,至少它能灵活正确的实现论文里给出的三种不同的架构。为了方便调试,我也尝试了 TensorBoard,非常好用。

炼丹

很多人沉迷深度学习中对着曲线调参炼丹这个过程,但我实在是一点也喜欢不起来。代码一写完用不同的架构跑了几次完整的训练后我就开始觉得不对劲,PSNR 永远会卡在一个定值,但这个定值又显著低于论文中报告的数据。我一开始怀疑是过拟合或学习率的问题,但调整过几次参数,加过正则项后发现都没有显著作用。直到我把模型导出来做 inference 才发现生成的图是全黑的,检查后才发现是初始化的问题导致了过了几层后梯度全没了,修改了初始化后,训练开始正常了。

然而,这样得到的最终结果大概是 39 左右,离论文里还是差了两个点,但视觉上又没有太大的差别。于是我怀疑是光流算法的问题,因为原作者用的是 MIT 一位博士实现的光流算法,但那份 C++ 代码年久失修我已经编译不起来,因此选用的是 OpenCV 里自带的 Farneback 和 DeepFlow 作为替代品。在检查了中间结果后,我发现这两个算法计算出的光流都不是很准确,导致 warp 后的图像有非常严重的 artifacts,而这些 artifacts 并不能通过这几层 CNN 有效的消除,导致了最终结果的差异。在成功运行起那份神秘的光流之前,我看着论文中的插图,发现他给出的 warp 后的结果与原图也太相似了,甚至给我一种直接在原图上做 copy-and-paste 的感觉,于是我又写邮件问原作者,得到他一句“请用我们用的光流算法”。最后我成功在一台 Windows 机器上用作者提供的 MATLAB 库跑了起来,看到结果的时候我惊呆了,这光流也太准了……但这一来一回,让我开始思考,这篇文章真的是靠其宣称的神经网络来做到消除错误的吗,难道不是它使用的光流已经提供了一个非常接近最优的初始状态吗?在做了几组定量、定性的对照实验后,我验证了这个想法,这最终成为了我报告/展示中一个重要的章节。

展示

很难想象我大四了居然还要为了课程通宵,但的确是这样的,为了九点钟的展示,我熬着夜,一边监控最后几个模型的训练,一边做 slides,而我的队友则在呼呼大睡。这里非常感谢我的室友关先生,他跟我一起熬夜,帮我的 slides 做了不少图,还和我一起调试、分析为什么作者提出的第二个架构 WE 在很短的时间内就会过拟合。在这个夜里,我居然还突发奇想,尝试了复用网络,但改变输入的方式,得到了一个 PSNR 值不高但视觉上没有 artifacts 的架构。这个从构思到处结果总共花了我不到三个小时的架构,成为了我报告/展示中重要的一章,且助教很是喜欢。

最后,在精神很虚弱的情况下,去参加了展示课。展示课的水平倒是超乎我的想象,尤其是大三的同学们,做出了不少我认为我大三时完全做不出的课程作业,有一个组三个女生做的 pinhole 和 pinspeck,想法很新颖,实践的也很不错。有一个组做了去除照片中的反射,实验很详实,还拍摄了一个完整的数据集。展示的时候也有条有理。反倒我自己展示的时候,也许是因为通宵的原因,感觉讲得比较混乱,时间也超了不少。

总结

这篇论文的复现其实我是不太满意的,并不是因为没有复现成功,相反,我还在原文的基础上做了不少探索和增量工作,主要是论文复现过程中没有良好的合作体验(尤其是和之前和叶子的合作比起来)。这一次的主要收获是是把近年来相关 HDR 的论文都读了一遍,感觉这个领域也被做的差不多了。

结语

能直接参与一个将投稿至 SIGGRAPH 的科研项目是一件非常有挑战的事情,但复现一篇被 SIGGRAPH 接收的工作对于熟悉这个领域,锻炼相应的能力也是很有帮助的。这篇文章中我记录了自己复现两篇 SIGGRAPH 论文的一些经历和感想,也期待在未来能继续复现可行且有意思的文章。


Older · View Archive (27)

二十四時間だけのバカンス

标题来自于两位我非常喜欢的歌手的合作:宇多田ヒカル与椎名林檎的二時間だけのバカンス。至于为什么是二十四小时,是因为理想情况下,我周一到周六都应该在上课/实验室,所以只剩周日的二十四小时了。当然,这显然并不是真实的情况。

Newer

2019年を振り返って

2018 年的最后一天,和大爷、吴凡、静静看完第 69 届红白歌会后,在为了赶上热水洗澡跑步冲回寝室的路上,想要好好总结一下过去的一年。2018 年对我来说是相当特殊的一年,我去了很多很多除了家和学校以外的地方,参加了 ASC,看了 live、舞台剧、音乐剧,加入了实验室开始搬砖,围观了一次学术会议,还有一些很多小事值得记录。但当新年一过去,面对着完全没有开始写的操作系统内核,总结的计划就这么搁置了。在 2020 年都过去了近十二分之一后,我决定不再拖延 2019 年的总结。