前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【损失函数合集】Yann Lecun的Contrastive Loss 和 Google的Triplet Loss

【损失函数合集】Yann Lecun的Contrastive Loss 和 Google的Triplet Loss

作者头像
BBuf
发布2020-02-14 12:34:14
2.2K0
发布2020-02-14 12:34:14
举报
文章被收录于专栏:GiantPandaCV

前言

昨天在介绍Center Loss的时候提到了这两个损失函数,今天就来介绍一下。Contrastive Loss是来自Yann LeCun的论文Dimensionality Reduction by Learning an Invariant Mapping,目的是增大分类器的类间差异。而Triplet Loss是在FaceNet论文中的提出来的,原文名字为:FaceNet: A Unified Embedding for Face Recognition and Clustering,是对Contrastive Loss的改进。接下来就一起来看看这两个损失函数。论文原文均见附录。

问题引入

假设我们现在有2张人脸图片,我们要进行一个简单的对比任务,就是判断这两张人脸图片是不是对应同一个人,那么我们一般会如何解决?一种简单直接的思路就是提取图片的特征向量,然后去对比两个向量的相似度。但这种简单的做法存在一个明显的问题,那就是CNN提取的特征“类间”区分性真的有那么好吗?昨天我们了解到用SoftMax损失函数训练出的分类模型在Mnist测试集上就表现出“类间”区分边界不大的问题了,使得遭受对抗样本攻击的时候很容易就分类失败。况且人脸识别需要考虑到样本的类别以及数量都是非常多的,这无疑使得直接用特征向量来对比更加困难。

Contrastive Loss

针对上面这个问题,孪生网络被提出,大致结构如下所示:

然后孪生网络一般就使用这里要介绍的Contrastive Loss作为损失函数,这种损失函数可以有效的处理这种网络中的成对数据的关系。

Contrastive Loss的公式如下:

其中是网络权重,是成对标签,如果,这对样本属于同一个类,则,属于不同类则。是与在潜变量空间的欧几里德距离。当,调整参数最小化与之间的距离。当,当与之间距离大于,则不做优化(省时省力)当与 X2 之间的距离小于, 则增大两者距离到m。下面的公式(4)是将上面的展开写了一下,如下所示:

而下面的Figure1展示的就是损失函数和样本特征的欧氏距离之间的关系,其中红色虚线表示相似样本的损失值,而蓝色实线表示的是不相似样本的损失值。

在LeCun的论文中他用弹簧在收缩到一定程度的时候因为受到斥力的原因会恢复到原始长度来形象解释了这个损失函数,如下图:

在这里插入图片描述

代码实现:

代码语言:javascript
复制
# Custom Contrastive Loss
class ContrastiveLoss(torch.nn.Module):
    """
    Contrastive loss function.
    Based on: http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf
    """

    def __init__(self, margin=2.0):
        super(ContrastiveLoss, self).__init__()
        self.margin = margin

    def forward(self, output1, output2, label):
        euclidean_distance = F.pairwise_distance(output1, output2)
        loss_contrastive = torch.mean((1-label) * torch.pow(euclidean_distance, 2) +     # calmp夹断用法
                                      (label) * torch.pow(torch.clamp(self.margin - euclidean_distance, min=0.0), 2))
 

        return loss_contrastive

Triplet Loss

原理

Triplet Loss是Google在2015年发表的FaceNet论文中提出的,论文原文见附录。Triplet Loss即三元组损失,我们详细来介绍一下。

  • Triplet Loss定义:最小化锚点和具有相同身份的正样本之间的距离,最小化锚点和具有不同身份的负样本之间的距离。
  • Triplet Loss的目标:Triplet Loss的目标是使得相同标签的特征在空间位置上尽量靠近,同时不同标签的特征在空间位置上尽量远离,同时为了不让样本的特征聚合到一个非常小的空间中要求对于同一类的两个正例和一个负例,负例应该比正例的距离至少远margin。如下图所示:

因为我们期望的是下式成立,即:

其中就是上面提到的margin,就是样本容量为的数据集的各种三元组。然后根据上式,Triplet Loss可以写成:

在这里插入图片描述

对应的针对三个样本的梯度计算公式为:

FaceNet

我们将三元组重新描述为,那么最小化上面的损失就是就是让锚点和正样本的距离,并使得锚点和负样本的距离大于,即。那么三元组的总体距离可以表示为: 。

FaceNet网络可以更加形象的表示为下图:

所以网络的最终的优化目标是要让a,p的距离近,而a,n的距离远。下面定义一下三种不同优化难度的三元组样本。

  • easy triplets:代表,即$d(a,p)+margin
  • hard triplets:代表$d(a,n)
  • semi-hard triplets:代表$d(a,p)mergin。这三种不同的triplets可以用下图来表示:

然后FaceNet的训练策略是随机选取semi-hard triplets来进行训练的,当然也可以选择hard triplets或者两者结合来训练。关于FaceNet更多的训练细节我们就不再介绍了,这一节的目的是介绍Triplet Loss,之后在人脸识别专栏再单独写一篇介绍FaceNet训练测试以及网络参数细节的。

代码实现

简单提供一个Triplet Loss训练Mnist数据集的Keras代码,工程完整地址见附录:

代码语言:javascript
复制
def triplet_loss(y_true, y_pred):
        """
        Triplet Loss的损失函数
        """

        anc, pos, neg = y_pred[:, 0:128], y_pred[:, 128:256], y_pred[:, 256:]

        # 欧式距离
        pos_dist = K.sum(K.square(anc - pos), axis=-1, keepdims=True)
        neg_dist = K.sum(K.square(anc - neg), axis=-1, keepdims=True)
        basic_loss = pos_dist - neg_dist + TripletModel.MARGIN

        loss = K.maximum(basic_loss, 0.0)

        print "[INFO] model - triplet_loss shape: %s" % str(loss.shape)
        return loss

可以来感受一下Triplet Loss训练Mnist时Loss下降效果,几乎是线性下降:

在这里插入图片描述

另外看一下作者只跑了2个Epoch之后的降维可视化结果,截图如下,可以看到已经类别已经聚集得特别好了:

在这里插入图片描述

附录

  • Contrasstive Loss原文:http://www.cs.toronto.edu/~hinton/csc2535/readings/hadsell-chopra-lecun-06-1.pdf
  • Triplet Loss原文:https://arxiv.org/abs/1503.03832
  • 参考:https://zhuanlan.zhihu.com/p/76515370
  • Triplet Loss代码实现:https://github.com/SpikeKing/triplet-loss-mnist

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GiantPandaCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 问题引入
  • Contrastive Loss
  • Triplet Loss
    • 原理
      • FaceNet
        • 代码实现
        • 附录
        相关产品与服务
        人脸识别
        腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档