余弦相似度始终为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模型,通过提取特征嵌入计算两个张量的相似度。
问题排查方向
维度与形状检查:打印两个张量的形状,确认
F.cosine_similarity的dim参数是否匹配向量维度:print(vector1_tensor.shape, vector2_tensor.shape)若batch_size为1且误选了错误维度计算,可能导致结果异常。
向量范数验证:余弦相似度是单位向量的点积,若模型输出向量已接近单位向量,微小数值差异可能在浮点精度下被判定为方向完全一致。检查向量的L2范数:
print(torch.norm(vector1_tensor, dim=-1), torch.norm(vector2_tensor, dim=-1))训练循环逻辑问题:循环末尾
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自定义函数实现校验:对照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
相关产品推荐
相关产品推荐

