以下链接是个人关于DG-Net(行人重识别ReID)所有见解,如有错误欢迎大家指出,我会第一时间纠正。有兴趣的朋友可以加微信:17575010159 相互讨论技术。若是帮助到了你什么,一定要记得点赞!因为这是对我最大的鼓励。 文末附带公众号− 海量资源。

行人重识别0-00: DG-Net(RelD)-目录-史上最新最全: https://blog.csdn.net/weixin 43013761/article/details/102364512

前言

话不多说,这是论文链接:
Joint Discriminative and Generative Learning for Person Re-identification
这是开源代码:
https://github.com/NVlabs/DG-Net
如果后续本人做了很多修改,我会公布我的源码。如果你想先跑代码,再看论文,直接看后面的博客就好了,会有代码运行的指导。
下面开始我最讨厌的事情,也就是论文的翻译阅读,由于本人的英语水平比较差劲,希望大家不要介意,其实挺无奈的,没有翻译的时候,觉得自己英语不好引起的,等自己翻译过来,才发现自己语文也不咋滴!好了,玩笑就到这里结束了,进入主题。

摘要

文章说行人重识别主要面解决的问题,是在不同摄像头下对同一ID的识别。人们对于通过生成网络(GAN)增加训练数据的兴趣一直在增长。但是,几乎现在所有生成数据的方法,与行人重重识别分开的。也就是说,分开了两个阶段,先生成数据(数据增强),再直接进行简单的重识别训练。

在这篇论文中,他们会介绍如何利用生成数据去改进行人ReID:使用一种联合学习框架,即端到端的成对重识别(现在可能懵逼,其实看了后面就知道大概是什么意思了),简单的说,就是把数据生成和行人重识别统一到一个框架中。

我们的生成模型会对每个行人进行编码(encode),编码成appearance code(外观= [身份信息]+ [衣服+鞋子+手机+包包等] 编码)与structure code(姿态+头发+脸型+背景 编码),并且交换他们的st code(后面都简写了,本人有点懒)与ap code。对于ap 编码器,其与discriminative(行人ID鉴别)模型是共用的,这个地方大家注意一下,也就是说ap 编码器同与行人重识别是同一个模块。

通过交换ap code与st code,生成模型可以生成高质量交叉ID(就是两个人换了衣服+鞋子+手机+包包等)的混合图像 ,通过在线反馈的方式改进discriminative模型。利用这种联合框架产生的数据,相对于基线有了很大的提升。在几个数据集都测试都处于领先位置。说得比较莫名其妙,感觉每篇论文都希望说自己时最先进的,或者最厉害的。

