技术方案写到第三天,出了大问题。
明诚盯着屏幕上的报错信息,已经看了二十分钟。数据融合模块的核心算法跑出来的结果全是乱的,高峰期车流量算出来是负数,低峰期是正数,完全反了。他重新检查了公式,代入了三组不同来源的数据,结果还是一样。不是数据的问题,是算法本身有逻辑漏洞。
欧阳旭从旁边探过头来看了一眼。“这个报错我没见过。”
“因为不是常规错误。是数学层面的问题。”
“那怎么办?”
“推倒重来。”
明诚的语气很平静,但欧阳旭听出了不对劲。他说“推倒重来”的时候,跟平时说“重启电脑”一样轻。但这个模块他写了四天,两千行代码,推倒重来意味着之前的工作全废了。
“要不要找钟离学姐看看?她不是做传感器的吗?算法也懂吧?”
明诚想了想。钟离瑶是物理系的,数学底子应该不差。但现在已经晚上九点了,叫她来不太合适。“明天再说。”
“你今晚打算写到几点?”
“写完再睡。”
欧阳旭看着屏幕上密密麻麻的代码,叹了口气。“那你加油。我去买点吃的给你。”
他走出实验室。门关上了,房间里只剩明诚一个人。他靠在椅背上,取下眼镜擦了擦。眼镜片上有指纹,是他刚才揉眼睛留下的。这几天连续熬夜,眼睛干得不行。但脑子更累。不是累在写代码,是累在想。想算法哪里错了,想怎么改,想明天能不能改完,想清仪会不会担心。
手机震了。清仪发来一条消息。“还在实验室?”
“嗯。”
“吃饭了吗?”
“吃了。欧阳旭带的小笼包。”
“你又在骗我。你每次说吃了的时候,都只吃了一半。”
明诚看了看桌上剩下的小笼包。四个,凉了,皮硬了。他只吃了两个。
“被你发现了。”
“你写到几点?”
“不知道。写完为止。”
“我过去。”
“别来了。太晚。”
“你一个人?”
“欧阳旭在。他去买吃的了。”
对面沉默了一会儿。“那我不过去了。但你写完告诉我。”
“好。”
“不许骗人。”
“不骗。”
明诚放下手机,重新戴上眼镜,盯着屏幕上的代码。从第一行开始看,一行一行,一个函数一个函数。看到第一百三十七行的时候,他发现了一个问题。权重分配那里,他用了一个归一化函数,但函数的输入范围没做限制。如果输入数据超出预期范围,输出就会变成负数。而他的数据正好在某些时段会超出范围,因为朝阳里社区的路况太极端了,高峰期车流量是平峰期的四倍,超出了模型的假设范围。
问题找到了,但不好改。归一化函数是整个算法的核心,改了它,后面所有依赖这个函数的模块都要调。相当于地基歪了,上面的墙全要拆。
他深吸一口气。拆就拆。
欧阳旭推门进来,手里拎着两个袋子。“我买了炒饭、饺子、还有可乐。你先吃,吃完再写。”
“不吃了。先改。”
“改什么?”
“归一化函数。地基歪了。”
欧阳旭看了看他的屏幕,又看了看他的脸。“你脸色很差。”
“没事。”
“你上次说没事的时候,晕倒了。”
“那是低血糖。吃了糖就好了。”
“那你吃颗糖。”
明诚从抽屉里摸出一颗硬糖,剥开,塞进嘴里。橘子味的,甜的。他嚼了两下,咽了。然后开始改代码。
十一点,门被推开了。明诚以为是欧阳旭又去买东西了,没抬头。
“端木。”
是清仪的声音。
他抬头。清仪站在门口,穿着睡衣,外面套了一件外套,头发披着,手里拎着一个袋子。她的脸被走廊的灯照得有点白。
“你怎么来了?”
“你说要写到写完为止。我猜到你会写到很晚。”她走进来,把袋子放到桌上,拿出一个保温盒,“给你炖了汤。”
明诚愣了一下。“你炖的?”
“宿舍有小厨房。公仪静教我的。”
“你什么时候学的?”
“今天下午。煲了三个小时。”
明诚打开保温盒。鸡汤,清亮亮的,上面飘着几颗枸杞。他拿起勺子,喝了一口。烫,但很鲜。
“好喝吗?”清仪问。
“好喝。”
“真的?你不是说太甜了吗?”
“不甜。咸的。”
“鸡汤当然是咸的。”
“所以好喝。”
清仪笑了,坐到旁边的椅子上。“你继续写,我在这陪着你。”
“你不用陪。回去睡觉。”
“不困。”
“你明天上午有课。”
“比较宪法。可以翘。”
“你不是不翘课吗?”
“为了你,可以翘。”
明诚看着她。她的眼睛在灯光下亮亮的,没有睡意,只有认真。她真的打算在这陪他一整晚。
“那你不许打瞌睡。”他说。
“你才打瞌睡。”
明诚嘴角翘了一下,转回去继续改代码。清仪坐在旁边,安静地看手机。偶尔抬头看他一眼,偶尔帮他倒杯水。实验室里很安静,只有键盘声和墙上时钟的滴答声。
十二点,门又被推开了。
钟离瑶站在门口,穿着一件深蓝色的卫衣,手里拿着一个文件夹。看到清仪,她停了一下。“慕容也在?”
“嗯。”清仪的语气很平。
“我来送传感器的详细参数表。端木说要今天给。”她走进来,把文件夹放到桌上,看了明诚的屏幕一眼,“你在改归一化函数?”
“嗯。”
“范围问题?”
“嗯。”
“我看看。”
明诚把屏幕转过去。钟离瑶看了一分钟,指着一行代码。“这里,你用线性归一化,但你的数据分布不是线性的。高峰期和平峰期的差距太大,线性归一化会放大误差。换对数归一化试试。”
明诚想了想。对数归一化能把大数值的差距压缩,确实更适合这种分布不均匀的数据。他改了公式,重新跑了一遍。
没崩。数据出来了。高峰期车流量不是负数了,是正常值。
“跑通了。”他的声音有点抖。
“正常。”钟离瑶笑了,“对数归一化是处理长尾分布的标准方法。”
清仪在旁边看着,没说话。明诚看了她一眼。她的表情很平静,但手指在膝盖上轻轻敲了两下。
“谢谢你,钟离。”明诚说,“改天请你吃饭。”
“不用。举手之劳。”钟离瑶拿起文件夹,“参数表放这了,有问题发消息。”她走到门口,回头看了一眼。“慕容,你炖的汤?闻着不错。”
“嗯。”
“他对吃的很挑。你能让他喝,说明炖得好。”
清仪没接话。钟离瑶笑了一下,走了。
门关上了。实验室又安静下来。
明诚看着清仪。“你刚才没说话。”
“没什么好说的。”
“她帮忙改bug了。”
“我知道。”
“你说过不吃醋的。”
“我没吃醋。”
“你的手指在膝盖上敲了五下。”
清仪低头看了看自己的手。“习惯动作。”
“以前没有这个习惯。”
“最近有的。”
“因为什么?”
清仪不说话了。她站起来,走到窗边,看着外面的夜色。
“端木。”
“嗯。”
“你觉得她刚才为什么要来?”
“送参数表。”
“参数表可以发邮件。不用大半夜送。”
明诚沉默了。
“她是来看你的。”清仪的声音很轻,“她知道你今晚在改bug,所以来了。顺便送参数表。”
“也可能只是顺便。”
“你信吗?”
明诚想了想。不太信。
“不信。”他说。
“那你打算怎么办?”
“明天开始,不让她来实验室了。参数表发邮件,讨论当面安排在会议室,你在场。”
清仪转过身看着他。“你这样会不会太刻意?”
“不是刻意。是边界。”
清仪的嘴角动了一下。“你什么时候学会设边界了?”
“从你开始。”
清仪走回来,坐到他旁边。两人并排坐着,肩膀隔了十厘米。
“汤快凉了,你喝完。”她说。
明诚端起保温盒,把剩下的汤全喝了。鸡汤有点凉了,但还是鲜的。
“喝完就回去睡觉。”清仪说,“代码明天再写。”
“还有一点没改完。”
“明天改。”
“今晚改完,明天就不用来了。”
“你改得完吗?”
“能。不多了。”
清仪叹了口气。“那你改。我等你。”
“你刚才说不困。”
“现在困了。”
“那回去睡。”
“不。等你。”
清仪靠在椅背上,闭上眼睛。睫毛微微颤动,呼吸慢慢变均匀。她真的困了,但不想走。明诚看着她,看了大概五秒,然后转回去继续写代码。键盘声轻了一点。不是故意的,是不自觉的。
凌晨一点半,明诚保存了最后一个文件,合上电脑。转头看清仪,她已经睡着了。头歪向一边,嘴巴微微张开,呼吸很轻。外套滑下来一半,露出里面的睡衣。浅蓝色的,棉质的,看起来软软的。
明诚把外套拉上去,轻轻盖住她的肩膀。
清仪动了一下,没醒。
他坐在旁边,看着她的睡脸。没有口红,没有表情,什么都没有,就是一张安静的脸。但他觉得好看。不是好看,是安心。看着她在旁边,心里很踏实。比代码跑通还踏实。
他拿出手机,拍了一张照片。不是偷拍,是记录。她说过,拍之前要告诉她。但她睡着了,没法告诉。明天再告诉她。
他靠在椅背上,也闭上了眼睛。
实验室的灯亮着,白色的光照着两个人。他睡在左边,她睡在右边。中间隔了十厘米。没人说话,也没人动。
凌晨两点,实验室的门又开了。
钟离瑶站在门口,手里拿着一杯咖啡。她看到了明诚和清仪,两个人靠在椅子上睡着了,肩膀朝着对方的方向歪着。
她站了三秒,把咖啡放在门口的地上,轻轻关上了门。
走廊里,她的脚步声慢慢远了。
咖啡的热气在冷空气里升起来,白色的,一小缕。