MKimiSH

Xianyao Zhang

All posts in one long list


10000

(Spotify 只能试听可真是太拙计了。。)

前言

上一次写日志是九千天的时候,也就是在2019年12月12日。妄加揣测的话,作者也好、读者也罢,听到这个日期的时候,多少都有些恍惚。就自己而言,看到这个普通的日子却好像需要费力地望穿绵延的迷雾。上一次写日志的时候说要在这一千天结束之前试图毕业,还要写 blog、学外语、学制造惊喜。要是进行一下检查的话,在今天到来之前顺利毕业的希望并未实现,blog 上次写还是在上次,外语学得一瓶子不满半瓶子晃荡,但至少在制造惊喜这方面算是有所长进。

那么今天我一万天了,终于在数量级的意义上追赶上了大多数人。或许应该回头看看,贴八张小时候的照片,写五个想当年的故事,发三段现如今的感慨,再凑一句“在路上”的结尾。但是过去的事迹往往需要在许多存储体上读取而来,这样可以使记忆更加清楚,不至于受到情绪的过多干扰。整体而言我并不想在这样的佳节受这样的束缚,况且有些存储体我现在无从查起。

所以就让我来讲我的故事吧。以现在的角度来讲的话,会不会很奇特呢。这些故事将来还会有更多的听众和更多的版本,现在写下来的话,至少相当于一个系统还原点。

以下均来自我的记忆,记不住的就编。日期是真实存在过的,但是事情可能是其他日期发生的,也可能根本就没发生过。

1995年4月22日 星期六 +0

感谢妈妈(此处应有刘和刚的歌声)。

散乱嘈杂的记忆并不是记不住这一天发生了什么的借口,况且我迄今为止对于生孩子这件事本身的全部印象都来自于影视作品。我所能知道的,大概是那天天上飘着一些云、很多云、或者没有云,天气是晴、多云、晴转多云、多云转晴、阵雨、小雨、中雨、大雨,但不太可能下暴雨、冰雹或者下雪;医院外面的路上车很多、车不多、甚至没有车,产房的窗外种着一棵树、几棵树、许多树、或者没有树、或者是一片草地。但是总有一家人在忐忑中期待着这一天的到来,盘算着已经备齐与尚需添置的物件,也思考着未来的生活会产生的变化。或许他们在将来的很长时间内都不会考虑到一万天之后这个兔崽子会不会写一些无聊的带有很多顿号的句子。至少当时他不会写作、不会期待、不会感谢甚至不会感觉。

会哭就行。

1998年1月16日 星期五 +1000

一个新生儿到来后,大家会来庆祝过满月,也会来庆祝过百天(也叫“过百岁”——那我现在是什么情况?),但是到了一千天的时候已经没有人数得过来了,大概都在准备过年。尽管1月16号过年有点早,而且我也没查日历,但是,一个两岁多的小孩能记得什么呢,可以随便编。

过年是要回奶奶家的。在这个习惯结束很久之后、甚至直到自己也要开始想“过年回谁家”这个问题的时候,才开始考虑每年都回奶奶家这件事是否完全合理,因为它似乎是一直存在着的。而所能记得的比较早期的办法是在家门口(也是爸妈工作的学校门口)的国道边上等济宁往返汶上的中巴车,在客车独有的气味中晃荡几十分钟之后,在中途的一个路口下车,再过马路到对面乘坐摩托三轮到达目的地;在客车上要先右转一次,但之后再怎么走,好像就不知道了。去姥姥家的方式好像也是类似的,但两条路线终究会在某个地方岔开,而我并不知道在哪里、往哪个方向。现在能够怀疑的,是爸爸妈妈对于那两条路的熟悉程度,是不是和我现在对于“买机票——去机场——下飞机换地铁到高铁站——下高铁再坐地铁到家”这条路的熟悉程度相当呢。后一条路现在当然不只包含这几个步骤了,在它们中间出现了许多方形的带有不确定性的码,像是马里奥跳一跳就能顶到的问号格子,只是顶出来的金币都好像是从自己口袋里流失的。

奶奶家有许多不一样的东西,比如说有很大的铁锅,锅下是烧柴火的灶,隔壁是烧柴火的烟烘热的炕;在清洁取暖的标准里面这还是传统炉灶。在我们去的时候通常都是会住在炕上的,确实很暖和,早上起来在窗户上能够看到冰花。再比如说有麻将,当然在那时候是不会打的,只是觉得五条八万南风红中的声音从小时候开始就是很亲切的。再比如说有院子,院子里面种了许多花草树木,其中有一株石榴还有一株枣树(没有另一株枣树)。对这些事物开始建立印象时候,还不会描述它们;也许它们构成了记忆的模糊背景的一部分。当然还有鞭炮——不喜欢甚至害怕放鞭炮,并且不理解为什么有人把鞭炮这个东西发明出来膈应人。每次要放鞭炮的时候都要躲远并且捂住耳朵,但是硝烟的气味却挺好闻。

