如何快速从大型数据库中查找人员?

数据挖掘 大数据 图像识别 搜索 可扩展性
2021-09-26 16:35:14

词汇

  • 人脸检测:查找图像中的所有人脸。
  • 人脸表示:表示人脸的最简单方法是作为图像(像素/颜色值)。这不是很节省空间,并且可能会使后续任务变得困难。人脸嵌入是另一种表示。在这种情况下,面是单位球面上的一个点R128,IIRC。
  • 人脸验证:给定两个人脸表示,判断它们是否相同

问题

我只是想知道如何识别一个有很多潜在人的人。因此,对于大多数应用程序而言,在图像中查找人脸效果非常好,速度也足够快。人脸验证也是如此。但是,如果您不将 1 张脸与其他 1 张脸进行比较,而是将 1 与数百万张/数十亿张脸进行比较,我不确定如何进行缩放。

假设您有很多具有该人身份的面孔示例。想想 Facebook,许多人在其中标记了朋友。或拥有生物特征护照的国家。

在实际应用中,人脸验证任务很简单,因为您可以与所有候选人进行暴力比较:

  • Facebook:只有候选人是你的朋友,所以大约有 200 位候选人。
  • 欧盟机场快速入境:将您的脸与护照进行比较。所以只有一名候选人。

但是再想想一些反乌托邦书籍/电影,相机可以识别任何人。虽然跟踪有助于减少该问题,但从数百万/数十亿的示例中找到匹配项的计算量非常大。假设一个人脸验证需要大约 200 毫秒,对于一百万个候选人,它已经需要 60 小时。对于 10 亿用户来说,这已经是 6 年了。对于地球上所有目前生活的人来说,它是 48 岁。

因此,对于这么多候选人,您不想与所有候选人进行比较。

当你使用人脸嵌入时,它变成了最近邻搜索R128.

计算两个向量的欧几里得距离R128大约需要 15μs(参见下面的“时序”)。这意味着一次检查7.5109人们需要 31 小时。好多了,但还是很长。

虽然人脸嵌入方法预先计算出良好的人脸表示,但遍历所有示例仍然是一种非常愚蠢的方法。如果只是R1,可以制作一棵简单的二叉树。对于几个维度,我认为像 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,
              ))
3个回答

那就是问题是呼叫识别,将感知映射到特定实体。

一个常见的选项是散列,获取感知并将其映射到特定的唯一整数。如果两个不同的感知映射到同一个整数,它们是同一个实体。如果两个不同的感知不映射到同一个整数,它们是不同的实体。无论有多少实体,散列查找一个实体都需要一定的时间。

在面部识别的情况下,哈希函数最好通过深度学习来学习。

你可以逐步做到这一点。例如,您可以对嵌入进行聚类并尝试对种族、性别和年龄进行分类。

然后你只需要搜索那个种族、性别和年龄的人。

类似的程序减少搜索区域。仅按性别,您已经将比较次数减少了一半,年龄可以帮助您将其分为(假设您使用 10 年)大约 11 个部分(大小不同,但仍然是一个很好的改进),您可以减少它进一步通过种族分离。

世界人口统计资料(维基百科)

年龄:根据 2006 年 CIA 世界概况,世界上大约 27% 的人口年龄在 15 岁以下。

  • 0-14 岁:26.3%(男性 944,987,919/女性 884,268,378)1
  • 15-64 岁:65.9%(男性 2,234,860,865/女性 2,187,838,153)1
  • 65 岁及以上:7.9%(男性 227,164,176/女性 289,048,221)(2011 年估计)1

性别:这可以通过一半/一半分布来近似

民族:最大的民族是汉族(汉藏 -> 中国人),拥有 13 亿成员

所以,在最坏的情况下,你有一个 15-64 岁的世界人,男性或女性,来自汉族

1.3×109×0.5×65.9%=428.35×106 people

使用您的时间估计 15μs 我们有:

15×106×428.35×106=1.78 hours

第二个最坏的情况是同龄的阿拉伯人,这需要大约 37 minutes 对于英国来说,大约需要 18 minutes

这仍然是一个缓慢的过程,但您可能可以在这个大组中找到集群,以进一步减少搜索时间。

我认为将 15-64 岁分为至少 3 组是可行的。如果可以做到这一点

您对 kd 树的想法是正确的。基本思想是,您不必在每次进行查询时都为每个人脸计算嵌入——您需要保持数据库最新并将已经计算的嵌入存储在索引中。当您获得“查询”(一张人脸的新照片)时,您会为此生成嵌入,然后在索引(可能是 kd 树)中搜索该新嵌入附近的嵌入。您还可以拥有多个索引,因此如果在伦敦发现了人脸,您可以首先查询仅涵盖可能在伦敦看到的人脸的索引。

您工作中最困难的部分可能是创建一个好的嵌入,您可能会通过使用神经网络生成高维嵌入然后使用流形学习将其映射到更小的嵌入来创建它(例如 t- SNE 或 UMAP)。

本文是关于使用类似方法的团队:https ://datascopeanalytics.com/blog/building-a-visual-search-algorithm/