最小化两个张量的余弦相似度并输出一个标量。火炬

minimum the cosine similarity of two tensors and output one scalar. Pytorch

我使用Pytorch余弦相似度函数如下。我有两个特征向量,我的目标是让它们彼此不同。所以,我想我可以最小化它们的余弦相似度。我对我的编码方式有些怀疑。感谢您对以下问题的建议。

  1. 不知道为什么val1里面有一些负值?

  2. 我已经完成了三个步骤将 val1 转换为标量。我这样做的方式正确吗?还有其他办法吗?

  3. 为了尽量减少相似度,我使用了1/var1。这是执行此操作的标准方法吗?如果我使用 1-var1 是否正确?

    def loss_func(feat1, feat2):
         cosine_loss = torch.nn.CosineSimilarity(dim=1, eps=1e-6)
         val1 = cosine_loss(feat1, feat2).tolist()
         # 1. calculate the absolute values of each element,
         # 2. sum all values together,
         # 3. divide it by the number of values
         val1 = 1/(sum(list(map(abs, val1)))/int(len(val1)))
         val1 = torch.tensor(val1, device='cuda', requires_grad=True)
         return val1 
    

不要将损失函数转换为列表。这会破坏 autograd,因此您将无法使用 pytorch 优化模型参数。

损失函数已经是最小化的东西了。如果你想最小化相似度,那么你可能只想 return 平均余弦相似度。相反,如果您想最小化相似度的大小(即鼓励特征正交),那么您可以 return 余弦相似度的平均绝对值。

您所实施的似乎将尝试最大化 相似性。但这似乎与你所说的不一致。此外,要将最小化问题转化为等效的最大化问题,您通常只需取反该度量即可。负损失值没有错。采取严格积极措施的倒数确实将其从最小化问题转换为最大化问题,但也改变了措施的行为,可能 不是你想要的。

根据您的实际需要,其中一种可能会满足您的需求

import torch.nn.functional as F

def loss_func(feat1, feat2):
    # minimize average magnitude of cosine similarity
    return F.cosine_similarity(feat1, feat2).abs().mean()

def loss_func(feat1, feat2):
    # minimize average cosine similarity
    return F.cosine_similarity(feat1, feat2).mean()

def loss_func(feat1, feat2):
    # maximize average magnitude of cosine similarity
    return -F.cosine_similarity(feat1, feat2).abs().mean()

def loss_func(feat1, feat2):
    # maximize average cosine similarity
    return -F.cosine_similarity(feat1, feat2).mean()