目录
3. 余弦嵌入损失(Cosine Embedding Loss)
向量余弦相似度损失
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
# 定义余弦相似度
cos = nn.CosineSimilarity(dim=1, eps=1e-6)
# 示例向量
x1 = torch.from_numpy(np.asarray([[1,2,3,4]]))
x2 = torch.from_numpy(np.asarray([[1.1,3.2,3.3,3.4]]))
# 计算余弦相似度
cos_sim = cos(x1, x2)
# 将相似度转换为损失
loss = 1.0 - cos_sim # 越相似,损失越小
# 求平均损失
mean_loss = torch.mean(loss)
print("Mean Cosine Similarity Loss:", mean_loss.item())
形状相似度
"""
Fréchet distance
"""
import math
import numpy as np
# Euclidean distance.
def euc_dist(pt1 ,pt2):
return math.sqrt((pt2[0 ] -pt1[0] ) *(pt2[0 ] -pt1[0] ) +(pt2[1 ] -pt1[1] ) *(pt2[1 ] -pt1[1]))
def _c(ca ,i ,j ,P ,Q):
if ca[i ,j] > -1:
return ca[i ,j]
elif i == 0 and j == 0:
ca[i ,j] = euc_dist(P[0] ,Q[0])
elif i > 0 and j == 0:
ca[i ,j] = max(_c(ca , i -1 ,0 ,P ,Q) ,euc_dist(P[i] ,Q[0]))
elif i == 0 and j > 0:
ca[i ,j] = max(_c(ca ,0 , j -1 ,P ,Q) ,euc_dist(P[0] ,Q[j]))
elif i > 0 and j > 0:
ca[i ,j] = max(min(_c(ca , i -1 ,j ,P ,Q) ,_c(ca , i -1 , j -1 ,P ,Q) ,_c(ca ,i , j -1 ,P ,Q))
,euc_dist(P[i] ,Q[j]))
else:
ca[i ,j] = float("inf")
return ca[i ,j]
""" Computes the discrete frechet distance between two polygonal lines
Algorithm: http://www.kr.tuwien.ac.at/staff/eiter/et-archive/cdtr9464.pdf
P and Q are arrays of 2-element arrays (points)
"""
def frechet_distance(P ,Q):
ca = np.ones((len(P) ,len(Q)))
ca = np.multiply(ca ,-1)
return _c(ca ,len(P ) -1 ,len(Q) -1 ,P ,Q)
if __name__ == '__main__':
A = [(0, 3), (1, 3), (2, 3), (3, 1), (4,2), (4, 2)]
B = [(0, 3), (1, 3), (2, 3), (3, 3), (3, 2), (4, 2)]
# C = [(4, 2), (4, 1), (4, 0)]
# D = [(0, 2), (1, 2), (2, 2), (2, 3), (2, 4)]
bbb= frechet_distance(A, B)
print(bbb)
1. 对比损失(Contrastive Loss)
对比损失常用于训练如孪生神经网络(Siamese networks)这样的模型,这类模型通常用于学习输入对是否相似。对比损失的目标是使得相似项的距离尽可能小,不相似项的距离尽可能大。
PyTorch 中没有内置的对比损失函数,但可以很容易地实现它。以下是一个简单的实现例子:
class ContrastiveLoss(nn.Module):
def __init__(self, margin=1.0):
super(ContrastiveLoss, self).__init__()
self.margin = margin
def forward(self, output1, output2, label):
# 计算两个输出之间的欧式距离
euclidean_distance = F.pairwise_distance(output1, output2)
# 计算对比损失
loss = torch.mean((1-label) * torch.pow(euclidean_distance, 2) +
(label) * torch.pow(torch.clamp(self.margin - euclidean_distance, min=0.0), 2))
return loss
2. 三元组损失(Triplet Loss)
三元组损失用于学习优化样本之间的相对距离,通常用于面部识别和人脸验证等任务中。它需要三个样本:一个锚点(anchor)、一个正例(positive sample,与锚点相似)、一个负例(negative sample,与锚点不相似)。目标是使锚点与正例之间的距离小于锚点与负例之间的距离。
# 创建一个三元组损失函数
triplet_loss = nn.TripletMarginLoss(margin=1.0, p=2)
anchor = torch.randn(100, 128, requires_grad=True)
positive = torch.randn(100, 128, requires_grad=True)
negative = torch.randn(100, 128, requires_grad=True)
# 计算损失
loss = triplet_loss(anchor, positive, negative)
print("Triplet Loss:", loss.item())
3. 余弦嵌入损失(Cosine Embedding Loss)
PyTorch 提供了 nn.CosineEmbeddingLoss
,这是专门为度量两个向量的余弦相似度而设计的损失函数,适用于比较两个向量的方向是否相同:
cosine_loss = nn.CosineEmbeddingLoss()
input1 = torch.randn(100, 128, requires_grad=True)
input2 = torch.randn(100, 128, requires_grad=True)
# 相似性标签,1 表示相似,-1 表示不相似
target = torch.ones(100)
loss = cosine_loss(input1, input2, target)
这些损失函数适用于不同的场景和需求,你可以根据具体的应用选择最合适的损失函数来优化你的模型。