行人ReID,参考以及后续训练,持续更新(二)2020

2020年6月,重磅,最强重识别工具箱FastReID开源,附带多种SOTA模型

https://zhuanlan.zhihu.com/p/146137740

添加了最近最好的几个reid模型,很多训练技巧,组合

1)、AWG 方法,添加了三个结构局部结构,效果涨幅很厉害

行人ReID,参考以及后续训练,持续更新(二)2020_第1张图片

2)、行人重识别 — Mutiple Granularity Network(MGN)

行人ReID,参考以及后续训练,持续更新(二)2020_第2张图片
行人ReID,参考以及后续训练,持续更新(二)2020_第3张图片

首先,输入图的尺寸是 384×128,用的是 Resnet50,如果在不做任何改变的情况下,它的特征图谱输出尺寸,global 这个地方就相当于对 Resnet 50不做任何的改变,特征图谱输出是 12×4。

下面有一个 part-2 跟 part-3,这是在 Res4_1 的位置,本来是有一个 stride 等于 2 的下采样的操作,把2改成 1,没有下采样,这个地方的尺寸就不会缩小 2,所以 part-2 跟 part-3 比 global 大一倍的尺寸,它的尺寸是 24×8。为什么要这么操作?因为我们会强制分配 part-2 跟 part-3 去学习细粒度特征,如果把特征尺寸做得大一点,相当于信息更多一点,更利于网络学到更细节的特征。

网络结构从左到右,先是两个人的图片输入,这边有 3 个模块。3 个模块的意思是表示 3 个分支共享网络,前三层这三个分支是共享的,到第四层时分成三个支路,第一个支路是 global 的分支,第二个是 part-2 的分支,第三个是 part-3 的分支。在 global 的地方有两块,右边这个方块比左边的方块大概缩小了一倍,因为做了个下采样,下面两个分支没有做下采样,所以第四层和第五层特征图是一样大小的。

接下来对 part-2 跟 part-3 做一个从上到下的纵向分割,part-2 在第五层特征图谱分成两块,part-3 对特征图谱从上到下分成三块。在分割完成后,做一个 pooling,相当于求一个最值,我们用的是 Max-pooling,得到一个 2048 的向量,这个是长条形的、横向的、黄色区域这个地方。

但是 part-2 跟 part-3 的操作跟 global 是不一样的,part-2 有两个 pooling,第一个是蓝色的,两个 part 合在一起做一个 global-pooling,我们强制 part-2 去学习细节的联合信息,part-2 有两个细的长条形,就是我们刚才引导它去学细节型的信息。淡蓝色这个地方变成小方体一样,是做降维,从 2048 维做成 256 维,这个主要方便特征计算,因为可以降维,更快更有效。我们在测试的时候会在淡蓝色的地方,小方块从上到下应该是 8 个,我们把这 8 个 256 维的特征串连一个 2048 的特征,用这个特征替代前面输入的图片。

(三)Loss 设计

整个模型里只用了两种 Loss,一个是 SoftmaxLoss 一个是 TripletLoss。我们当时做了些实验和思考去想 Loss 的设计。现在这个方案,第一,从实践上证明是比较好的,第二,从理解上也是容易理解的。

首先,看一下 global 分支。上面第一块的 Loss 设计。这个地方对 2048 维做了SoftmaxLoss,对 256 维做了一个 TripletLoss,这是对 global 信息通用的方法。下面两个部分 global 的处理方式也是一样的,都是对 2048 做一个 SoftmaxLoss,对 256 维做一个 TripletLoss。中间 part-2 地方有一个全局信息,有 global 特征,做 SoftmaxLoss+TripletLoss。

但是,下面两个 Local 特征看不到 TripletLoss,只用了 SoftmaxLoss,这个在文章里也有讨论,我们当时做了实验,如果对细节当和分支做 TripletLoss,效果会变差。为什么效果会变差?

一张图片分成从上到下两部分的时候,最完美的情况当然是上面部分是上半身,下面部分是下半身,但是在实际的图片中,有可能整个人都在上半部分,下半部分全是背景,这种情况用上、下部分来区分,假设下半部分都是背景,把这个背景放到 TripletLoss 三元损失里去算这个 Loss,就会使得这个模型学到莫名其妙的特征。

比如背景图是个树,另外一张图是某个人的下半身,比如一个女生的下半身是一个裙子,你让裙子跟另外图的树去算距离,无论是同类还是不同类,算出来的距离是没有任何物理意义或实际意义的。从模型的角度来讲,它属于污点数据,这个污点数据会引导整个模型崩溃掉或者学到错误信息,使得预测的时候引起错误。所以以后有同学想复现方法的时候要注意一下, Part-2、part-3 的 Local 特征千万不要加 TripletLoss。

(四)实验参数

