FaceNet:通过三元组损失实现人脸识别和聚类的统一嵌入.
本文提出了三元组损失函数 Triplet Loss,用于学习人脸识别任务中不同人脸的特征。
三元组损失是指每次训练使用三张人脸的图像:
- anchor:记为$A$,经过网络得到特征向量\(f(A)\);
- positive:与anchor是同一个人,记为$P$,经过网络得到特征向量\(f(P)\);
- negative:与anchor不是同一个人,记为$N$,经过网络得到特征向量\(f(N)\);
训练时希望同一个人的特征向量接近,而不同人的特征向量差别大:
\[|| 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)