同样是直到不回奶奶家过年很久之后才明白,生活会让人想吼叫,而鞭炮总是愿意代劳。

2000年10月12日 星期四 +2000

算盘是一种古老的计算工具,它不仅历史悠久,学习的时间也通常很早,以至于将来会忘掉自己已经忘掉了算盘的用法,也需要花一分钟才能记起当时学习算盘的最终目的是“手中无盘、心中有盘”。展开说来,就是忘掉了自己已经忘掉了怎么在忘掉算盘的情况下使用算盘。反正我现在算个23乘45都要按一下计算器、python 或者 MATLAB,估计要遭小孩子们笑话。

学习珠心算的地方并不宽敞明亮,就是一个有一些小桌子和小椅子的教室。每天幼儿园结束之后,许多小孩子会聚在一处哗哗地打算盘。至于教室在哪里,每周去几天,每天打多久,这都不是一个五岁小孩能主动记忆的东西。只记得当时小孩子们打的是塑料珠子的小算盘,而家里还有一个大算盘,其算珠都是晶莹的琥珀色和黑色,可不允许我用。但说白了,最好玩的还是把大算盘倒扣过来然后当小车滑来滑去,不让我用似乎也是应该的。

噢,也许有两个打珠心算的地方,一个是平常的,一个是赛前突击来着;赛前突击的那个比较昏暗,每天打得也比较久。对于那次所谓比赛,记忆似乎是完全空白的,时间地点人物全都不知道,像是去某个地方领了第六名的奖状,而记得第六名是因为我们五个孩子获得了一二三五六名。

在一定年龄之前学会的技巧似乎完全取决于家长,但它们是会真的影响以后的兴趣的吧。

2003年7月9日 星期三 +3000

在旧327国道某个里程碑附近(注:这就相当于“国道上的任何地方”),有一栋5层3个单元的居民楼,算起来总共30户。在二单元上到二楼,左手边有一扇带纱网的铁架门,里面还有一扇木质门。进门是一个小厅,其右手的房间是客厅,客厅连着阳台;右前方是大卧室,正前方是小卧室,小卧室里有电脑(但是不玩扫雷);左手稍远是厨房,进去再左转是厕所。

不好意思最近看房看太多了;本来是想说,进门后的小厅里有一台海尔冰箱,比我还要年长些,在这个时节,冰箱的冷冻室里往往陈列着雪糕和冰棍。有时爸爸批发雪糕的时候会带上我,骑着小摩托要骑一会才能到批发的小屋——又或者这是之后批发的地方,之前有个很近的地方?但不管在哪里,直到很久之后才明白,为什么批发雪糕的地方往往这么热,还要给冷柜盖上被子。听说这样批发的雪糕要比一支支单买便宜很多,还听说雪糕买回来不能马上就吃,还非得冻一会。如果要选一支小时候最喜欢吃的雪糕的话,一定是那个火炬冰淇淋了。但那个听说尤其贵,于是在印象中它的个头尤其大,甚至要分两次才能把巧克力外壳、雪糕和蛋筒都吃完;日后在北京的冰柜里发现它其实是正常大小、好像也不比四个圈重多少的时候,满脸都是不愿相信。

从济南来的糖炒栗子则算是另一种美食,但不知道是先听说“栗子”这个名词,还是先听说的“糖炒栗子”这个词组。而什么是“研究生”呢?好像妈妈是在济南的什么地方上学的样子,还要坐火车才能去,我去了还要被迫爬山,不过她的同学阿姨好像人都很好。不过每次妈妈回来的时候总会有一包炒栗子吃,尽管可能包装都有些破损但总还是很甜很香的。

30户中有6户是经常去的地方,可算来从那栋楼搬走的时间也已经有在那里住过时间的两倍多了。

2006年4月4日 星期二 +4000

星期二算不得一个很有盼头的日子,因为不但距离周末很远,而且还有连着两节的语文课,还有思想品德课,还有体育课。尽管已经来这里一段时间而且也升了一个年级了,但是他没有感觉到有多么融入,只感觉到自己的山东口音正在逐步从鲁南向半岛方向移动。早上来到教室坐下之后,他的眼睛越过头顶的日光灯管看灯罩和吊绳之间的蜘蛛网,却似乎被晃花了眼,看不那么清楚了。

