您现在的位置是:首页 >技术杂谈 >Reid之损失函数理论学习讲解网站首页技术杂谈

Reid之损失函数理论学习讲解

爱吃肉的鹏 2023-06-18 12:00:02
简介Reid之损失函数理论学习讲解

基于深度学习的Reid主要流程为输入图像-->CNN(提取特征)-->Global average pooling-->特征向量,将用这些特征来衡量图像的相似情况。并用这些特征进行检索,返回分类情况

在训练网络的时候需要涉及损失函数,因此就引出了表征学习和度量学习。

表征学习:在训练期间没有考虑图片的相似度,而仅仅是把行人重识别任务当作分类问题或者验证问题来看待,用这种方式辅助网络学习特征间的相似度

度量学习:训练期间考虑了两张图的相似度,表现为同一行人的不同图片间的相似度大于不同行人的不同图片。(可以理解为正样本间的距离大于负样本距离)。

目录

1 表征学习

1.1 分类损失

1.1.1 属性损失(Attribute loss)

1.2 验证损失(Verification loss)

1.3 表征学习总结

2 度量学习

2.1 对比损失(Contrastive loss)

 2.2 三元组损失(Triplet loss)

2.3 改进的三元组损失(Improved triplet loss)

2.4 四元组损失(Quadruplet loss)

2.5 TriHard loss 

2.6 度量学习的总结


1 表征学习

分类损失:也称为ID损失,利用行人的ID作为训练标签,每次只需要输入一张图片。【可类比为猫狗分类,标签0代表猫,标签1代表狗】。相同之间的ID距离会拉近, 不同ID之间的距离会拉远。

验证损失:输入一对(两张)行人图片,让网络学习这两张图片是否属于同一个人,等效于二分类。

1.1 分类损失

只用分类损失(ID损失)训练的网络称为IDE网络(ID embedding)。特征层后接一个FC层,经过softmax计算交叉熵损失。参考下图,ResNet是用来做特征提取,ReID特征是我们Pool后得到的特征,然后需要用FC对这些特征进行分类(比如markt1501训练的时候分类为751类),然后经过softmax获取最终的输出。黄色框内的过程就是计算分类损失的过程

但是!在测试的时候,是不需要用到FC层,是用我们的Reid特征,也就是Pool后得到的特征来做检索,丢弃FC层(只在训练的时候有FC层)。

1.1.1 属性损失(Attribute loss)

在进行Reid识别的时候可以通过一些辅助特征来判断是否为同一人,比如衣服的颜色,头发的颜色等。这种网络的结构设计如下,如果你属性预测的准,那么你最好得到的ID也就准。这种网络的特点为:

1.可以同时连接几个属性分类损失增强ReID特征的性能;

2.每一个属性损失都是一个分类的交叉熵;

3.这种结构的网络可以理解为一个multi-task网络(多任务网络),因为有很多FC层;

4.测试的时候也是丢弃FC层,只用Pool层。

1.2 验证损失(Verification loss)

1.验证损失每次输入一对(两张)图片,进入同一个Siamese(孪生)网络进行特征提取。对应到图中就是上下均为一对(就是上面输入两张,下面的分支输入两张,那就是4张图)。那么两个网络就会提取两个特征,然后可以用这两个网络输出的特征进行相减来提取特征差异(对应到上面分支最终输出的虚线框,yi-yj),然后再经过FC层做一个二分类,判断是否为同一个人。

2.融合两个网络的特征信息计算一个二分类损失;

3.训练阶段可以和ID损失一起使用;

4.测试阶段每次输入两张图片,直接判断两个人是否为同一人。


1.3 表征学习总结

1.不学习图片之间的相似性;

2.通常需要额外的FC层来辅助特征学习,测试阶段FC层则丢弃;

3.ID损失(分类损失)的FC层维度需要和ID数量一致,当训练集太大时难以收敛;

4.验证损失测试的时候需要输入一对图像,识别率低;

5.表征学习通常情况下训练比较稳定,结果易复现;

6.表征学习的分布式训练通常比较成熟; 


2 度量学习

度量学习的目的是学习两张图片的相似性。这个相似性可以用以下映射关系表示:

fleft ( x 
ight )=R^{F}
ightarrow R^{D}

上式表示为F维的图像空间映射到D维的特征空间。(该过程就是特征提取的过程)

然后再定义一个度量函数,这个度量函数是希望对两个特征向量进行距离上的判断

D(x,y):mathbb{R}^{D}	imes mathbb{R}^{D}
ightarrow mathbb{R}

距离的公式常用的有:

        欧式距离:d_{I_{1},I_{2}}=left | f_{1}-f_{2} 
ight |_{2}

        余弦距离:d_{I_{1},I_{2}}=1-frac{f_{1}cdot f_{2}}{left | f_{1} 
ight |_{2}left | f_{2} 
ight |_{2}}

在度量学习中我们希望两个正样本的距离尽可能的小(表示为同一个人),负样本的距离尽可能大(不同行人)。

上面的过程就是在特征空间上聚类的过程。

传统的度量学习过程为下面这个式子:这个式子的含义是,D为距离函数,xi和xj是两个图像的特征,T表示向量转置,M是一个矩阵(这个M是可学习的)。而这两个x是手工提取的特征,比如HOG。

D_{M}(overrightarrow{x_{i}},overrightarrow{x_{j}})=(overrightarrow{x_{i}}-overrightarrow{x_{j}})^{T}M(overrightarrow{x_{i}}-overrightarrow{x_{j}})

而在深度学习中的度量学习,这个矩阵M就是一个欧式距离,深度学习中学习特征x,而不是矩阵M。因为M的矩阵可以分解为A^{T}cdot A,因此这个矩阵是可以找到近似解的,而这个矩阵是可以通过FC层进行拟合的,所以相当于在训练过程中,这个矩阵的解是已经近似拟合出来的,可以使其称为特征x的一部分,那么剩下学习的就只有特征x了。

