词汇
- 人脸检测:查找图像中的所有人脸。
- 人脸表示:表示人脸的最简单方法是作为图像(像素/颜色值)。这不是很节省空间,并且可能会使后续任务变得困难。人脸嵌入是另一种表示。在这种情况下,面是单位球面上的一个点,IIRC。
- 人脸验证:给定两个人脸表示,判断它们是否相同
问题
我只是想知道如何识别一个有很多潜在人的人。因此,对于大多数应用程序而言,在图像中查找人脸效果非常好,速度也足够快。人脸验证也是如此。但是,如果您不将 1 张脸与其他 1 张脸进行比较,而是将 1 与数百万张/数十亿张脸进行比较,我不确定如何进行缩放。
假设您有很多具有该人身份的面孔示例。想想 Facebook,许多人在其中标记了朋友。或拥有生物特征护照的国家。
在实际应用中,人脸验证任务很简单,因为您可以与所有候选人进行暴力比较:
- Facebook:只有候选人是你的朋友,所以大约有 200 位候选人。
- 欧盟机场快速入境:将您的脸与护照进行比较。所以只有一名候选人。
但是再想想一些反乌托邦书籍/电影,相机可以识别任何人。虽然跟踪有助于减少该问题,但从数百万/数十亿的示例中找到匹配项的计算量非常大。假设一个人脸验证需要大约 200 毫秒,对于一百万个候选人,它已经需要 60 小时。对于 10 亿用户来说,这已经是 6 年了。对于地球上所有目前生活的人来说,它是 48 岁。
因此,对于这么多候选人,您不想与所有候选人进行比较。
当你使用人脸嵌入时,它变成了最近邻搜索.
计算两个向量的欧几里得距离大约需要 15μs(参见下面的“时序”)。这意味着一次检查人们需要 31 小时。好多了,但还是很长。
虽然人脸嵌入方法预先计算出良好的人脸表示,但遍历所有示例仍然是一种非常愚蠢的方法。如果只是,可以制作一棵简单的二叉树。对于几个维度,我认为像 kd-tree 这样的东西可能会起作用。但是 128 维呢?
有没有另一种方法可以让这个人更快?
定时
import numpy as np
durations = timeit.repeat('np.linalg.norm(a-b)',
setup='import numpy as np;a=np.random.random(128);b=np.random.random(128)',
repeat=1000,
number=3)
print('min: {min:5.1f}μs, mean: {mean:5.1f}μs, max: {max:6.1f}μs'
.format(min=min(durations) * 10**6,
mean=np.mean(durations) * 10**6,
max=max(durations) * 10**6,
))