上周末的作业批完发下来了,那本做“图文并茂”的本子上又多了一个“中”。既然图也不行、文也不行,得不了“优”和“良”大概也没有什么话可说。他想,那些画画好、写作文好的人都是天生的吧,这事情跟自己仿佛是没什么关系了;尤其是写记叙文要所谓“真情实感”,怎么是自己能达到的呢。不过数学课有一些速算的作业,仿佛几年前自己做过类似的事情,而且现在算起来也很快并且不理解其他人为什么会在这个任务上卡壳;但是却又不记得算盘怎么打了。

刚要写点作业,他手上的钢笔就不小心掉到了地上,折了尖还洒了墨水。幸好不是洒在本子上或者桌套上,幸好。而他本子上的字迹是很密的,会想方设法把空白都填满,并以此为一种能力。这点直到上了大学才有所改观,因为本子再也用不完了。

骑自行车的小学生,真的需要注意被拐卖的风险吗?

2008年12月29日 星期一 +5000

虽然今天是星期一,但是马上就过元旦了,故而过得像星期三一样。他从来没有关心过做早饭要花多久,而给其他人做早饭又要比食客早多久起床;今天也没有关心。起来之后洗漱一番,顺从地把牛奶喝了、粥和鸡蛋吃了,把蓝色的、宽松的、对他身材非常友好的校服穿好,把还不如上小学的时候沉重的书包背好,然后下四层楼的五十八级台阶,进行一个180°右转、一个90°右转再一个90°左转到达储藏室,打开门推出一辆蓝色的小轮车。七点的天是没有完全亮的,路灯还在照着小区门口尚且冷清的路上。走出小区门口的时候总会想一次——对面的楼到底什么时候才能建好。

到学校的路骑车也就十五分钟。作为卫生委员,在到校之后的第一件事就是检查卫生,观察死角有没有扫干净、拖地有没有拖完整、窗台有没有灰。大概做卫生委员对于一个孩子的成长是很有益处的,可以使得他注意卫生,也可以使得他知道脏东西只是脏而并不是邪恶,就算抹了一手灰也没有必要大惊小怪,洗掉就好。

现在似乎对于体育课的抵触不如之前那么严重了,因为操场边上有一些乒乓球台,可以去打球。但他的乒乓球水平和桥牌水平、2D桌球水平一样,一直停留在门外汉的阶段,不知道是羞于提升、懒于提升还是真的不得要领。

手指上在窗台上摸到灰的时候,有时是高兴的,有时是不高兴的。

2011年9月25日 星期日 +6000

有百分之五十的可能,今天是在学校上自习的日子;有百分之五十的可能,今天是大休结束的日子;有百分之一百的可能,今天是要上晚自习的。(注:我算过了,调休大概是调不到今天的,会调10月8号和10月9号。)

高中生活是很紧张,对于大脑的压力很大,但是对于背部的压力在所有求学阶段里面是最轻的,因为书包里几乎不需要装任何东西,而上学和放学也基本是车接车送。这种在不同小区接送学生的生意,确实也有得赚,但毕竟要面对早上没睡醒和晚上累得不行的学生们,怕也不是特别好的差事。

分班之后终归是不一样。听说过许多关于不分班的传言,但最后在他这一级还是没变。还真是,记得高一的教室在哪里,记得高三的教室在哪里,却记不得高二的教室在哪里了。可能再想十分钟能想起来,也可能就想不起来了;大约是在楼的中间某层的中间位置,不易被记住吧。总之是有许多新的同学,也有许多旧的同学,但没有给自己留下过阴影的同学,这让他感觉不错。最近获得了一个看起来很高端的、皮面的本子,有一些要写点什么的冲动。似乎开始意识到,设备的提升确实有助于兴趣的提升。大约后座的同学也有写些什么的打算。

书包里不多的东西里面有在他爸办公室打印的《Love the way you lie》和《Lose yourself》的歌词,在自习的时候的阅读材料。是不是要庆幸他爸没有把英语学好,要不然怕是要聊一聊的。——或者其实他一直是知道的,毕竟已经打过七八份歌词了,只是觉得儿子要学英语才没有多说,毕竟高一班主任作为英语老师也没多说什么。

感谢姆爷教我英语,尤其是口语的连音、节奏,当然还有一些词汇。

2014年6月21日 星期六 +7000

大约从这里开始,很多东西真的算作“有据可查”了。这只是因为我的手机里保存了所有微信的聊天记录,但我已经弄不懂怎么找回 QQ 的聊天记录了——到底是要充什么样的会员、输入什么样的密码、审核什么样的证件?感觉早就跟不上 QQ 的更新速度了,但可能它也没想让人一直跟上,只要一直有人跟得上就好。

前几天有个同一级的山东女生问他一些关于数算的问题。他似乎懂得一些大道理,但毕竟当学期只在学程设而下学期才会学数算,就只能支支吾吾、似懂非懂。坐在46楼2067的门后的时候,总觉得自己应该多带电脑出去自习,但电源是那么难获得,电脑又是那么怕丢——总归是不方便。就没想过要找个人一块去?

