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

为何PyTorch中完全相同的零向量余弦相似度为0而非1?

问题原因与解决方案

问题根源

你遇到的问题源于全零向量的L2范数为0。余弦相似度的计算公式为:
$$\text{cos_sim}(a,b) = \frac{a \cdot b}{||a||_2 \times ||b||_2}$$
当a和b都是全零向量时,分母为0,属于数学上的未定义场景。PyTorch的F.cosine_similarity函数在这种情况下会默认返回0,而非你预期的1。

修复方案

可以手动实现余弦相似度计算,添加极小的epsilon避免除以0,同时对全零向量的场景做特殊处理:

import torch
import torch.nn.functional as F

def calc_similarity_batch(a, b):
    representations = torch.cat([a, b], dim=0)
    # 计算向量间点积
    dot_product = torch.matmul(representations, representations.T)
    # 计算每个向量的L2范数
    norm = torch.norm(representations, dim=1, keepdim=True)
    # 添加epsilon避免除以0
    similarity_matrix = dot_product / (norm * norm.T + 1e-8)
    # 标记所有全零向量对,将其相似度设为1
    zero_mask = (norm.squeeze() == 0).unsqueeze(0) & (norm.squeeze() == 0).unsqueeze(1)
    similarity_matrix = torch.where(zero_mask, torch.tensor(1.0, device=similarity_matrix.device), similarity_matrix)
    return similarity_matrix

# 测试代码
a = torch.tensor([[0.,0.,0.,0.,0.]])
b = torch.tensor([[0.,0.,0.,0.,0.]])
print(calc_similarity_batch(a, b))

运行后会输出预期结果:

tensor([[1., 1.],
        [1., 1.]])

如果只需要处理自身与自身的相似度场景,也可以简化逻辑:先计算原始相似度矩阵,再将对角线位置(自身匹配)的全零值替换为1,但上面的方案更通用,能覆盖任意全零向量之间的相似度计算。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:02:04