FaceNet:通过三元组损失实现人脸识别和聚类的统一嵌入.

本文提出了三元组损失函数 Triplet Loss,用于学习人脸识别任务中不同人脸的特征。

三元组损失是指每次训练使用三张人脸的图像:

训练时希望同一个人的特征向量接近,而不同人的特征向量差别大:

\[|| f(A)-f(P) ||^2 ≤ || f(A)-f(N) ||^2\]

上式存在平凡解$f(x)=0$,因此加上一个margin $α$:

\[|| f(A)-f(P) ||^2 + α ≤ || f(A)-f(N) ||^2\]

则完整的Triplet Loss定义为:

\[L(A,P,N) = \max(|| f(A)-f(P) ||^2 - || f(A)-f(N) ||^2 + α, 0)\]

使用PyTorch自定义三元组损失:

class TripletMarginLoss(nn.Module):
    def __init__(self, margin=1.0, p=2):
        super(TripletMarginLoss, self).__init__()
        self.margin = margin
        self.p = p
        
    def forward(self, anchor, positive, negative):
        pos_dist = F.pairwise_distance(anchor, positive, self.p)
        neg_dist = F.pairwise_distance(anchor, negative, self.p)
        loss = F.relu(pos_dist - neg_dist + self.margin)
        return loss.mean()

也可以调用PyTorch内置的三元组损失:

triplet_loss = nn.TripletMarginLoss(margin=1.0, p=2)
output = triplet_loss(anchor, positive, negative)