今天早饭吃了一个小白房的鸡腿饼,甚至还喝了豆浆。吃的时候又在想那个建立“野鸡中学在北大”群的想法,就是把没有什么高中校友的同学们聚集起来,进群标准是近十年加起来不能出超过十个清北。但他终究还是没在 BBS 上发出这个帖子,好像觉得是在自贱身份还是什么。而这个想法再次出现的原因是前几天考完试那些大神们又在阳光下的二教外谈笑风生了,说不出话的他只想骑着车风一般地穿过他们。

选专业的时候好像也没问过谁,就确定要撂下三个选计算机的室友去智能系;最后保留原来宿舍的申请也没有得到批准但新宿舍也还挺好。想来去智能系不是一个非常错误的决定,也许躲开了一些不那么相关的课程,获得了一个不错的绩点,也及早开始接触了图像处理相关的研究。

听说大二上会有那个叫做 ICS 的很难课,听说军训非常晒,听说要早点开始科研。

2017年3月17日 星期五 +8000

最后一个学期,跟她一起选了一门有五百人还是三百人的课。上课时间是晚上六点二十(当然有可能记错,也很有可能是星期二而不是星期五,但都不重要),上课地点是在理教108——似乎刚来的时候信科有什么迎新讲话也是在这里讲的,当时领导的名字还挺搞笑。他跟往常一样五点去吃了晚饭,大约是去学一吃的,似乎有许多住在同一个宿舍楼上的人非常不经常去学一。提前一小时到达教室的时候毫不意外地发现前八排的座位都被占了。但这不重要,反正在大四下这个阶段坐在哪里听课都没什么区别,于是在第十三排靠过道的地方坐下并占了一个座。同学们陆陆续续地来了,她也在六点零三分的时候到达并看到了他。他的眼前闪现过三个学期前自己在一个并不活跃的群里偶然问起的“有没有人上艺术史”的问题,然后就是在迟到的情况下从中门步入仅有投影仪照明的二教205,并摸黑找到给自己留座的人的。“真的有三个学期了。”这句话一直在脑中游荡,但似乎这句话又在呵斥他:“三个学期都被你浪费掉了。”于是就听课,听完以后陪她骑车回到宿舍楼下然后自己回去,毕竟也很近。但你我至少往后,成为了密友。

最近去过几趟紫竹桥。紫竹桥其实是个不太复杂的立交桥,但给人的印象确实是带些紫色,有一种紫甘蓝的感觉,但神奇的是这个感觉完全来自于名字。可能是因为“紫”这个字在地名中确实不容易出现,而其颜色又特别强烈吧。从小西门骑车过去大约要二十分钟或者更多点,尤其是在车子并不那么听话的情况下。他到现在还是不知道自己的车铃为什么消失了,但是已经养成了用嗓子当铃铛的习惯——这当然不是说他有银铃般的嗓音——也养成了转弯打手势的习惯——而后者事实上有助于他熟悉将来的欧洲生活。但骑出这二十分钟,就已经到了一个陌生的城市了,所有的街道店铺都要重新识别定位,过马路的时候不知道哪个方向的红灯长,也不知道在自行车道和人行道是绿灯的时候会不会有右转甚至左转的汽车来抢道。在等红灯的时候,他的视线是想散一散焦的,但好像很难做到;信号灯在视野里仍是锐利的圆形,而背后的天空挂着阴沉的云。但试过散心旅游,如何答没有。

回到宿舍后他发现收到了一封邮件,是一个叫做 WOKO 的机构发来的,听说是给学生租房子的。于是他就填表了,但租房子好像并不是他现在最挂心的事情。这当然是不对的,租房子是非常需要挂心的事情,但在当时他心里也只有一个念头。爱若难以放进手里,何不将这双手放进心里。

幸好事情起了变化。幸好心情能够对称。幸好磨合快过摩擦。

幸好还有 Eason 教我唱歌。

2019年12月12日 星期四 +9000

好了,现在我们有 reference 了。我很相信,当时写的是当时觉得有必要写的,日常的并没有写下来的必要。但现在能够认识到这种行为的片面性,毕竟,“日常”也是可以发生突变并且屡次突变的。

他与她上次见面到现在有三十六天了。早上从 T35 的楼门口出来,走一个下坡去坐7路电车,这样的日子已经过了一年半了,有时会在车站的小超市买包饼干或者买瓶饮料。问题是,如果他知道这三十六天未见将会延长至四百八十五天的话,会不会不买饼干而买水果呢?

