这是CVPR2020的一篇度量学习的论文.来自韩国.我觉得还蛮有意思的,因此学习一番.

他的图画的是真好看,虽然做的事情其实就是把amsoftmax换个皮...

原理

论文主要提出了一个名为Proxy Anchor的损失函数.他相比于上图中a,b,c,d的方法.同时考虑了间距的大小作为损失的系数,且利用了整个batch中所有的数据,并用anchor作为proxy使得聚类中心更加明确.

基于pair的损失

对于一些没有利用整个batch所有数据的方法,那就需要依赖采样来取得triplet pair,N-pair等等,这样实际上引用了额外的复杂度.因此使用基于proxy的方法,不需要pair采样的方式.

基于proxy的损失

基于proxy的度量学习是一种相对较新的方法,可以解决基于pair的损失的复杂性问题。proxy表示训练数据子集的代表,并被估计为嵌入网络参数的一部分。此类别中方法的共同思想是推断一小组的proxy,这些proxy捕获嵌入空间的全局结构,并将每个数据点与proxy相关联,而不是训练过程中的其他数据点。由于proxy的数量明显少于训练数据的数量,因此可以大大减少训练的复杂性.

第一个基于proxy的方法为Proxy-NCA,他使用proxiesNeighborhood Component Analysis作为一种近似,首先为每个类别设置一个proxy,将数据点与proxy关联,拉近正类的距离,拉开负类的距离.

使用proxy有助于极大地提高训练的收敛性,但有一个固有的局限性:由于每个数据点仅与proxy相关联,因此基于pair的方法的丰富的数据间关系不再可用。因此提出Proxy Anchor损失可以克服此问题,因为它的梯度可以反映数据的相对联系,这允许它们的嵌入向量在训练过程中相互影响.

Proxy-NCA Loss

首先介绍原本的损失.Proxy-NCA损失将proxy分配给每个类别,proxy的数量与类别标签的数量相同。给定一个输入数据点作为anchor,将同一类输入的proxy视为正,其他proxy为负。令x表示输入的嵌入向量,p+为正proxyp为负proxy。损失则为如下:

(X)=xXloges(x,p+)pPes(x,p)=xX{s(x,p+)+LSEpPs(x,p)}

其中X为整个batch的嵌入向量,P为负proxy的集合,s(,)表示余弦相似度.其中LSElog sum exp.熟悉基于softmax损失的同学应该已经看出来了,这里其实就是交叉熵换了个皮.

对于此损失的梯度如下: (X)s(x,p)={1, if p=p+es(x,p)pPes(x,p),otherwise 

训练时会使得xp+尽量接近,使得xp远离.不过注意到对于正类的梯度是恒定的,对于负类的梯度是有考虑到相似度的.此损失还是比较鲁棒的,但是由于损失仅使每个嵌入向量与proxy相关联,因此它无法利用细粒度的数据间关系。这种缺点限制了通过Proxy-NCA嵌入的能力.

Proxy-Anchor Loss

Proxy-Anchor损失旨在克服Proxy-NCA的局限性,同时保持较低的训练复杂性。主要思想是将每个proxy作为锚,并将其与整个数据批关联,以便在训练过程中数据通过proxy anchor彼此交互。此损失先按照Proxy-NCA的标准设置为每个类别分配一个proxy,公式为:

(X)=1|P+|pP+log(1+xX+peα(s(x,p)δ))+1|P|pPlog(1+xXpeα(s(x,p)+δ))

这个也是比较老套的设置方法,其中δmargin,α为尺度系数.将一个batch中所有的嵌入向量X分成两个子集X+p,Xp,其中X+p表示proxyp的正样本嵌入向量,Xp则是剩下的所有向量.

将损失换一个形式: (X)=1|P+|pP+[Softplus (LSExX+pα(s(x,p)δ))]+1|P|pP[Softplus (LSEpXpα(s(x,p)+δ))]

这样更加符合circle loss中所提出的统一形式了.其中这里的|P+|是正样本的统计数量,|P|是总类别数.这个系数我觉得不加也没关系...

NOTE 我看了下他官方的代码,实际上什么基于proxy的方法就是额外再加一个可训练的聚类中心...我之前的各种损失函数的实现是直接把最后一层作为聚类中心(也就是他们所说的proxy),这么看来把circle loss拉到度量学习的标准任务里肯定也是很能打的.

额外实验1

我做的cifar10分类实现,实际上batchsize改成500之后|P+|有99.99的概率为10,|P|为10。我训练结果只和circle loss差0.8个点。然后我认为删除这个系数没有关系,但结果立马打脸了,差7个点了。其实这个问题还是在于α系数上面,对于proxy anchor lossamsoftmax loss来说没有像circle loss中的自适应pace,优化到后期可以说学习率太大也可以说是梯度太大,模型参数波动性会较大。这个实验佐证了自适应pace的重要性。

额外实验2

后面我又做了一下关于margin的实验,实际上我们考虑softmax分类的过程,要使他分类难度增强应该是降低正确类别的数值,因此应该是sp=cos(θyi)m,这样才会强制正确类别的向量夹角更小。那么对于不正确的的分类类别,应该是加大他的数值,sn=cos(θjyi)+m,这样会强制降低向量更加接近垂直。

这里留个小坑,对于circle loss里面的margin设置我还是得重新仔细看看。

NOTE 2020-6-23日更新,因为circle loss设置了自定义pace,因此他计算决策面的时候将α考虑进去了,所以他得到的margin和我之前设想的不一样。然后我又做了一下他的间距分布图,其实这个损失还是可以继续改进的,大家可以看到当cos(θp)=0cos(θn)(π,π2)时,对于负pair的损失是较小的。他所说的circle区域实际上是在cos(θp)=0cos(θn)=π2有一个更小的凹槽,这里是我们的ideal区域。

接下来如果有老哥可以把cos(θp)=0cos(θn)(π,π2)这块区域的损失重新设计一下,应该可以得到更好的收敛效果。

等等。。这样判断太武断了,应该还需要分析一下梯度的变化。我这里就不继续深入了。