Contrastive Loss 详解及用法

槽:我发现网上的很多博客要么误人子弟,要么就是学艺不精就出来写,一开始我对这个概念不太理解,看别人写的博客,知道了这个loss是什么,但是怎么用,那是完全没人提啊。大家都知道,contrastive loss用在embedding vector上,这个embedding vector怎么得到的?压根就没人讲。另外,loss函数里也涉及一些超参数,超参数应该取多少?也压根没人提。都是看了看表明文章,就出来咔咔写博客,论实用性,那是真的屁用没有。

前言:这篇文章是看了论文《Supervised Contrastive Learning》极其源码之后的简单总结。想深入学习的同学建议别光看这个博客,去看论文原文和源码。

论文地址:https://papers.nips.cc/paper/2020/file/d89a66c7c80a29b1bdbab0f2a1a94af8-Paper.pdfhttps://papers.nips.cc/paper/2020/file/d89a66c7c80a29b1bdbab0f2a1a94af8-Paper.pdf

Contrastive loss的目标是让同类样本的特征相互靠近,不同类样本的特征相互远离。这里的“同类”实际上是一个更宏观的概念。比如在自监督学习当中,一张图像经过不同的随机数据增强,得到多张图像,这多张图像是同类的。在监督学习当中,相同类别的图像,是同类的。下面首先讲一下loss的定义,然后再讲loss如何使用。

self-supervised contrastive loss

自监督学习,没有标签。假设一个batch有N张图像,将这N张图像做2遍不同的数据增强,得到2N张图像。上式中的 I 则代表了这2N张图像的集合。z_i是集合中,第i张图像的embedding特征(后面讲这个embedding特征是如何得到的),z_{j(i)}指那张与图像i同源的图像。A(i)是指除第i张图像之外剩下的2N-1张图像的集合。

这个式子比较容易理解。 

Supervised contrastive loss

同样的N张图像,同样的2遍数据增强,得到同样的2N张图像。只不过,这2N张图像现在是带标签的。那么,同类别图像的特征应该互相靠近,不同类别图像的特征应该互相远离。于是,在上式当中加个类被限制,就得到了Supervised contrastive loss。

 P(i)指与图像i具有相同标签的图像的集合。这个式子也比较简单。人家能把这么点事情写成一篇文章,还能中,足以说明,写作能力对中文章的重要性。写作能力着实是头等重要的科研能力。

如何使用

其他博客基本讲了讲这loss是怎么回事就结束了。实际上还有很多问题没解决。图像的embedding特征z是如何得到的?公式里那个超参数\tau一般取值为多少?

整体上来讲,contrastive loss的使用,需要在原来的分类器的基础上,额外添加一些embedding layer。分类器由特征提取器(backbone)以及分类头构成。特征提取器就是卷积,然后拉平,将一张图像转换为一个向量。然后,分类头则是Fc+softmax。那么contrastive loss如何用进来呢?要想用,得添加embedding layer。一般就是MLP,中间采用常用的Relu激活函数就行了。MLP中,最后一层FC的输出接L2 norm,就得到了图像的embedding。 L2 norm讲图像的特征映射到一个单位超球面上,然后,采用向量之间的角度,来作为向量的相似度。向量内积除以向量长度就是角度嘛。单位向量,长度都是1,所以,向量内积直接就是角度。L2 norm可以直接用pytorch的torch.nn.functional.normalize来实现。训练的时候,分类器上的cross entropy loss,embedding layer这里的contrastive loss一起上。测试的时候,embedding layer就被弃用了,走原本的测试流程就行。超参数\tau,论文源码中使用了0.07。

另外再吐槽一下,L2 norm好多人写博客都说,把向量归一化到0--1之间。我真的呕血,看看公式行吗,向量里的正负号是假的吗?真的是瞎**乱写又不负任何责任。实际上,是把向量归一化到-1到1之间。如果原本的向量当中没有负值,那确实L2 norm的输出不会出现负值。

总之就是简单讲一下。详细内容,看论文和源码即可。论文写的不错,非常容易读。这方面我得多学习学习。源码也非常简单。一看就明白是咋回事了。

### 回答1: 对比损失(Contrastive Loss)是一个用于度量相似度或距离的损失函数。在PyTorch中,我们可以使用这个损失函数来训练一些需要度量相似度或距离的模型,比如人脸识别、语音识别等。该损失函数的计算方式是将正样本(相似样本)的距离(或相似度)降低,将负样本(不相似样本)的距离(或相似度)增加。 ### 回答2: 对比损失是一种针对分类问题的常见损失函数,用于衡量两个样本之间的相似度或差异度。PyTorch提供了实现对比损失的API,即`nn.ContrastiveLoss()`。 对比损失的计算方法是将两个输入样本通过一个共享的神经网络模型,得到两个特征向量$f(x_1), f(x_2)$,然后计算它们之间的欧氏距离$d = ||f(x_1)-f(x_2)||_2$,并将其作为损失函数的一部分。如果两个相同类别的样本(即$y_1=y_2$)距离小于一个预设的阈值$m$,则认为它们是“相似”的,此时损失为$d^2$,反之如果是不同类别的样本(即$y_1\neq y_2$)距离大于$m$,则认为它们是“不相似”的,此时损失为$max(0, m-d)^2$。 在PyTorch中,可以使用以下代码来定义对比损失: ```python loss_fn = nn.ContrastiveLoss(margin=1.0) ``` 其中`margin`参数是阈值$m$。 然后将输入样本和相应标签传递给模型并计算损失,例如: ```python x1, x2 = get_input_samples() # 获取输入样本 y = get_input_labels() # 获取标签 out1, out2 = model(x1, x2) # 执行前向计算 loss = loss_fn(out1, out2, y) # 计算损失 ``` 需要注意的是,在使用对比损失函数时,样本对的构造方式至关重要。一般来说,可以使用负采样的方式来构造不同类型的样本对,使得训练集中正样本和负样本数量相等。否则,模型很容易就会收敛到一个平凡的解。 总之,对比损失是一种较为常用的损失函数,可以用于许多不同的任务,例如人脸识别、图像检索、文本分类等。在PyTorch中,可以很方便地使用`nn.ContrastiveLoss()`实现对比损失的计算。 ### 回答3: contrastive loss就是一种损失函数,其主要目的是将同类样本的特征向量拉近,把不同类的特征向量拉远。这有助于使训练模型更加准确地分类不同类的问题。 PyTorch是一种用于构建深度学习模型的开源框架,使用PyTorch可以更方便地实现深度学习算法。 在PyTorch中,实现contrastive loss的方法可以通过构建一个自定义的损失函数来实现。首先,需要定义一个度量函数,用于度量输入样本之间的相似度。其中,常见的度量函数有欧式距离和余弦距离等。然后,在自定义的损失函数中,根据度量函数计算输入样本之间的相似度,并利用这些值来计算损失。 具体而言,对于具有标签的输入数据,损失函数的计算包括以下步骤: 1. 首先,将输入数据分为两类,一类是同类样本,一类是不同类样本。 2. 对于同类样本,使用定义的度量函数度量它们之间的相似度,并将相似度值作为损失函数的一部分。 3. 对于不同类样本,使用度量函数度量它们之间的距离,并将距离值作为损失函数的一部分。同时,需要设置一个阈值,将距离值小于阈值的样本划分为同类样本。 4. 最终,将同类样本和不同类样本的损失加权求和,并反向传播用于调整模型参数。 总之,contrastive loss pytorch可以通过自定义损失函数来实现。对于训练深度学习模型时需要进行分类或相似度匹配问题时,contrastive loss pytorch是一个非常有效的工具。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值