他收到她的 vlog 的时候,正好是对研究的问题产生了一点想法的时候,也正好是开始喜欢喝气泡水的时候。当时手头的实验距离成形还有很长的距离,手头的空瓶子却越来越多;而他自己似乎并不完全具备在 blog 里面写过的那种紧迫感,每周都会给自己的项目网站上加记很多东西,但有多少算是进展,又有多少算是绝无可能全部实现的扩展思路呢。问题是,如果他知道这一个想法最终真的能成文,但成文需要花三次投稿、一年半的时间的话,会不会不喝气泡水而喝自来水呢?

晚上快九点的时候他从办公室出来,再坐7路回家。走过一个上坡之后,在 T35 的楼门口走过密密麻麻的门铃,再进门看一眼自己的信箱是否收到任何信件。当然没有,他很少订阅什么东西,于是在生日的时候都不会收到什么推广消息,更别期待有人记得他这种奇怪的纪年法。但今天有人记得了,还给他发了一个视频。“也一定要学会制造一些惊喜。”问题是,他制造惊喜花的心思再多,又怎能与真正的举家搬迁相比呢?

能够孤身来到陌生语言环境的人都是侠客,而她又要比他有侠气得多。流离在某月某天某地,仍自觉共你一起。

2022年9月7日 星期三 +10000

有的人是可以在这种突变中努力维持自己正常生活的样子的,而我不是其中一员。在家办公也好,在办公室干活也罢,很难说一种比另一种更适合我;难以从国内再获得补给,就更加努力地发掘一下本地超市的东西;与她无法见面,就努力寻找虚拟的游戏、学术的视频聊天和非学术的 PPT 带来的乐趣:这一切也都可以接受。至于把头发留起来,那大概是我一直以来都想做的事情吧;当时也想到过什么“直到发了一篇论文就把头发剪了”之类的,但好像这个赌注并不起作用。在留到古美门的发型的时候,模仿他的手势拍了个照片;再长一点的时候戴发带坐车上班还去了德国,也不觉得有什么太大的问题;而现在每次在街上看到发型独特的人,甚至还能产生一些共鸣。我问过自己很多次,如果疫情没有发生,我会把头发哪怕留到刚刚可以弯曲的程度么;而每次的答案都是恐怕不会。于此而言,一方面要承认许多事情就是不会有时机去做,另一方面则还是要仔细考虑前面的这个承认会不会被当做借口去得过且过。

曾经拍过自己刚落地的时候第一次乘瑞士火车的样子——那大概是正好五年零两天前吧——又或者只拍了红色的车门和车门上绿色的按钮。现在还是会想拍这些不带人、不包含景点也没有艺术性的照片,只是现在理解了原因:在一定的时间之后,它们可以恢复自己的视角,从而恢复或者触发记忆中的场景。可笑的是找房子的时候拍下的照片似乎也都属于这一类,它们可以跳过什么视角什么场景而直接触发紧张的情绪。

从现在的视角看,2019年12月12日的那班7路电车像是《千与千寻》里的水上列车一般,与现在间隔的不只是一千天的时间,还有一整个“本应该”的世界。对于不同的人来说,能够定义“疫情前的世界”的时间锚点或许是2020年元旦的清晨、2019年圣诞的前夜,又或是出国旅行的起飞前、回家过年的吵闹后;而拜自己的 blog 所赐,这个双十二就是我的锚点。记忆回退到这时,总能看到完全不同的下一千天;而它与现实世界差别之大,好像在一条向前推进的长河中被龙卷风拽着直插云霄。但只要河足够宽,被卷起的水滴还会变成长河的一部分的。而我们只能尝试着识别、调整和改变,在这个过程中更深刻地理解自己,理解自己在如今或者从前的重大事件当中的做法和想法的原因。

而对自己、对他人的理解力的迅速发展,如果不是完全在亲密关系中习得,也是深受她影响的。若问世界谁无双,会让昨天明天也闪亮。

后语

如果真的按照十进制的天数去计算生命的话,大约没有比达到一万天更值得纪念的了,毕竟在可预见的将来都达不到下一个数量级了。但这样是否意味着今天的纪念会变得正式得多呢,也就不会有这种空闲来胡言乱语了。那时我大概会开始计小时、计分、计秒了——甚至可能发明一个叫“年”的东西然后来计一计。

如果一千天才能庆祝一次,时间跨度未免过于长了;一百天又嫌太短,好在一年是三百六十多天;同样因此才可以有幸在不同年份的春夏秋冬来给大家讲一些以自我为中心的、夹叙夹议的故事。不敢假定读者是什么感觉,但能够迫使自己把模糊的记忆落在纸上,这一点就已经让笔者满意了。

如果有最后一点值得庆祝的事的话,那就是要庆祝已经不需要再想自己应该成为什么样的人了——已经可以用自己来定义“像我这样的人”了。

