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

余弦相似度始终为1的问题排查求助(附代码)

余弦相似度始终为1的问题排查求助

我在做学校项目时,遇到了余弦相似度(cosine similarity)计算结果始终为1的问题。已确认vector1_tensor和vector2_tensor数值不同,但无论使用PyTorch内置的F.cosine_similarity还是自定义计算函数,结果均为1。以下是相关代码和发现,求帮忙定位问题原因:

训练代码

for i, (_image1, _label1) in enumerate(train_loader):
    image1 = _image1.to(DEVICE)
    label1 = _label1[0]
    vector1_tensor = model(image1)
  
    if (i == 0): #Exception Case
      image2 = image1
      label2 = label1
      vector2_tensor = vector1_tensor
   
     #PROBLEM LOCATION 

     similarity =  F.cosine_similarity(vector1_tensor, vector2_tensor, dim = -1)
     scaled_similarity = torch.sigmoid(similarity)

    if label1 == label2:
      target_vector = [1]
    else :
      target_vector = [0]

    target_tensor = torch.tensor(target_vector).float()
    target_tensor = target_tensor.to(DEVICE)

    optimizer.zero_grad()
    cost = loss(scaled_similarity, target_tensor)
    cost.backward()
    optimizer.step()

    if not i % 40:
      print (f'Epoch: {epoch:03d}/{EPOCH:03d} | '
            f'Batch {i:03d}/{len(train_loader):03d} |'
             f' Cost: {cost:.4f}')

    #Recycle tensor for reduced computation
    image2 = image1.clone()
    label2 = label1
    vector2_tensor = vector1_tensor.detach()

模型定义代码

class trans_VGG(nn.Module):
    def __init__(self, base_dim):
        super(trans_VGG, self).__init__()
        self.feature = nn.Sequential(
            conv_2(3, base_dim),
            conv_2(base_dim, base_dim*2),
            conv_2(base_dim*2, base_dim*4),
            conv_3(base_dim*4, base_dim*8),
            conv_3(base_dim*8, base_dim*8)
        )
        self.fc_layer = nn.Sequential(
            nn.Linear(base_dim*8*7*7, 4096),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(4096, 1000),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(1000, 800)
        )
        for param in self.parameters():
            param.requires_grad = True

    def forward(self, x):
        x = self.feature(x)
        x = x.view(x.size(0), -1)
        x = self.fc_layer(x)
        return x

相关发现

  • 自定义余弦相似度函数计算结果仍为1;
  • 已确认vector1_tensor与vector2_tensor数值存在差异;
  • 项目基于VGG模型,通过提取特征嵌入计算两个张量的相似度。

问题排查方向

  1. 维度与形状检查:打印两个张量的形状,确认F.cosine_similarity的dim参数是否匹配向量维度:

    print(vector1_tensor.shape, vector2_tensor.shape)
    

    若batch_size为1且误选了错误维度计算,可能导致结果异常。

  2. 向量范数验证:余弦相似度是单位向量的点积,若模型输出向量已接近单位向量,微小数值差异可能在浮点精度下被判定为方向完全一致。检查向量的L2范数:

    print(torch.norm(vector1_tensor, dim=-1), torch.norm(vector2_tensor, dim=-1))
    
  3. 训练循环逻辑问题:循环末尾vector2_tensor被赋值为上一轮vector1_tensor的detach版本,若模型初始参数导致所有输出向量方向一致(比如未训练时参数随机但输出向量高度相似),会出现相似度始终为1的情况。可手动给向量加微小噪声测试:

    vector1_tensor = model(image1) + torch.randn_like(vector1_tensor)*1e-3
    vector2_tensor = vector2_tensor + torch.randn_like(vector2_tensor)*1e-3
    
  4. 自定义函数实现校验:对照PyTorch官方逻辑检查自定义函数,避免点积、范数计算错误:

    def custom_cosine_sim(x1, x2, dim=-1):
        x1_norm = torch.norm(x1, p=2, dim=dim, keepdim=True)
        x2_norm = torch.norm(x2, p=2, dim=dim, keepdim=True)
        return torch.sum(x1 * x2, dim=dim) / (x1_norm * x2_norm + 1e-8)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:17:22