拿出手机、打开前置摄像头,在光线较好的地方按下按钮。该张照片会上传到服务器上。并不是把它们保存起来,而是要立刻用上一套算法。

这套算法的第一件事情并不是要看你长得多帅或者多丑。是找点。眼角、鼻尖、嘴角、下巴最低点、两边颧骨最高处。人脸关键点检测通常选取68个点,有的模型使用了106个点。两点之间距离也被计算出来了。眼睛的距离、鼻子的高度、人中段的长度以及下巴的角度大小。把这几个数据放在一起就形成了一个向量组。

向量就是一组数字,也可以看作是一串数字。例如你这张脸,在经过了计算之后,就变成了一串 [0.32, 0.78, 0.45, 0.91...] 的东西了。长度可以是128比特也可以是512比特。就是人脸特征嵌入。同一个体不同时间的照片、同一张照片不同时期拍摄的照片,在数学空间里它们之间的距离非常接近。不同人的眼睛之间的距离会变大。

明星的脸也被这样处理过很多次了。几十万张公开的剧照、红毯照、海报等都经过了相同的算法。每一个明星都会有一套或者几套标准向量。一些明星的造型变化很多,可能会有十几种不同的造型,包括不同的妆容、不同的发型以及不同时代的特点。数据库就放在那里,等你那串数字过去进行比较。

自拍测相似明星

比对的过程并不是简单的图像叠加,在高维向量空间中进行最近邻搜索。把你的128维向量扔进去了,系统就开始计算它与数据库中数以万计的明星向量之间的余弦相似度了。余弦值越接近于1的时候,两个脸之间的角度就越小,在数学上就更相似了。整个计算过程,从你点击上传开始到最后得出结果为止,一般都在300毫秒之内完成。超过这个时间段之后,用户就会感到不耐烦了。

返回的结果页面上,你会看到一张明星的照片,在图片下方会有一个百分比数值。85%是某某某,72%是某某某。该比例是通过余弦相似度来映射得到的。原始相似度为0.82可以被映射到85%,而0.65则会被映射到72%。映射函数各家调法不同。有的做的比较激进,相似度达到60%,就可以显示为80%。用户看着高兴。有的比较保守,相似度真的要达到90%,才会显示出90%。这要由产品经理来确定基调。

技术栈支持这套东西的是前端普通网页或者小程序、后端主要是卷积神经网络进行推理。人脸识别模型一般就是经过预训练好的,常用的有基于ResNet或MobileNet等结构改造而成的。训练数据为几百万张带有标签的人脸。训练的目标是使同一个体的不同向量之间的距离小一些,而不同个体之间向量的距离大一些。一次被烧毁的计算资源大约等于几百块显卡运行几天。

在结果页面上会显示,“你与迪丽热巴相似度为82%。”从算法的角度来看,并不存在审美的评判标准。它不会觉得迪丽热巴很美,也不会觉得你喜欢什么样子。它只会按照这128个数字来计算距离。把自拍照的角度歪一歪、灯光暗一些,那么相似度就会由原来的82%降到现在的60%,而这位明星也会由迪丽热巴变成了古力娜扎。因为输入向量受到扰动之后,最近邻检索的结果就发生了飞跃性的变化。

光的影响权重很大。顶光会使眼睛周围的阴影加深,算法提取出的眼部特征点的位置就会发生偏差。侧光会使一半的脸部轮廓线无法准确地进行判断。因此在前置摄像头自拍时,系统就会强制提高屏幕亮度作为补光灯使用。并不是要把人拍得一无是处,而是为了保证关键点检测的误差控制在像素级别之内。

明星数据库中的向量也并不是固定不变的,需要不断地进行更新和维护。新出的小偶像,今天刚刚登上热搜榜,明天就要把她的照片也加上去了。怎么加?找到一些正面的人像高清图片,进行一次特征提取,并保存下来。一些小偶像的照片被修饰得很厉害,算法提取出的向量和她真实的相貌之间可能存在差异。因此用户用自拍来比较,比出的相似度很低,没有人点击。没有点击就表示数据可能存在错误,需要更换图片来源并重新提取数据。

自拍测相似明星

用户的自拍照行为数据也会被记录下来。一张照片上传之后进行比对得出的结果,如果用户点击了“分享”或者“再测一次”的话,那么说明这个结果还可以。直接关闭页面就表示不满意的。不满意的状况中,有的是真的不符合要求,有的则是用户认为符合要求的明星数据库里面是没有的。数据越多,调整的方向就越明确。

整个过程中都没有人为地去评价“你觉得他像谁呢?”全靠向量计算。权威性不是来自于某位专家的意见,而是来自于数以百万计的人脸进行训练后得到的模型权重。权重文件是固定不变的,只有输入相同的图片时,才会得到一样的输出结果。可复现。这是由算法得出的结果,并没有带有感情色彩。

自拍的角度建议为:正面、平视、自然光。俯拍可以拉伸下巴线条,使特征点下移,从而很容易看出脸型较长的演员。俯拍会使额头显得更大一些,眼睛之间的距离也会变小一些。你认为是视角改变造成的,其实是因为在向量空间中坐标发生了变化。一漂之后,最近邻就会更换了。

有人尝试用宠物的照片来测试。算法也运行了,但是得到的相似度都比较低。由于训练数据都是人像,并没有见过猫脸或者狗脸的情况。硬要说的话,就找一个比较接近的明星向量来凑合表示一下。此时所显示出的结果都是纯粹的随机噪声,并没有多少实际的意义。

盯着手机屏幕上出现的结果的时候,感觉它有些像,但是又不完全一样。这是正确的感受。82% 的相似性表示,在 128 个维度中,有百分之八十的维度数值非常接近,剩下的百分之二十则存在一定的差别。差异主要是由于脸型的宽窄、嘴唇的厚薄、眉骨的高度等造成的。算法不会告诉你要找的是什么问题,它只会给出最后的结果。

整个过程只用了几秒钟的时间就完成了。手机发热一会儿,流量流失几十KB,在屏幕上面出现了一张明星的脸。觉得好笑的话可以截图发到群里。该行为就完成了闭环。