9000

一天晚上回家路上,在电车里迷迷糊糊的时候,一个念头曾经闪现过,就是自己什么时候该到9000天了呢。于是就在脑子里试图计算24×365+6到底是多少,不知道有没有显露出Joey的迷惑脸,却着实让自己从迷糊的状态缓缓睡去,迷糊过后也,就忘了这件事。虽然是很重要的事,但是从自己不写日志开始,对天数的敏感性也就在下降了。大概会来的吧,来的时候我会想起来吧,我这样想。

突然收到喵的vlog,是至今为止我最大的惊喜了吧。应该是第一次看vlog,我坐在办公室的椅子上感动得无以复加,险些哗哗掉泪,甚至不敢看多几遍。

这时候,才想起来之前算过却忘掉的日子原来是今天。上一篇日志还是跟喵去日本的时候写的,竟然已经七八百天了。期间也并不是没有写东西,只是自己想从QQ空间挪到自己的网站,却只能在每次自己的网站上发布1篇文章然后就作罢了。这不好。

9000天的人了,大孩子了,人模狗样,有办公室,有俩电脑。在这里也呆了两年有余了,却刚刚开始上德语课而且还一脸懵逼不知道老师在讲的什么。其间也去过一些地方,跟喵一起逛来逛去的时候是最开心的了。游记也写了一些,信也寄了一些,但是忽然感觉把生活给别人围观会让自己有点不舒服,但是其实大家乐呵乐呵也是有益处的吧。看我说这些废话,不发就不发啊。更重要的原因,也许是现在不再需要向大众去寻找理解和安慰了吧。但是写点别的还是不错的吧,又不是说每次敲字都一定要针对自己的生活大发议论。

苏黎世有它的矛盾之处:平时秩序极其井然,去到别的城市都会想念这种公交车也准点到可怕的秩序;一年中却总有些极其奔放的时刻,在最繁华的地段,秩序完全让位于唱唱跳跳吃吃喝喝。他们似乎一有机会就会涌上街头五彩缤纷地载歌载舞,电车也乖乖改线,这大概是一种调节的艺术吧。——不过还是有两列火车撞在一起造成一两人受伤这种情况的。

话说,可不可以讲我现在“奔万”了啊。“奔三”听起来总是不如“奔万”有奔头嘛不是。人的这一辈子,能记住的出生天数的位数发生改变,也就只有一或两个,这还得取决于记事早不早——我大概属于只有一个的那一类人。

于是一万天的目标就是顺利毕业。说起来容易做起来当然有难度,但是可以说还是很有希望的。当然,这是较小的目标,大目标说起来另有所在。其他的小目标包括跟喵再多走一些国家和地区并体验多个海拔的活动,多锻炼身体(always & finally),会一些德语和少量的法语,少扫雷但是要高质量地扫雷,适当地写写blog、或许拓展到vlog,如此种种。总之是,要做一个积极的人;消极状态有它存在的道理,但对自己或是任何关心自己的人都没有好处。

关于自己就不多写了吧,今天看到了贵校新出的瓜,看了那些聊天记录,有些反胃。自己绝对不会变成这样的人,也容忍不了这样的人。另外,尤其希望贵省把他开除省籍。不,希望贵物种把他开除人籍好了。

对了,最近期的目标是学习怎样制造惊喜。

Git Tips

This post is mainly a reminder of some errors I have encountered with Git. Writting things down may help me avoid recurrent errors :)

GIT push: permission denied (public key)

  • Happened when I wanted to git push.
  • stackoverflow
  • Need to set up the SSH key and add it to Github (or wherever your remote is).
  • I was surprised when finding out that I didn’t do it on my laptop!

src refspec master does not match any.

  • Happened when I wanted to git push. When creating my github.io repo, I didn’t follow the process of forking the template and then modifying. I cloned the original repo, modified it and then wanted to push to the origin to the empty github.io repo that I created. At first it didn’t work because the origin still points to the original repo which of course I cannot write to. Then I changed the origin by git remote set-url and it gave me this error. I thought it was because of not forking the repo, so I followed the recommended path again. But this error still persisted.
  • stackoverflow
  • Turned out that the forked repo did not have the master branch, only a gh-pages branch. I need to specify the branch name…

Miscellaneous

  • show changes on a file before commit, before/after add git diff file shows diff of a file from the previous commit. git diff --cached file after add
  • show refs: git show-ref
  • git clone submodules git clone --recurse-submodules -j8 git://github.com/foo/bar.git
  • update submodules: commit in submodule, push in submodule, commit in main repo, push in main repo. (not validated yet)
  • git push <remote_name> --delete <branch_name> deletes a remote branch. git branch -d/-D <branch_name> deletes a local branch. -D forces the delete.
  • git cherry-pick <commit> applys the changes introduced by commit on top of the current branch. I used that a lot. Probably it is very bad…
  • git config --global alias.co checkout set a global git shorthand.

