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

Contrastive Loss 详解及用法_第1张图片

自监督学习,没有标签。假设一个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的输出不会出现负值。

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

你可能感兴趣的:(深度学习,计算机视觉,人工智能)