很多同学对复现方案有一定兴趣,也好奇到底这个东西为什么可以做那么好。用的框架是 Pytorch。TripletLoss 复现是怎么选择的? 这个 batch是选 P=16,K=4,16×4,64 张图作为 batch,是随机选择16 个人,每个人随机选择 4 张图。然后用 SGD 去训练,参数用的是 0.9。另外,我们做了weight decay,参数是万分之五。像 Market1501 是训练 80epochs,是基于 Resnet50 微调了。之前实验过,如果不基于 Resnet50,用随机初始化去训练的话效果很差,很感谢 Resnet50 的作者,对这个模型训练得 非常有意义。

初始学习率是百分之一,到 40个epoch降为千分之一,60 个 epoch 时降为万分之一。评估时会对评估图片做左右翻转后提取两个特征,这两个特征求一个平均值,代表这张图片的特征。刚才有问题到我们用了什么硬件,我们用了 2 张的 TITAN 的 GPU。

在 Market1501 上训练 80 epoch的时间大概差不多是 2 小时左右,这个时间是可以接受的,一天训练得快一点可以做出 5-10 组实验。

(五)更多思路

当前的行人重识别方法,如PCB, MGN,都是为了使网络学习到更精密有区分度的特征,一般将最后得到的feature map进行水平切分然后分别求loss,简单做水平切分可能会造成一块完整的feature,如背包,被丢失,失去信息。所以他们都做了相应的改进,如PCB加上了RPP,所以PCB之后加上了RPP把没有切分好的feature重新划分,需要进行两阶段的训练。而MGN的则是用了一个比较复杂包含多种切分的方法的网路,切两次,切三次,最后把这些feature融合起来。

切分feature map的本质是为了不让网络太关注于那些太显而易见的全局特征。因为行人重识别是一个zero shot learning的问题,就是说训练中的人和测试中的人是不同的人,而且主流的行人数据集都较小,容易过拟合, 导致这些在训练的时候表现很好的全局特征在测试的时候反而达不到最好的效果。那么除了这样水平切分特征之外还有什么方法能够达到同样的效果呢?这里提供一种新的方法叫做Batch Feature Erasing。

论文链接: https://arxiv.org/pdf/1811.07130.pdf

原文链接:https://www.toutiao.com/a6571726582254141960/ ———————— 版权声明:本文作者为云从科技资深算法研究员袁余锋老师,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
3)、Bag of Tricks and A Strong Baseline for Deep Person Re-identification (BoT)

加一些训练技巧
行人ReID,参考以及后续训练,持续更新(二)2020_第4张图片

4) sbs是添加,结构,损失,数据处理等小方法方法在 123的基础上再训练的

stronger baseline on top of BoT:

Bag of Freebies(BoF):

  1. Circle loss
  2. Freeze backbone training
  3. Cutout data augmentation & Auto Augmentation
  4. Cosine annealing learning rate decay
  5. Soft margin triplet loss
https://bbs.cvmart.net/topics/1499/vote_count%3F  写的很好,经验

3. finetune,微调也是有许多比较fancy的技巧,在这里不做优劣比较,针对分类任务说明。

    微调方式一,最常用,只替换掉最后一层fc layer,改成本任务里训练集的类别数目,然后不做其余特殊处理,直接开始训练;
    微调方式二,在微调一的基础上,freeze backbone的参数,只更新(预训练)新的fc layer的参数(更新的参数量少,训练更快)到收敛为止,之后再放开所有层的参数,再一起训练;

    微调方式三,在微调方式二预训练fc layer之后或者直接就是微调方式一,可选择接上差分学习率(discriminative learning rates)即更新backbone参数和新fc layer的参数所使用的学习率是不一致的,一般可选择差异10倍,理由是backbone的参数是基于imagenet训练的,参数足够优秀同时泛化性也会更好,所以是希望得到微调即可,不需要太大的变化。

    optimizer = torch.optim.Adam([{'params': model.backbone.parameters(), 'lr': 3e-5},
    {'params': model.fc.parameters(), 'lr': 3e-4}, ])
    微调方式四,freeze浅层,训练深层(如可以不更新resnet前两个resnet block的参数,只更新其余的参数,一样是为了增强泛化,减少过拟合)。

4. Find the best init_lr,前面说到3e-4在Adam是较优的init_lr,那么如何寻找最好的init_lr?

    出自fastai, lr_find(),其原理就是选取loss function仍在明显降低的较大的学习速率,优劣性其实也是相对而言,不一定都是最好的。

Bag of Specials(BoS):

  1. Non-local block
  2. GeM pooling

2020年初,基于深度学习的person re-identification综述 Deep Learning for Person Re-identification: A Survey and Outlook

该文章发表于2020年初,作者调查了245篇近两三年的行人重识别(Person Re-identification)论文,分类为封闭世界ReID与开放世界ReID,综述了该方向的技术进展,对未来ReID技术发展给出了几个有价值的方向,是近期最值得读的ReID综述。

实际也是AGW 模型提出文章

你可能感兴趣的:(reid)