人脸搜索不比较图像。它把每一张脸转换成一串固定长度的数字——也就是向量——然后比较这些向量。同一个人相隔数年、在不同房间里拍的两张照片,即使像素几乎没有任何重合,产生的向量也会挨得很近。

搞懂这四个阶段,你就能准确说出为什么有些截图一传就中,而有些不管重试多少次都不行。

第一步检测,发生了什么?

检测回答的问题比大家想的要窄:这张图里哪儿有一张脸,它的五个关键点在哪儿?

检测器扫过图像,对找到的每一张脸返回一个边界框,外加五个关键点坐标——左眼、右眼、鼻尖、左嘴角、右嘴角。这一步我们用的是 YuNet。到这里为止还没有任何跟身份有关的事情发生;这纯粹是几何。

如果检测失败,后面所有环节都跟着失败。而检测失败的原因,跟通常意义上的画质完全无关:一只手挡住嘴、一个彻底的侧脸、一张小于检测器最小尺寸的脸。

第二步对齐,发生了什么?

对齐利用那五个关键点,把脸形变到一个标准位置——两眼在同一条水平线上,落在固定坐标,缩放到固定大小。

这一步就是为什么歪着的头和正面的头能被拿来比较。进入编码器的每一张脸,姿态相同、尺寸相同、裁切的区域也相同。注意这次裁切丢掉了什么:大部分头发、衣着、背景、房间。这些都不属于身份信号。

它也解释了一个常见的挫败感。如果关键点稍微偏了——比如有一只眼睛被遮住——对齐就会把脸形变错,而由此得到的向量会以一种「看起来很笃定」的样子出错。

第三步编码,发生了什么?

一个编码器网络把对齐后的脸变成一个由 512 个数字组成的向量。这一步我们用 ArcFace。这个向量就是这张脸的数学描述。

真正让它有用的是训练目标:网络被训练成让同一身份的向量紧紧聚在一起,让不同身份的向量互相推开。它不是被训练来描述一张脸长什么样的;它是被训练来描述这是谁的。

阶段 输入 输出 什么时候会失败
检测(YuNet) 完整图像 边界框 + 5 个关键点 脸被遮挡、太小、角度太偏
对齐 边界框 + 关键点 标准化的人脸裁切 关键点不准
编码(ArcFace) 对齐后的裁切 512 维向量 裁切画质差、模糊,或压缩过重
比对 向量 带分数的排序列表 不会失败——它永远会返回点什么

最后一行才是要紧的,值得单开一节。

第四步比对,发生了什么?

比对计算你的向量与索引中每一个向量之间的余弦相似度,然后按由近到远返回最接近的那些。

余弦相似度的取值从 0 到 1,描述的是两个向量之间的夹角。在我们的数据上,针对视频截帧标定的阈值是 0.40。高于它,就当这一对大概是同一个人;低于它,结果不过是恰好排在最前面的噪声。

最后这一点是向量检索最容易被误解的地方:**它永远不会返回空。**你向它要十张最接近的脸,它就给你十张,哪怕正确的那个人根本不在索引里。分数是唯一能把真答案和「现有最接近的陌生人」区分开的东西。一份不带分数的排序列表是没法读的。

为什么是索引决定了什么能被找到?

因为比对只能对已经编码过的东西排序。索引不是对整个网络的搜索;它是一组事先算好的、固定的向量。

我们这一份里有 241,792 张脸,其中 2,333 张挂着有名字的女优,取自 106 个站点的封面与截帧(我们的索引,2026-08 快照)。由此直接引出两个后果:

  • 一张脸如果在索引里、却从来没挂上名字,返回的就是一个无名身份。这很常见——光是我们的相似女优数据里,就有 7,004 条引用指向没有名字的身份
  • 一张压根没被索引过的脸,无论分数多少都不可能被返回。工具仍然会把它最接近的几个猜测摆给你看。

**有一条边界值得说清楚:**我们的来源很集中。有名字的女优里,2,333 位中有 2,246 位的代表图来自同一个站点。因此覆盖面反映的是这些来源发布了什么,而不是整个行业的产出。

这跟以图搜图有什么不同?

以图搜图找的是你整张图片的副本。人脸搜索找的是同一个身份在不同图片里的样子。它们成功和失败的条件正好相反。

以图搜图 人脸搜索
比较的是 整图指纹 人脸向量
需要这张图原样存在于网上 需要 不需要
裁切到脸部有没有帮助 没有——反而更糟 有——那正是它要的输入
扛不扛得住不同的光照和姿态 很差 设计上就是为此
对你自己截的一帧画面管不管用 不管用 管用

如果一个工具在你裁切到脸部之后反而变了,那它做的就不是人脸搜索。这是一个很可靠的一步诊断法。

相关问题


理解这条流水线最快的办法就是看它跑一遍。在这里上传一帧画面:检测和对齐在你的浏览器里完成,只有裁切出来的人脸区域和它的五个关键点会被送去比对,原图永远不会离开你的设备。