(Background image credit: video)

Denoising Monte-Carlo Renderings with Kernel Predicting Convolutional Network

写这个之前的心理:如果不写,那么10月份就没有post了。。。结果还是拖过了10月。

本文是对于SIGGRAPH 2017的论文 Kernel-Predicting Convolutional Networks for Denoising Monte Carlo Renderings 做的中文简介。该论文提出使用Kernel-predicting convolutional network (KPCN) 对路径追踪(path tracing)算法渲染得到的图片进行去噪(denoising),即CNN输出并不是直接得到去噪后的图片,而是对每个像素位置获得一个filter,然后用这些filter对于输入图片进行逐像素的滤波,得到每个像素最终的RGB值作为输出。该方法在一个数据集上进行训练之后,可以迁移到场景差异很大的另一个数据集上获得较好的结果。

算法流程

Fig

输入图片首先被分成Diffuse(漫反射)和Specular(镜面反射)两个分量,分别进行去噪。图像是HDR的,没有最大的像素值限制。这两个分量之和是原图像(diffuse+specular=color)。

同时作为网络输入的还有场景中的其他一些特征,如albedo(反射率)、normal(法向量)、depth(深度),同时对于这些color channel和feature channel,每个像素的方差(variance)也作为特征。输入数据共有18个channel:diffuse(3+1), specular(3+1), albedo(3+1), normal(3+1), depth(1+1)。

然后是预处理。Diffuse分量要除以albedo,specular分量经过对数变换(logarithmic transform),两个分量均经过normalization和gradient extraction的步骤,得到最终输入的diffuse和specular分量。Feature channels不做预处理。这些预处理的变换在得到输出图片的时候均会被还原(逆变换)。

第三步便是经过一个CNN得到输出结果。这个CNN在本文中显得反而不那么重要,也并不是什么fancy的结构。本文着重对比了两种情况,一是直接预测去噪图片(direct prediction,DPCN),二是kernel prediction(KPCN)。在kernel prediction时,输出21x21的滤波器,即CNN输出有441个channel。然后用这些滤波器对每个像素的邻域做滤波,得到输出的像素值,即以下公式:

其中$p$是一个像素点,$c(p)$是$p$处的颜色值,$q$是$p$的邻域中的另一个像素,$w_{pq}$是CNN在$p$处输出的滤波器在$q$位置的权重。得到的$\hat{c}_p$就是去噪之后$p$处的颜色值。

最后,训练使用的loss是预测的图片与reference(也就是ground truth)图片之间的$l_1$-loss。

看完这个流程之后,大概会有两个问题:

  1. 为什么有这么多feature可供使用?一般的denoising,也就只有noisy image作输入。
  2. 为什么要用kernel prediction这样复杂的流程?直接输出个图片不好吗?

这样的feature,我还能有一大把

这是由于我们进行去噪的对象是Monte Carlo rendering,也就是渲染得到的图片。具体而言,这些图片是通过路径追踪方法渲染得到的图片。这种方法是基于渲染方程(rendering equation),从摄像机开始发射一条路径(path),在场景中不断反射,寻找光源,计算沿着该路径会有多少光(radiance)传到相机里。如下图(来自scratchapixel.com

由于是渲染图片,场景是已知的,但场景信息不容易直接encode给CNN(首先维度就不一样高)。所幸,在path tracing这个算法中,我们的path会不断与场景发生交互(即不断反射),在每次交互的时候,就可以获得场景的一些信息。我们得到的albedo、normal、depth等feature,就是在这个path第一次反射时,反射面的一些性质。利用这些feature,CNN可以了解哪些像素点的范围内是同一个物体,哪些像素点比较贴近图片中的edge,从而更准确地做出预测,不管是直接预测颜色值,还是预测使用邻域中的哪些像素来估计当前像素的值。

注意,我们只使用了path第一次反射时的特征,而一条path会在场景中反射很多次,所以事实上我们还有很多可以使用的特征。但是使用过多的特征会出现边际收益递减,作者经过试验后使用了18维的输入。

Kernel prediction可以加速训练

作者分析了KPCN和DPCN的效果差异,列在Fig 9里。结果表明KPCN的训练速度是DPCN的5-6倍,效果也较DPCN好一些。

究其原因,事实上KPCN对于每个像素,把滤波器的权值限制为非负并且加和为1(使用一个softmax层就可以做到)。这样使得每个像素的输出被限制在其邻域的像素值的凸包之内,缩小了搜索范围,提高了搜索效率。DPCN没有输出限制,于是搜索空间过大,训练不稳定且较慢。不管是用什么loss,如果输出范围过大,神经网络就很容易在ground truth两侧震荡,难以收敛。

KPCN事实上是受到Monte Carlo rendering denoising的前人工作启发,只在每个像素邻域内预测一个滤波器就足够了。DPCN所具有的自由度,对于去噪这一个特定任务,而且是十分需要细节的任务,并不占优势。

一点感慨

  • 能够得到好结果,数据预处理十分重要。对于Diffuse和Specular进行分别的预处理,对于这两个分量的去噪都有决定性的意义。参见Figs. 10-13.
  • 不同的数据,需要使用不同的方法,尽管task是一样的。
  • Disney有那么多电影的渲染数据可以用真是好啊,别家也没条件做出这种东西来吧233。
  • Rendering也被CNN入侵啦!快跑啦!

Excel Tips

Sometimes I have to do some Excel operations. They say it is not good to show that you know Excel on your resume, but I do think sometimes it is handy :)

