You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

dlib人脸识别中Cosine Similarity大于1的问题及正确计算方法

如何正确计算人脸识别中的余弦相似度?

我在VS Code中使用dlib进行人脸识别测试,原代码以欧氏距离(Euclidean distance)小于0.6判定为同一人脸。编写了计算Cosine Similarity的代码,但得到的结果大于1,结果明显有误,请问如何获取正确的Cosine Similarity?

相关代码:

fig, ax = plt.subplots(1, figsize=(20, 20))
ax.imshow(img_rgb)

for i, desc in enumerate(descriptors):
    
    found = False
    for name, saved_desc in descs.items():            
        dist = np.linalg.norm([desc] - saved_desc, axis=1)
        
        # my code : compute cosine similarity        
        cosine = np.dot([desc],saved_desc)/(norm([desc]),norm(saved_desc))                
      
        if dist < 0.6:
            found = True

            text = ax.text(rects[i][0][0], rects[i][0][1], name,
                    color='b', fontsize=40, fontweight='bold')
            text2 = ax.text(rects[i][1][0], rects[i][1][1], cosine,
                    color='b', fontsize=20, fontweight='bold')
            text.set_path_effects([path_effects.Stroke(linewidth=10, foreground='white'), path_effects.Normal()])
            rect = patches.Rectangle(rects[i][0],
                                 rects[i][1][1] - rects[i][0][1],
                                 rects[i][1][0] - rects[i][0][0],
                                 linewidth=2, edgecolor='w', facecolor='none')
            ax.add_patch(rect)

            break    

当前错误输出:

neo
[1.35159114 1.36754706]
neo
[1.15541134 1.10536481]
trinity
[1.13942505 1.03432384]
morpheus
[1.26643039 1.28631887]
neo
[1.28240694 1.31706417]
trinity
[1.4723583  1.43481646]

期望得到小于1的Cosine Similarity。


问题原因

  • 分母错误使用逗号:(norm([desc]),norm(saved_desc)) 创建了一个元组,而非两个范数的乘积。Numpy会将其视为对分子进行广播除法,导致结果异常。
  • 维度冗余:[desc] 将一维的人脸描述符转为二维数组,增加了计算复杂度,还可能引发维度不匹配的隐性问题。

修正后的代码

将余弦相似度计算代码替换为以下内容:

# 修正后的余弦相似度计算
desc_norm = np.linalg.norm(desc)
saved_desc_norm = np.linalg.norm(saved_desc)
# 避免除以0的异常情况
if desc_norm == 0 or saved_desc_norm == 0:
    cosine = 0.0
else:
    cosine = np.dot(desc, saved_desc) / (desc_norm * saved_desc_norm)

额外说明

  • 余弦相似度的取值范围是**[-1, 1]**,值越接近1表示两个特征向量越相似,适合用来衡量人脸特征的匹配度。
  • 若saved_desc是存储多个人脸描述符的二维数组,可调整为:
    cosine = np.dot(desc, saved_desc.T) / (desc_norm * np.linalg.norm(saved_desc, axis=1))
    

内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 06:05:33