这篇总结陆陆续续写了很久(1个多月?都是抽休息的时候写一些),凑合着看吧。
2017年的主要总结,我想先用几点概括一下吧:补必修课,英语学习,科研之路,博士申请,云南实习 I,毕业答辩,云南实习 II,在家修养,澳洲签证。
补必修课
作为导师的大弟子,我和导师对学校选课机制都了解甚小。于是在研一选择课程的时候,我们错误的把数学系其他专业的必修课选择在列表里。而过去的这两年,学校选课系统一直没有任何提示。直到研三开学的时候,学校更新了选课系统。
于是在某个风和日丽的早晨,我突然发现,曾经我以为自己选好的“必修课”统统变成了选修课。导致我必修学分差了9学分,无法顺利毕业。
研三的上学期,我的精力有大半放在了:微分方程数值解、现代微分几何、非线性数值优化,这三门必修课上了。同时我还要兼顾科研方面讲讨论班,不停的学习一个又一个的机器学习算法和计算机视觉算法。
简单谈谈这三门课吧!
首先,非线性数值优化这门课还是非常有价值的。选用的书是numerical optimization,是一本非常不错的优化书籍,实用性很强,我还是非常认真的学习了。不过大概是我跟数学系基因不匹配吧,我看书的关注点从来都是:明白了问题是怎么回事,理解算法是怎么来的以及我如何能把它用在一些实际问题上;而数学系考试的重点从来都是:收敛性如何分析,收敛速度如何分析,如何证明某个算法的特性。所以我考试成绩也是意料之中的糟糕,但挂科还不至于。
微分方程数值解也是如此,我更关注的是如何根据微分方程构造差分,有限元是什么。或者说,我更关注一些偏表面、偏实际应用的东西。而对于实质上的,收敛性、稳定性、解的存在性这种东西,缺乏深入的研究,也没有兴趣研究。
至于现代微分几何,我基本没学进去。这个课跟我之前学的黎曼几何一样。上来就是单位分解定理,然后是各种微分符号、切空间、联络什么的。说实话,研究数学而不结合问题来讲,只是基于一些定义,开始逻辑游戏,推导各种性质。这在我看来有点自娱自乐的意思。因此,本质上我对这个课非常反感的,尽管它有一些应用背景(比如量子物理),但不结合任何问题的纯数学探讨,在我看来只是浪费我时间。
逃离数学系的决心
数学系研究生的这几年再次坚定了我逃离数学系的决心。
数学是艺术是很美的学科,很有趣也很适合消磨时间。但数学系的很多人,其实并不明白数学如何应用在实际问题中,而数学本身脱离实际问题也可以成立。这就导致了数学系的研究人员可以完全不管任何实际问题。
从我的角度来看,在数学系从事科研的很多人,对于理论的研究都比较深,对于模型的性质也了解的比较深。它们认为理论是复杂的,是晦涩的,是艰难的。同时也认为应用的问题是简单的,解决应用问题的模型也是非常简单的。
说实话,这些数学研究者的看法大抵正确。但真正应用问题的困难性被忽略了。
应用问题的困难不是数学模型上的复杂,而是问题的开放性。没有人知道实际问题的本质是什么,而能找到一个有效的数学模型的过程本身是艰难的(不管这个模型是简单还是复杂,找出一个比现有的更好用的模型很难)。
所以,与其研究数学模型本身的性质,我更想深入研究实际问题的本质,如何来找出一个更加好的数学模型。所以我打算从事偏工程类的研发工作。
英语学习
大概有1个月左右的时间认真学了一会英语。还去报了新东方的课,实际上并没有什么收获。妄图通过上课来弥补基本功的不足是没有效果的。
怎么说呢,对英语的投入始终没法保持持续。而相对来说,对技术的投入却总是有激情和兴趣。两者的本质区别是不是兴趣呢?我认真思索了一下,其实不是。
对于技术方面我能持续投入的根本原因是,我学习技术是没有计划性的。
通常来说,我学习一个新的技术,都是因为有一个问题需要我解决。于是为了解决这个问题,我查了很多资料,看了一些书,把问题非常好的解决掉了。在这个过程中,我又会发现很多我不知道的东西,因为有很浓的好奇心和探索心理,我基本会把涉及到的方方面面都了解一遍,偶尔会对某个方面深入了解。长期保持积累的这个习惯,让我的技术累积达到了一个很广泛的程度。
而对于我学不好的方面,比如英语。我的日常生活中并没有太强的使用性需求。日常阅读英文文档需要的英语知识非常少,因此对我来说也毫无压力。没有人需要我翻译什么书籍,也没有人需要我为电影视频制作字幕。唯一需要英语的场景,就是考托福雅思GRE。这个需求的本质并不是帮别人解决问题,而是达到别人设定的标准。学习英语的过程中,很难有那种帮别人解决问题的成就感,而分数带来的成就感对我来说没什么意义。
而这次为了达到出国的要求,必须学习英语。于是就开始计划性的学习。这点上我承认我是非常差的,否则我也不会高中一直在班级里倒数了。总之,虽然最后英语成绩很差,但还是达到了拿offer的水平。于是后来又把英语学习放下了,没继续学。
未来需要努力的方向有两个:
提升计划的执行力。这些年努力下来,比当初高中的时候好了一些,但还是和当时班级里顶尖的同学有很大差距。目前主要就是:记笔记、写TODO列表,定期check。简单来说就是借助文档对自己管理。
从源动力上改善。比如不设定目标,首先为了帮助其他人或解决自己需求来做一件事。随后,由好奇心驱动,探索更多的细节和内容,跟更多的人互动。用这种方式来学习自己不擅长的科目。
学英语仍然作为长期的计划,继续保持吧。被它恶心了这么多年,不掌握到一定程度,真的不甘心。
科研之路
我导师不太愿意在应用方法上投入精力,对很多模型和应用背景都不太了解。所以,搞科研很多时候都是自己搞,大部分低年级研究生什么都不会,组里也缺乏讨论氛围。我们的讨论班很少讲论文,讲了也没人能听懂,导师也没怎么看过这些东西,提供不了太多的思路。所以最后讨论班就变成了给大家培训基本知识的课堂。(其实这不太好,毕竟基本知识所有人应该私下去学,而不是把探索学术问题的地方变成了课堂。)
期间,我还做了一次数据算法比赛。投入也不太多,很多时间都放在如何优化代码结构上了,偏离了比赛的主题。也是后来才意识到,对于比赛这种东西代码写的优雅是没什么用的,关键在于快速出结果,讨论分析结果后再次快速出结果。
至于paper方面,那段时间看了有大概50篇吧,cvpr, icml, nips等等的,很多论文看完也做了笔记。有了初步的研究方向。自己也做了一些实验。但平时补必修课+老师的横向项目+培训低年级基本知识,我始终没能在科研上专注和投入大量的精力做实验。所以最后论文内容并没有完成,我自己本身也有很大的问题。
另一方面,我其实并没有想写这篇论文。因为我觉得内容并不够,并没有真正解决问题,分析也不够深入。按照我的想法是:最好我能有半年的时间专注的只研究这个事情,并做充分和全面的调研,真正能做到解决问题之后再把成果发表成论文。而草率的把论文写出来(水论文),把精力放到讲故事上,对我来说真的没什么意义。论文多确实是能带来很多好处和资源,但我搞研究并没有想要得到这些,想要的是真正和大家分享一个实用的发现,并得到大家的认可。
虽然,研究生三年过去了我还没有一篇论文,但我也在这个过程中学到了很多。我相信所有的失败都不是白白的浪费时间。对于我来说,科研这种事情,既然是想做而不追求什么回报,那么无论将来什么时候再做都行。我真正的目标本身是,发现并分享一个真正创新而又实用的方法,那其他的方方面面又有什么好在意的呢?
博士申请
说实话,我的导师是一个非常好的人,很多时候也会替学生考虑。但教研室里,除了我跟导师沟通比较多,其他的很多学生更是愿意作为一个被管理者的角度和导师相处:导师push一下就做一做,不push就做自己想做的事儿,有问题有想法也不会找导师。
我认为,学生和导师之前要充分沟通才能建立相互之间的信任,而这种信任是直观重要的。这点上,我和我导师的相处关系就特别好。我们与其说师生关系,更接近朋友关系,会分享和探讨生活和学习上的方方面面。
我博士申请主要是导师给了我强力的推荐。我也因为这个推荐得以接触到更高的平台。我对此非常感激的,也非常期待自己的博士生涯能和更多优秀的人建立联系。
我博士申请的大学是澳大利亚的悉尼大学,导师也是一个学术声望非常高的一个老师。目前研究方向还没完全确定,但我对强化学习和因果推断更加感兴趣,也在看相关的基础书籍。希望未来能从事相关的研究。
申请的时候,我还经过了对方的电话面试。因为主要是基本功的考核,我还是得到了比较高评价(得益于讨论班上给各个学弟学妹不停的普及算法基础知识)。虽然我能写到简历上的硬核的实力不多,拿不到学校方面的奖学金,但悉尼的导师给我发了全奖的offer。我觉得自己十分幸运,也十分感激每一个在我人生路上给我提供机会和平台的人。
我会全力以赴,努力做好自己!
云南实习 I
悉尼导师在国内有个团队,做人工智能创业公司。于是在研三下学期,我就到公司这边进行实习生涯。
公司坐落在风景秀丽、气候宜人的云南,环境相比很多创业公司来说要好很多。当然,跟大型互联网公司比的话,还是有差距的。
来公司之后,主要做了一下深度学习框架的事情。听说是想支持多个框架的切换。于是我从计算图模型开始设计整个架构,计划采用类似keras的方式来设计一个兼容性的框架。因为业务要求,需要用C++开发,因此不能直接使用keras。
对于技术上这种框架架构设计来说,我还是有一定的信心和经验的。看过的框架源码也有好几个,包括游戏方面的cocos2d-x,第一代的深度学习框架caffe。我自己也基于nodejs后端开发过业务框架,涉及中间件、ODM,此外我还尝试过开发类似TFLearn那样写一个顶层的算法框架。虽然我没有很完善的搞定一个通用的技术框架,但我具备写框架需要的基本知识:精通几门开发语言,底层的CUDA和CPU并行计算都做过,优化和profiler也都试过,网络方面、序列化技术、内存管理、GUI开发、Web开发这些都有涉猎。而且我还在积极的阅读编译原理和操作系统的基础知识,也是受益匪浅。
说实话,干这种高端开发,像是搞艺术一样写代码的工作,我还是很愿意的。一来能证明我的实力,二来也能锻炼我的业务思维。因为写框架也是要围绕业务展开的。
公司对我的项目的需求上还是挺复杂的,希望我能开发经可能通用,同时支持训练的框架。我估算了一下整个方案的工作量,预计自己只能做一个开头工作,剩下的要靠组建团队来持续开发。于是,我在公司里引入了比较流行的协作开发模式,以及相应的工具链。包括git的branch管理、单元测试、CMake管理项目文件等等。
在公司实习的这段时间,我也认识了很多牛逼的博士朋友。有公司的主要技术负责人王院长,有搞SLAM的琰神,有年纪轻轻却马上毕业算法搞得666的付欢师兄,还有一些跟我一起要入学的小伙伴,算法强人梓衡和ACM大神立浩。每个人都有自己的特长,也都能发现和解决疑难问题。都是潜力极强的小伙伴。
不过最后,毕业答辩即将到来,我就回学校去搞答辩了。
毕业答辩
硕士毕业答辩一般比较水,不过我还是把自己做的工作整理了一下。简单来说就是把我研究网络初始化的思路和实验进行了总结。然后附加了一个年久失修的、导师反复强调让我搞出来发论文的、多光谱食品鉴别的算法框架。其实我对这个兴趣缺缺,算法框架虽然是我提出来的,但我觉得解决这个问题的方式更加像是一个工程,而不是学术研发。
但说实话,深度学习方面近期的发展,更像是工程进展。而明明是搞工程的套路,调了调参数,设计了个新的trick,还非得编个故事来说自己多么的有启发性,自己多么的有道理。但是大家开心就好,好用就好。
其实,学术界有这种追求实用性的作风还是个不错的事情。毕竟有很多的期刊也会偏向于理论,而应用的实用性得到重视,也说明工程师的地位也在上升。越来越多的迹象表明,大家更加看重理论结合实际的效果,而不是一个没有实际用处的理论。一般来说,这种提升性能的核心工程技术研发,都应该是国家或公司高度保密的内容。而目前学术界反而比较开放的分享这些技术,让我看到了人工智能行业的良性发展模式:理论和实践相结合,更注重理论的实用性。
当然有很多大牛批评说:深度学习领域,学者都跑去搞工程去了,本末倒置。有失偏颇吧,毕竟能搞出有用理论的人太少,其他人跟着凑热闹灌水写没用的理论分析,还不如做实验给大家更多的启发。但有实力做理论研发的人,一定也在默默的构建理论体系框架,更加结合实际经验的进行总结,得出一些更加有用的结论。
答辩整体来说进展的还是比较顺利,我的工作数学内容也比较少,但大家觉得还可以。听说有的人因为数学内容太少,还被拒绝通过。不得不说,数学系还是太注重理论。一个人应用能做出好的结果来,看起来容易听起来容易,可操作起来,我敢保证让很多数学系的老师很久都重复不出来一样的结果。而很多老师认为比较有启发,能合适应用的理论,转化为算法往往效果很差。甚至一些有应用经验的人都不用实验就能指出存在的问题。
纯数学系的人还是适合做算法的理论分析,而不是提出算法。设计和发明算法需要一个人非常懂应用问题,同时具备比较深的理论功底。这个事情是需要一个人同时具备两种能力,而不是两个具备相对能力的人配合所能达到的。毕竟,理论很广,应用也很广,两个人想结合的那么默契是不现实的;而如果一个人掌握两个方面,他往往会围绕一个核心问题来展开自己的知识面,反而更能做出突破性成果。
云南实习 II
留学澳洲的事情,因为奖学金流程被学校卡了一下,因此延期到了2018年的3月份。于是毕业的这段时间,我再次回到云南这边进行研发工作。
这次我跳出了自己的岗位细节,站在部门的角度,问了部门一些规划。
其实开发工作还是要站在更顶层才能有更明确的侧重点。这次开发,让我认识到我之前眼光过于局限,对于一些细节规划过于庞大,而这块问题目前不是公司的重点,也不能够投入大量资源来做。了解到公司的痛点之后,做技术也更加有方向性了。
首先我在公司推行标准的项目管理方式和自动化运维流程。主要技术有:Gitlab,Docker,Jenkins。Docker这个东西其实很早就知道了,以前搞项目的时候,让一个本科生(轮神)搞了搞。我自己则没太关注,因为我的代码都放在github上了,而CI当时则是用的travis,免费又好用。这次自己整了整Gitlab+Jenkins+Docker,迅速用三天时间把《第一本Docker书》给撸完,搞了大概2周左右,才把一切的流程打通,可以自动化测试和部署。初步弄好的时候,还是感觉屌屌的。(同时,我建立了:docker大法好的基本认知)
随后,我又在公司里面引入了Javascript技术。本着JS大法好的精神,前端上了Vuejs和一堆配套库,包括lint和test,后端则是迅速基于koa2撸了一个api的简单框架,初步把公司网站的主页给搭了起来。说起来,我还是不太倾向于传统java web的开发方式。前后端不解耦合,很不利于平台建设。况且现在前端框架这么牛逼,很多Java Web开发者还把JavaScript当成玩具语言,更多则是使用JSP来做前端。说实话,现在的前端支持模板渲染、路由、数据流,本身就是一套MVC了,后端真没必要再渲染。而传统Java Web的方式则是基于容器来渲染JSP页面。我觉得java web只保留servelet就好,主要处理一些:业务逻辑繁琐复杂、需要频繁操作关系性数据库的问题。此外我还建议接口统一restful,简单轻便(性能真有问题了,再说RPC或者IPC相关技术,至于XML,我真的不喜欢)。
最后临走前,我又考虑到大数据平台建设,给公司提供了一些技术规划:分布式文件系统、分布式数据库、分布式计算,给出了大概的架构方式。
总之,这次实习两个月左右,干了不少偏工程和流程管理的活儿,也站在了更顶层的角度去思考技术。说实话,这种顶层架构的活儿比较适合我的能力。而做一个大项目下的小部分,本身不能体现我的能力。毕竟我学得比较广,相对而言,小细节反而把握的不够深入。这些坑爹的BAT之类的大公司,大都是招聘螺丝钉为主的,面试问题要么就拿数据结构算法来坑我、要么就针对某个小细节不停的问更细节的(比如加密算法、系统API、海量数据排序)。本身我就是解决问题的方式来学习的,很多公司用户规模上也还没遇到这种问题,谁闲的没事不解决重要紧急的问题,反而提前考虑优化问题?优化问题本身难不难呢?我觉得一般吧,真要搞也不见得搞不定(还真没有特别多我搞不定的,GPU上写CUDA我都写过,也能达到一定提升;stream指令、避免bank conflict之类的,本质就那么回事,写起来都不用考虑工程项目结构,一个文件写下来就行)。
哎,偏偏这种细节问题答不上来,就显得你很弱一样;大公司这种态度让我觉得特不爽。而他们的一些员工也一样,以前一个google的入职员工,问我两个算法题。我没答出来就说我基础不行啊之类的,醉了。就是没刷题呗?我很少做螺丝钉的工作,当然用不着那么细节上的优化。如果真给我时间,我照样写的出来符合性能的算法。毕竟我数学系出身,算法什么的,再基础不过了。
在家修养
在云南呆着,不知道是吃饭还是什么原因,身体突然不太好。再加上按理说签证也递交了,可能快下来了,于是我就回家修养了一段时间。
回家之后,保持了很长一段时间的好作息,身体也恢复挺好的。
趁着寒假的机会,也去了一趟对象的家里,算是提前见了一下父母吧。嘿嘿。HH同学家人都很淳朴,她们家那边的饼啊啥的非常好吃,印象深刻。鉴于HH同学打算找工作,所以基本在家的时候,多来陪她一起学习了。
我自己的学习方面进展不太大,简单看了一些强化学习的书,《Reinforcement Learning: An Introduction》,大概看了几章吧。还搞了本信息论的书,也看了个开头。操作系统的书《Operating System Concept》也只看了前面的部分,看到dead lock附近吧。怎么说,我还挺喜欢看这些书的,毕竟能结合实际经验反过来学习理论,感觉理解上更加深刻和实用。论文有点不爱看,不管什么比较简单的idea,都能说的特别好,这个好那个好;但根本来说就是个trick,讨论就算有理论,也比较针对一个点,一个很小的子问题,不系统。
我还是比较喜欢学习系统一点的知识,能串联到一起,解决一个大问题这样的。论文什么的,也许以后读博士的时候,再去细扣吧。
路漫漫其修远兮!
澳洲签证
眼看着到入学截止日期,签证就像石沉大海一样。简直是坑死了。
各种手段都用过了,均没有回馈。
据说受影响的主要以phd为主。因为phd基本都不是自费的,澳大利亚不爽。外加澳洲政府高层整个有个傻逼排华,整天宣扬中国威胁论,还搞什么我们这些phd都是去澳大利亚窃取他们的高端技术。(WHAT?要不要脸?渣渣土澳,有什么值得窃取的技术?袋鼠养殖么?)
总之,我很无奈,只好把offer再次延期,到7月份。
说实话,有点不那么想去了。读博士也不利于结婚。有点想结婚定居,好好过日子。
生活嘛,有的是可以选择的。也不必非得搞得不读个海外博士不算成功这样子。
只要能心态平稳,安心进步,享受家人的温暖,享受爱情,多增长见识,多帮助他人,多回馈大家;我觉得人生就是成功的。
反正其实随便找个工作赚得也不少了,想赚更多不如想怎么样活得更优质。