Functions / 函数

线性插值TREND

trend([known_y], [known_x], new_x) performs (least square) line fitting on known_y and known_x as \(y=ax+b\) and predicts the \(y\) value of new_x.

Shortcuts and quick settings / 快捷键及快速设置

  • 重新计算所有公式, recalculate all formulae: Ctrl+Alt+Shift+F9.
  • 多列/行自动列宽/行高, automatic column width (or row height) for multiple columns (rows): Home->Cells->Format->Click!

Charts / 图表

制作带阴影的折线图

  • 要求:给两条折线A,B中间夹的部分绘上阴影。
  • 做法:
    1. 百度经验。用A,B画面积图(而不是折线图),将下方的折线(如A)对应面积图的填充颜色设为白色(或背景色),就可以得到阴影图。 问题:如果背景有其他图表则会覆盖住其他图表。
    2. 百度经验里也有…百度还是有点用的。 English 利用堆积面积图,首先计算B-A,而后用A和这个差值制作堆积面积图,而后将A代表的面积块的填充色设为透明即可。需要较新的Excel版本。

(Background image credit: video)

YAML Custom Features

In this short post I changed the title that is displayed on the front page from YAML Custom Features to YAML Features.

---
title:             "YAML Custom Features"
menutitle:         "YAML Features"
---

I also added a redirect to this post. If you browse to YAML-Feature-Redirect you should be redirected to this page. This only works if you have not removed the plugins.

---
redirect_from:     "/YAML-Features-Redirect"
---

If you like to redirect from multible sources you can specify it as an array.

---
redirect_from:  
  - "/YAML-Features-Redirect/"
  - "/blog/old-category/YAML-Features/"
---

I also changed the cover image for this block via YAML.

---
cover:         /assets/mountain-alternative-cover.jpg
---

To generate keywords for the search engines I use the tags that you specify in the post. If you are writing a page you need to specify keywords instead of tags.

---        
tags:          Jekyll YAML Features Explained  #Only used in posts!
keywords:      Jekyll YAML Features Explained  #Only used in pages!
---

Post will be sorted by category on the front page. This is how you define the category in YAML.

---        
category:     Readme
---

On a page I have additional options. For instance I can hide the page from the menu by setting the visible tag to false.

---        
visible:       false     
---

If I like to have the page in the menu I can add weight to the page in order to specify a position in the menu.

---        
weight:       5  
---

The default language of your blog is defined in the _config.yml file but if you like to write a post/page in another language you can use the language attribute. This will specify that you are using another language on this page for search engines. Please use on of the language codes as value.

---        
language:       en  
---

You can enable disqus comments in posts by adding comments to the page. To configure the disqus forum you need to modify the disqus_shortname in the _config.yml file.

---        
comments:       true  
---

If you like to write some formula you can enable MathJax. Go to the theme feature post to see it in action. You can find the preprocessing options in _includes/mathjax_support.html.

---        
math:           true 
---

If you are writing a scholar article and like to add bibliographic metadata you can use the following YAML. This makes your article searchable at Google Scholar.

---        
citation:
  author: 
    - "Doe, John"
    - "Roe, Jane"
  publication_date:    "1996/05/17"
  online_date:         "1996/06/22"
  title:               "title"
  conference_title:    "conference_title"
  journal_title:       "journal_title"
  volume:              "271"
  issue:               "20"
  firstpage:           "11761"
  lastpage:            "11766"
  pdf_url:             "/media/scholar_article.pdf"
  pdf_url_dynamic:     true                            #true: http://your-domain.com/[pdf_url]
  issn:                "1234-5678"
  isbn:                "0-2345-6634-6"
  institution:         "institution"
  report_institution:  "report_institution"
  report_number:       "12345678"
---

Additional features, that can be specified, can be found in the YAML Front Matter documentation.