上面这一段文字说的是传统学习和深度学习中度量函数思想的不同,如果不理解也没有关系,并不影响下面的学习。

常用的度量学习损失函数有:

1.对比损失(Contrastive loss)

2.三元组损失(Triplet loss)

3.改进的三元组损失(Improved triplet loss)

4.四元组损失(Quadruplet loss)

5.TriHard loss

2.1 对比损失(Contrastive loss)

同样也是孪生网络结构,输入两个图片,拉近正样本对间的距离趋于0(y=1),推开负样本对距离大于α(y=0),y是标签(表示是否为同一个人),α是手动设置的阈值,比如0.5,0.6。就是计算这个孪生网络中两个输出的之间的欧式距离。

L_{c}=yd_{I_{1},I_{2}}^{2}+(1-y)(alpha -d_{I_{1},I_{2}}^{2})_{+}^{2}

(z)_{+}:max(z,0)

 2.2 三元组损失(Triplet loss)

需要输入3张图片。关键是这三张图片是怎样的图片。这三张图片可以称为anchor,Positive【与anchor是同一个行人就是正样本图片】,Negative【与anchor不是同一个人的就是负样本图片】。也就是,三张图片是有两个ID的。学习的过程就是拉近正样本之间的距离,推开负样本之间的距离。这个过程其实就是样本的匹配过程。(如果你学过目标检测,里面也有这个概念,anchor和box的IOU关系来表示正负样本)。

 设计的损失函数为:

d_{a,p}+alpha <d_{a,n}

L_{t}=(d_{a,p}-d_{a,n}+alpha )_{+}

不过上面这种设计是有缺陷的,上面这种没有考虑到d_{a,p}绝对距离,这样的话会在做跟踪任务中失效。打个比方,假设我此时设置的α为0.3,d_{a,p}=0.5d_{a,n}=0.7,此时得到的L=0.1,然后假设d_{a,p}=1.5d_{a,n}=1.7的时候,L还是等于0.1。虽然这在做检索问题的时候问题不大,但在跟踪问题时就容易出问题了。

2.3 改进的三元组损失(Improved triplet loss)

了解决这个缺点就需要改进三元组损失。公式如下。

L_{t}=d_{a,p}+(d_{a,p}-d_{a,n}+alpha )_{+}

2.4 四元组损失(Quadruplet loss)

四元组损失是三元组损失的改进版。每次输入四张图片,a:anchor图片,p:正样本,n1,n2是两个负样本图片。

L_{q}=(d_{a,p}-d_{a,n}+alpha )_{+}+(d_{a,p}-d_{n1,n2}+eta )_{+}

1.输入四个图片,那么就有3个ID;

2.损失函数的第一项为三元组损失函数,第二项为弱推动的三元组损失函数;

2.5 TriHard loss 

 这个loss的提出,主要是希望网络可以关注困难样本。

核心思想是:对于每一个训练的batch(也就是batch的选择),挑选P个ID的行人(不同类),然后这每个行人又随机挑选K张不同的图片,那么就是一个batch中有PxK张图片。之后对于batch中的每一张图片a,可以随机挑选一个最困难的正样本最困难的负样本组成三元组。

定义两个集合A、B,A是与图片a相同ID的集合(也就是这个集合中全是a这个人),B就是和a不是一个人的集合。则损失函数为:

L_{th}=frac{1}{P	imes K}sum (underset{pepsilon A}{max(d_{a,p})}-underset{pepsilon B}{min(d_{a,n})}+alpha )_{+}

在正样本对里取最大距离为最困难的正样本;(表示为是同一个ID,但很难区分)

在负样本对里取最小的距离为最困难的负样本;(表示为不是同一个ID,但特征看起来非常的像)

TriHard loss的实现过程为:

下图中的每个矩阵为距离矩阵,假设现在有N个人(那就是N个ID,就是P=N),每个人挑选3张图(K=3),则此时的batch就有3N张图片,则可以提取3N个特征,对这3N个特征两两计算距离,那就可以得到一个3NX3N的距离矩阵(第一个矩阵)。可以看红色矩阵内像素为0的值,就是表明同一张图片的距离,那么距离肯定为0,红色矩阵就是表示为同一ID的人(也就是正样本对)绿色就是负样本对之间的距离。第二个矩阵是对第一个矩阵的平移(或者说是重组),把所有的正样本(红色)挪到左边,负样本对(绿色)移动到右边,然后在每一行去一个最大距离(Max(pos)),这就是最困的正样本,每一行取最小的(Min(neg))表示为最困难的负样本。然后我们让Max(pos)-Min(neg)【这两个向量的长度都是3N维度的】。这个过程就是对上面的公式的实现。

 不过这种Loss是只考虑的极端情况,如果数据集中打标签的时候出现了大量的错误,网络容易奔溃。


2.6 度量学习的总结

1.可直接学习图片之间的相似性;

2.不需要额外的FC层来辅助特征学习;

3.网络大小与训练集规模无关,但是数据采样器时间会增加

4.TriHard loss为目前业界度量学习的标杆;

5.度量学习通常而言训练比较随机,需要有一定的训练经验;

6.度量学习的分布式训练不太成熟,通常需要自己实现这部分代码;


是否可以将表征学习和度量学习进行组合训练呢?答案肯定是可以的。就是如下图所示。就是三个图片输入(2个ID),将会提取3个特征f1,f2,f3,同时还可以跟表征学习,加入FC层,得到分类情况ID1,ID2,ID3。

测试阶段的FC测将被丢弃。

 

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。