红牌警告,第一个重难点: \color{#FF0000}{红牌警告,第一个重难点:} 红牌警告,第一个重难点:这里我强调一个概念,ap code表示的不仅仅是衣服,鞋子,手机,包包等。他暗含了身份了信息,是的 身份信息 \color{#FF0000}{身份信息} 身份信息,不要认为我们判断一个人是依据姿态,头发,脸型(structure code),如果有这个思想,那么恭喜你,你和我当初一样,入坑了。

对身份的识别是依赖经过Ea得到的ap code,因为他才包含了准确的身份信息。怎么个抽象,怎么个提取,后续有详细到极致的讲解(分析代码时讲解,有了预备知识才好理解)。

1、介绍

行人重识别的目的是为了在不同摄像头之中,找到相同的人,所谓的身份确认,电视剧大家应该多少看到过,类似于通过涉嫌监控,对嫌疑犯进行追踪。把这个过程进行分解(论文中所谓的度量-那些鬼,总喜欢搞点莫名奇妙的东西出来),就从两个不同的摄像头中拿到两张图片,然后进行行人检索,看下有没有同一个行人。其技术面临的挑战,主要是同一个人,在不同摄像头下面,背景,视角,甚至穿着打扮等等,都会发生很大的变化,因此,如何提高模型抵抗这种干扰的能力,已经成为现在大多数研究者的目标。

一般来说,现在ReID方面,普遍选择利用CNN去学习特征向量(invariant deep embeddings),因为CNN对于图像特征提取的能力是非常强的。目前最先进的行人重识别,会把他看作一个深度度量问题(翻译得莫名其妙,不知道什么意思,先不要管),或者看作一个分类问题,然后让模型去学习特征向量的提取。为了进一步减少来自背景,视角等等的影响,现在很多的方法,都是采取局部匹配,或者集成显示对其(大概就是从整体进行识别把)。

还有其他的增加模型鲁棒性的方法,就是让模型去学习,去观察这些变化,从而忽略行人或者环境多变性(尤其是同一行人的变化)的影响,强迫ReID模型去是学习行人,体型,姿态,发行等不变性特征。随着GAN的发展,出现了免费扩充数据的方法,尽管各种增加数据的方式不同,但是通常都是考虑这些生成图片的两个要素
1.真实性(realism),也就是合成的图片尽量和真实的图片一致。
2.多样性(diversity),就是产生的图片要多种多样,能够产生没有经过训练类型的图像。
在上述两种条件下,之前的一些方法,采用无条件的GAN或者有条件行人姿态的GAN,去生成图片 ,然后提高行人重识别模型。然而普遍存在的一个问题是,生成模型和行人重识别模型的是独立的,因此可能导致生成模型的优化任务和行人从识别的优化任务不一致,大致的意思就是说,因为生成模式和识别模式是相互独立的,没有能达到最优化的效果,限制了生成数据的增益效果。

由于上面的原因,他们提出了一种,共同联合的网络(DG-Net),其数据生成和鉴别学习统一成了一个网络。
为了达到这个目的,引入了一个生成模块:对每个张训练图像进行编码和解码操作,得到两个latent spaces(可以理解为两个特征向量):
一个为ap code,主要是和外表,或者其他身份联系的东西,如衣服+鞋子+手机+包等,注意还包含了身份信息
一个为st code,主要为人的框架,姿态,头发,脸型,背景等
他还讲,他们把已经编码的特征空间叫做codes(也就是通过CNN进行特征提取的latent spaces,叫做codes)。

表格1,如下:

appearance spac编码器和鉴别模块是共用的(同一个),这个是re-id学习的主干。这种设计,让生成和行人重识别模块 形成了一个统一的框架:
1.生成模块合成的图片,用来细化外观编码器(一脸懵逼,不知其所言,只能后面代码找答案了)
2.这些编码器,也会反过来作用于,并且改善外观编码。
3.两个模块是共同优化,共享这个ap code(再优化生成模块的同时,也优化了身份鉴别模块,因为他们是同一个)。
这里大家看起来可能不是很明白,不过没关系,继续往下看,或许就明白,没有明白也没关系,我们相信肯定能在源码中找到答案的。

图片的生成,可以描述为切换外观和结构,就是把衣服+鞋子+手机+包包等之类的调换一下,可以这样理解。给定任意两张图像(可相同,也可不相同),通过codes操作都能生成真实的,并且多样的合成图片,生成的id可以相同(没有换衣服+鞋子+手机+包包等),也可以交叉(就是换了衣服+鞋子+手机+包包等)。

如Figure 1,在基于Market-1501数据集合成的图片:

生成的图片不仅逼真,并且在基于已有身份ID上,合成了各种多样性的图片。不像没有条件的GANS,这种方法允许控制吗,并且产生更好的图片。也不像姿态-引导的生成器,我的方法不需要增加任何额外的数据,主要是利用训练数据集,内部存在的姿态和其他多样性变化。

这个生成模块的设计,是为了更好的去服务改善识别模块。对于一张行人图片,通过一个ap code去结合不同的st code,能够产生很多,衣服+鞋子+手机+包包保持不变,但是姿态,视角,背景等等改变的图片。我们可以看到Figure 1的每一行,他们都是相同的衣服+鞋子+手机+包包,但是背景和姿态以及身份ID各不一样,这样能让网络更好的捕获组合的跨身份信息。
红牌警告:此处为第二个重难点
他们介绍了”(primary feature learning)主要特征学习-不知道是啥玩意,或许后面有详细介绍”,通过一个动态的软标签策略,可以保持一个st code和不同的ap code合成一新图像,他保持了姿态,背景以及身份ID不变,倒是改变了衣服+鞋子+手机+包包。比如Figure 1中的每一列就说明了这个现象,都是同一个人穿着不同的衣服和鞋子,这样我们出来训练的模型就可以忽略衣服+鞋子+手机+包包的变化,其会被迫的去学习头发,身体大小的特征, 具有更好的鲁棒性。因此,他们的方法强迫网络进行 “fine-grained feature mining(细致纹理采集)”,即采集标志身份ID的细致属性。这个在下篇博客和后面的源码,都有详细的分析讲解。

这项工作提供了一种,从数据生成到ID识别,统一的网络框架。大量的实验证明了他们生成图片的方法,超过其他的任何方法(他们说的,不是我讲的啊!),并且他们ReID的准确率,也比求他的算法要高(吹吹牛,其实也挺好的-不过这应该是实事,从目前来看)。

1、相关工作

很多研究人员都把重心放在损失的度量上面,一些方法结合identification loss(分类)和verification loss(这个不太了解,了解的朋友可以告诉我),或者triplet loss(三角损失)。最近一些研究利用行人属性加强监督和多任务学习,如利用行人路线,人体结构优先的局部匹配等。一个常用的惯例是,分割输入图像或者feature maps(特征图),利用局部空间线索,如姿态估计,也是引入了局部特征学习,除了姿态估计,人工解析也被用在增强空间匹配度。相比下,DG-Net只依赖于简单的identification loss,而不需要添加其他人为姿态解析等。

另外一个活跃的研究方向就是利用GANS去产生训练数据, Zheng等人第一次介绍了利用无条件的GAN去生成图像,Huang 等人进一步利用WGAN和分配为标签去生成图片。Li等人提出利用在两个Re-id模型之间共享权重的方法。此外,还有最近还有一些利用姿态估计来进行条件图像生成,还有基于姿态和位置,分两个生成阶段的途径去细化合成的图像(这段真的不知道怎么翻译,表示难受)。

类似于一些方法,pose(姿态)也被用在行人图片的生成上面,让模型通过学习姿态,产生更多姿态的图片。Siarohin等人,使用nearest neighbor loss代替传统
σ 1 σ1 σ1或者 σ 2 σ2 σ2 loss。所有的方法都把图像生成和行人重识别分成了两个不连续的步骤。DG-Net把两个阶段进行了统一。

在此期间,最近一些研究也利用了风格转换合成数据,去不补偿训练数据域和目标域的差距。CycleGAN应用于重一个行人数据集到另一个数据集风格的转换;StarGAN应用于产生不同摄像头行人图像。Bak等人使用游戏引擎,改变了各种照明条件(乱七八糟的,感觉不知道怎么说)。Wei 等人,利用语音风格提取前景mask去协助风格转换。对比所有的风格转换,我是用过操控ap code和st code去增强行人重识别的学习。

3、方法

如下插图Figure 2:

DG-Net将图片生成模块,ReID鉴别模式紧紧的耦合到了一起,我们引入两个图片映射,self-identity生成与cross-identity生成,其会在线的生成图片,然后喂给行人重识别网络学习。我的discriminative模块涉及到了primary feature学习与fine-grained feature(细节)采集,他们都是和生成模块共同设计的,为了更好的去生成数据。
还有就是我带大家看论文图中的一句话:

他说re-id鉴别器是别嵌入在生成模块中的,和编码器Ea是共用的。也就是说,编码器,不仅仅是编码器,其还是ReID行人从识别的模型(着重注意,项目落实,就是把Ea这个模块落地,现在不需要理解,但是你一定要有这个印象)。

3.1. Generative Module

时间实践中,我们把输入图像经过缩放(3个尺度)或者转化为灰度图,送入到Es然后通过G生成图片,我们强制为生成模块制定了两个目标:
1.调整生成器生成self-identity(自身ID)
2.控制生成器适应真实数据的分布,去生成cross-identity (跨身份ID)

生成的图片分为两种:
self-identity表示的是重构,recon(下面loss的recon就表示重构)就是代表重构的意思,就是构建一个原来就存在的图片。
cross-identity 表示合成,直白的说,合成就是换了衣服之后的图片。

Self-identity generation 如插图Figure 2(b),提供一张





x


i




x_i


xi
,生成模块首先是要学会如何重新构建





x


i




x_i


xi
他本人,这个简单self-reconstruction(自身重构)任务,对于生成器来说,这是一个重要的任务,因为起码能保证图片生成自己本人是没有问题的,我们重构这个图片使用的是像素差loss(图像相同,则像素差为0):
(1)





L



r


e


c


o


n




i


m


g


1




=


E


[









x


i






G


(



a


i



,



s


i



)









1



]



L^{img1}_{recon}=E[||x_i-G(a_i,s_i)||_1]


Lreconimg1=E[∣∣xiG(ai,si)1]


基于同一个人在不同图像中,ap code(衣服+鞋子+手机+包)是相近的,我们进一步对同一人的任意两张图片进行重构,在这种情况下,生成器应该能通过





x


t




x_t


xt
重构





x


i




x_i


xi
,并且





y


i



=



y


t




y_i=y_t


yi=yt
。直白的说,生成器需要具备这种能力,那就是同一个人的两种图片进行合成重构,生成图片的身份ID不会发生改变。
(2)





L



r


e


c


o


n




i


m


g


2




=


ξ


[









x


i






G


(



a


t



,



s


i



)









1



]



L^{img2}_{recon}=\xi[||x_i-G(a_t,s_i)||_1]


Lreconimg2=ξ[∣∣xiG(at,si)1]
这种相同身份,交叉图像重构的loss会鼓励外观编码器,把相同身份的ap code聚集在一起(就是学习到同一人的外观特征),同时,又会迫使不同ID的ap code分离。我们使用identification loss区分不同的ID。直白的给大家说,就是喂给网络同一个人并且相同衣服+鞋子+手机+包,但是不同姿势的照片,就是为了让机器学习到把衣服+鞋子+手机+包的特征提取出来。衣服+鞋子+手机+包提取出来了,就好换衣服+鞋子+手机+包了嘛
(3)





L



i


d



s



=


ξ


[





l


o


g


(


p


(



y


i







x


i



)


)


]



L^{s}_{id}=\xi[-log(p(y_i|x_i))]


Lids=ξ[log(p(yixi))]





p


(



y


i







x


i



)



p(y_i|x_i)


p(yixi)
是预测基于ap code去预测





x


i




x_i


xi
属于实际类别(或者ID)





y


i




y_i


yi
的概率,感觉这里就是使用的oftmax进行对分类。这里是重点,可以知道我们的身份的重识别通过ap code去预测的,即ap code包含了





身份信息




\color{#FF0000}{身份信息}


身份信息

Cross-identity generation 不同于self-identity
generation(自ID生成)生成相同ID的图片,交叉身份ID的生成,其是生成不同ID的图像,在这种情况下,是没有像素级别的监督(注意啊,这句话是在告诉你,是没有办法直接计算像素差loss的,因为你没有合成之后的标签图片,当当有合成的图片也没有,没办法直接判断你合成的对不对)。我们通过基于ap code与st code,生成 latent code,然后再对latent code进行解码操作, 其效果如Figure 2©:


提供





x


i




x_i


xi






x


j




x_j


xj
两个身份ID不相同的图像,也就是





y


i







y


j




y_i \neq y_j


yi=yj
。这个生成的图片要







x


j


i



=


G


(



a


i



,



s


j



)



x_j^i=G(a_i,s_j)


xji=G(ai,sj)
需要保持来自





x


i




x_i


xi






a


i




a_i


ai
外观信息,以及来自





x


j




x_j


xj






s


i




s_i


si
结构信息,说这么多看图就知道了,反正就是两张图片的衣服鞋子换了一下。在两张图像编码之后,我们应该就能力去构建两种latent codes(就是生成的两个code):
(4)





L



r


e


c


o


n




i


m


g


1




=


ξ


[









a


i







E


a



(


G


(



a


i



,



s


j



)


)









1



]



L^{img1}_{recon}=\xi[||a_i-E_a(G(a_i,s_j))||_1]


Lreconimg1=ξ[∣∣aiEa(G(ai,sj))1]

(5)





L



r


e


c


o


n




i


m


g


2




=


ξ


[









s


j







E


s



(


G


(



a


i



,



s


j



)


)









1



]



L^{img2}_{recon}=\xi[||s_j-E_s(G(a_i,s_j))||_1]


Lreconimg2=ξ[∣∣sjEs(G(ai,sj))1]

大家看上面的损失,通过G生成融合的图片之后,又通过Ea或者Es进编码,得到新的ap或者st code,与之前旧的ap或者st计算loss,原理就这样的,既然不能直接计算像素之间的loss,那就计算
ap或者st的loss吧,好比如我把衣服借给你穿一下,但是你脱下来还给我,衣服还是没有变吧。

类似于self-identity generation,我们也能强制identification loss作用于基于ap code生成的图像,让他的身份ID保持一致性(就是图片使用dentity loss-分类loss):
(6)





L



i


d



c



=


ξ


[





l


o


g


(


p


(



y


i







x


i



)


)


]



L^{c}_{id}=\xi[-log(p(y_i|x_i))]


Lidc=ξ[log(p(yixi))]
这里的




p


(



y


i







x


i



)



p(y_i|x_i)


p(yixi)
,是预测





x


i




x_i


xi
属于真实类别





y


i




y_i


yi
的概率,在上面我们可以看到生成





x


i


j




x_i^j


xij
的图像。另外,我们还使用了adversarial loss让生成数据的分布接近真实数据的分布(就是让生成图片尽量逼真):
(7)





L



a


d


v




=


ξ


[


l


o


g


D


(



x


i



)


+


l


o


g


(


1





D


(


G


(



a


i



,



s


j



)


)


)


]



L_{adv}=\xi[logD(x_i) + log(1-D(G(a_i,s_j)))]


Ladv=ξ[logD(xi)+log(1D(G(ai,sj)))]

Discussion. 通过这种上面的loss定义,我们能够让生成模块明确的去学习ad code与ap code,然后基于通过ad code与ap code的latent code生成高质量的行人图片,这样很大程度上降低了生成的复杂性。相对于一些其他的方法,如仅仅从随机噪音或者姿态因素生成图像,是很难控制图片的的生成,并且生成的图像不可避免带有人工的特点。

此外,为了更好的利用latent code,在我们生成图像中是解纠缠的( explainable-如果不是很明白,可以看看我之前的这篇文章:风格转换0-04:stylegan-论文超详细解读(持续更新修改),往下面翻,会有解纠缠的详细介绍),并且latent code被限制在现实图片的内容中,确保了生成图像的真实性。

理论上通过抽取各种图像进行配对, 我们能生成




O


(


N


×


N


)



O(N\times N )


O(N×N)
张图片,即使数据集的图像进行两两配对。从而产生一个很大的在线样本训练池,其已经超过了之前O(2\times N )$生成图像的方式。这里的在线,大概就是一遍生成一遍训练的意思,不是等到生成所有图像之后进行训练。

3.2. Discriminative Module

我们的鉴别模块通过共享外观生成器,嵌入在生成模块之中的,其是行人重识别的主要结构,直白的说,就是嵌入在生成模块之中的,行人重识别模块。按照交换两张图片ap code和st code的思维,我们提出了一种primary feature(主特征-应该是外观)与fine-grained feature(细节特征-估计是结构)的学习方法,更好的去利用了在线生成的图片数据。因为这两个任务的重点,集中在图片生成的不同方面,在外观编码器(appearance encoder)基础上,对于两种类型的特征映射 ,并且分别对两个映射得到的特征,进行身份预测。



也就是通过





E


a




E_a


Ea
得到的ap code,开了两个分支





f



p


r


i


m





f_{prim}


fprim






f



f


i


n


e





f_{fine}


ffine
,两个分支使用ID LOSS,对身份进行预测。也就是进行了两次身份预测,下篇博客重点讲解。





再次红牌警告:此处为第二个重难点




\color{#FF0000}{再次红牌警告:此处为第二个重难点}


再次红牌警告:此处为第二个重难点

好了,我感觉有点累了,今天需要休息下,希望大家多多关注,能给我点赞,请看下篇文章吧,我会继续详细翻译讲解的。通过文章开头链接就能找到!