我有一组1900多个512维的面部嵌入/向量,我希望将所有相似的个体/面孔进行分组。此外,还有未知数量的不同面孔。
我使用了sklearn.cluster.DBSCAN,类似于PyImageSearch Face Clustering with Python中的建议。然而,它无法有效地进行聚类,返回0个聚类。我认为矩阵过于稀疏。我认为有几个选项:
- 计算1900个组合的欧几里得相似度 – 即使使用矩阵乘法也很慢,但它有效
- 采用降维/PCA将向量降至128维,并尝试使用DBSCAN
- 使用最近邻算法 – 我必须事先知道有多少不同的人
- 使用中文耳语聚类
我目前正在尝试不同的方法,但也许我错过了某个众所周知的方法/方法?
回答:
首先,我认为重要的是你要检查你的面部识别系统使用什么相似性测量来判断两个嵌入是否属于同一个人。有些引擎使用余弦相似度而不是欧几里得距离(例如Sphereface或Arcface)。
其次,我会检查面部识别引擎在考虑两个嵌入属于同一个人的相似性测量上的阈值。通常这是为了在标记数据集上平衡真阳性和假阳性而进行的。
利用以上两点,我将执行以下算法:
- 创建所有嵌入之间的相似性矩阵,一个1900×1900的矩阵,其中条目I,j的值对应于嵌入I和嵌入j之间的相似性测量。
- 使用适当的值(上述第二点)对矩阵进行阈值处理。矩阵中高于阈值的每个条目将获得1,低于阈值的将获得0
- 将阈值矩阵视为图的邻接矩阵,并运行图连通分量算法(使用BFS或DFS)来查找分量的数量。每个分量对应一个独特的身份。
关于第二点的一个说明:你可以使用一些面部识别数据集(如LFW或celeb a)自己找到阈值,并通过平衡FP和TP来决定如何微调阈值。