2021-06-09 15:45:23 +08:00
|
|
|
|
# 车辆ReID
|
2021-06-09 17:24:01 +08:00
|
|
|
|
ReID,也就是 Re-identification,其定义是利用算法,在图像库中找到要搜索的目标的技术,所以它是属于图像检索的一个子问题。而车辆ReID就是给定一张车辆图像,找出同一摄像头不同的拍摄图像,或者不同摄像头下拍摄的同一车辆图像的过程。在此过程中,如何提取鲁棒特征,尤为重要。因此,此文档主要对车辆ReID中训练特征提取网络部分做相关介绍,内容如下:
|
2021-06-09 16:51:16 +08:00
|
|
|
|
- 数据集及预处理方式
|
2021-06-09 15:45:23 +08:00
|
|
|
|
- Backbone的具体设置
|
|
|
|
|
- Loss函数的相关设置
|
|
|
|
|
|
2021-06-09 16:51:16 +08:00
|
|
|
|
全部的超参数及具体配置:[ResNet50_ReID.yaml](../../../ppcls/configs/Vehicle/ResNet50_ReID.yaml)
|
2021-06-09 15:45:23 +08:00
|
|
|
|
## 数据集及预处理
|
|
|
|
|
### VERI-Wild数据集
|
|
|
|
|
|
2021-06-09 16:51:16 +08:00
|
|
|
|
<img src="../../images/recognotion/vehicle/cars.JPG" style="zoom:50%;" />
|
2021-06-09 15:45:23 +08:00
|
|
|
|
|
|
|
|
|
此数据集是在一个大型闭路电视监控系统,在无约束的场景下,一个月内(30*24小时)中捕获的。该系统由174个摄像头组成,其摄像机分布在200多平方公里的大型区域。原始车辆图像集包含1200万个车辆图像,经过数据清理和标注,采集了416314张40671个不同的车辆图像。[具体详见论文](https://github.com/PKU-IMRE/VERI-Wild)
|
2021-06-09 16:51:16 +08:00
|
|
|
|
## 数据预处理
|
2021-06-09 15:45:23 +08:00
|
|
|
|
由于原始的数据集中,车辆图像已经是由检测器检测后crop出的车辆图像,因此无需像训练`ImageNet`中图像crop操作。整体的数据增强方式,按照顺序如下:
|
|
|
|
|
- 图像`Resize`到224
|
|
|
|
|
- 随机水平翻转
|
|
|
|
|
- [AugMix](https://arxiv.org/abs/1912.02781v1)
|
2021-06-09 16:51:16 +08:00
|
|
|
|
- Normlize:归一化到0~1
|
2021-06-09 15:45:23 +08:00
|
|
|
|
- [RandomErasing](https://arxiv.org/pdf/1708.04896v2.pdf)
|
2021-06-09 16:51:16 +08:00
|
|
|
|
在配置文件中设置如下,详见`transform_ops`部分:
|
|
|
|
|
```yaml
|
|
|
|
|
DataLoader:
|
|
|
|
|
Train:
|
|
|
|
|
dataset:
|
2021-06-09 17:28:42 +08:00
|
|
|
|
# 具体使用的Dataset的的名称
|
2021-06-09 16:51:16 +08:00
|
|
|
|
name: "VeriWild"
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 使用此数据集的具体参数
|
2021-06-09 16:51:16 +08:00
|
|
|
|
image_root: "/work/dataset/VeRI-Wild/images/"
|
|
|
|
|
cls_label_path: "/work/dataset/VeRI-Wild/train_test_split/train_list_start0.txt"
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 图像增广策略:ResizeImage、RandFlipImage等
|
2021-06-09 16:51:16 +08:00
|
|
|
|
transform_ops:
|
|
|
|
|
- ResizeImage:
|
|
|
|
|
size: 224
|
|
|
|
|
- RandFlipImage:
|
|
|
|
|
flip_code: 1
|
|
|
|
|
- AugMix:
|
|
|
|
|
prob: 0.5
|
|
|
|
|
- NormalizeImage:
|
|
|
|
|
scale: 0.00392157
|
|
|
|
|
mean: [0.485, 0.456, 0.406]
|
|
|
|
|
std: [0.229, 0.224, 0.225]
|
|
|
|
|
order: ''
|
|
|
|
|
- RandomErasing:
|
|
|
|
|
EPSILON: 0.5
|
|
|
|
|
sl: 0.02
|
|
|
|
|
sh: 0.4
|
|
|
|
|
r1: 0.3
|
|
|
|
|
mean: [0., 0., 0.]
|
|
|
|
|
sampler:
|
|
|
|
|
name: DistributedRandomIdentitySampler
|
|
|
|
|
batch_size: 128
|
|
|
|
|
num_instances: 2
|
|
|
|
|
drop_last: False
|
|
|
|
|
shuffle: True
|
|
|
|
|
loader:
|
|
|
|
|
num_workers: 6
|
|
|
|
|
use_shared_memory: False
|
|
|
|
|
```
|
2021-06-09 15:45:23 +08:00
|
|
|
|
## Backbone的具体设置
|
|
|
|
|
具体是用`ResNet50`作为backbone,但在`ResNet50`基础上做了如下修改:
|
|
|
|
|
- 对Last Stage(第4个stage),没有做下采样,即第4个stage的feature map和第3个stage的feature map大小一致,都是14x14。
|
|
|
|
|
- 在最后加入一个embedding 层,即1x1的卷积层,特征维度为512
|
2021-06-09 16:51:16 +08:00
|
|
|
|
具体代码:[ResNet50_last_stage_stride1](../../../ppcls/arch/backbone/variant_models/resnet_variant.py)
|
|
|
|
|
|
|
|
|
|
在配置文件中Backbone设置如下:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
Arch:
|
2021-06-09 17:28:42 +08:00
|
|
|
|
# 使用RecModel模型进行训练,目前支持普通ImageNet和RecModel两个方式
|
2021-06-09 16:51:16 +08:00
|
|
|
|
name: "RecModel"
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 导出inference model的具体配置
|
|
|
|
|
infer_output_key: "features"
|
|
|
|
|
infer_add_softmax: False
|
|
|
|
|
# 使用的Backbone
|
2021-06-09 16:51:16 +08:00
|
|
|
|
Backbone:
|
|
|
|
|
name: "ResNet50_last_stage_stride1"
|
|
|
|
|
pretrained: True
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 使用此层作为Backbone的feature输出,name为具体层的full_name
|
2021-06-09 16:51:16 +08:00
|
|
|
|
BackboneStopLayer:
|
|
|
|
|
name: "adaptive_avg_pool2d_0"
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# Backbone的基础上,新增网络层。此模型添加1x1的卷积层(embedding)
|
2021-06-09 16:51:16 +08:00
|
|
|
|
Neck:
|
|
|
|
|
name: "VehicleNeck"
|
|
|
|
|
in_channels: 2048
|
|
|
|
|
out_channels: 512
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 增加ArcMargin, 即ArcLoss的具体实现
|
2021-06-09 16:51:16 +08:00
|
|
|
|
Head:
|
|
|
|
|
name: "ArcMargin"
|
|
|
|
|
embedding_size: 512
|
|
|
|
|
class_num: 431
|
|
|
|
|
margin: 0.15
|
|
|
|
|
scale: 32
|
|
|
|
|
```
|
2021-06-09 15:45:23 +08:00
|
|
|
|
## Loss的设置
|
|
|
|
|
车辆ReID中,使用了[SupConLoss](https://arxiv.org/abs/2004.11362) + [ArcLoss](https://arxiv.org/abs/1801.07698),其中权重比例为1:1
|
|
|
|
|
具体代码详见:[SupConLoss代码](../../../ppcls/loss/supconloss.py)、[ArcLoss代码](../../../ppcls/arch/gears/arcmargin.py)
|
2021-06-09 16:51:16 +08:00
|
|
|
|
在配置文件中设置如下:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
Loss:
|
|
|
|
|
Train:
|
|
|
|
|
- CELoss:
|
|
|
|
|
weight: 1.0
|
|
|
|
|
- SupConLoss:
|
|
|
|
|
weight: 1.0
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# SupConLoss的具体参数
|
2021-06-09 16:51:16 +08:00
|
|
|
|
views: 2
|
|
|
|
|
Eval:
|
|
|
|
|
- CELoss:
|
|
|
|
|
weight: 1.0
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 其他相关设置
|
|
|
|
|
### Optimizer设置
|
|
|
|
|
```yaml
|
|
|
|
|
Optimizer:
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 使用的优化器名称
|
2021-06-09 16:51:16 +08:00
|
|
|
|
name: Momentum
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 优化器具体参数
|
2021-06-09 16:51:16 +08:00
|
|
|
|
momentum: 0.9
|
|
|
|
|
lr:
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 使用的学习率调节具体名称
|
2021-06-09 16:51:16 +08:00
|
|
|
|
name: MultiStepDecay
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 学习率调节算法具体参数
|
2021-06-09 16:51:16 +08:00
|
|
|
|
learning_rate: 0.01
|
|
|
|
|
milestones: [30, 60, 70, 80, 90, 100, 120, 140]
|
|
|
|
|
gamma: 0.5
|
|
|
|
|
verbose: False
|
|
|
|
|
last_epoch: -1
|
|
|
|
|
regularizer:
|
|
|
|
|
name: 'L2'
|
|
|
|
|
coeff: 0.0005
|
|
|
|
|
```
|
2021-06-09 17:24:01 +08:00
|
|
|
|
### Eval Metric设置
|
2021-06-09 16:51:16 +08:00
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
Metric:
|
|
|
|
|
Eval:
|
2021-06-09 17:24:01 +08:00
|
|
|
|
# 使用Recallk和mAP两种评价指标
|
2021-06-09 16:51:16 +08:00
|
|
|
|
- Recallk:
|
|
|
|
|
topk: [1, 5]
|
|
|
|
|
- mAP: {}
|
|
|
|
|
```
|
2021-06-09 17:24:01 +08:00
|
|
|
|
|
|
|
|
|
### 其他超参数设置
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
Global:
|
|
|
|
|
# 如为null则从头开始训练。若指定中间训练保存的状态地址,则继续训练
|
|
|
|
|
checkpoints: null
|
|
|
|
|
pretrained_model: null
|
|
|
|
|
output_dir: "./output/"
|
|
|
|
|
device: "gpu"
|
|
|
|
|
class_num: 30671
|
|
|
|
|
# 保存模型的粒度,每个epoch保存一次
|
|
|
|
|
save_interval: 1
|
|
|
|
|
eval_during_train: True
|
|
|
|
|
eval_interval: 1
|
|
|
|
|
# 训练的epoch数
|
|
|
|
|
epochs: 160
|
|
|
|
|
# log输出频率
|
|
|
|
|
print_batch_step: 10
|
|
|
|
|
# 是否使用visualdl库
|
|
|
|
|
use_visualdl: False
|
|
|
|
|
# used for static mode and model export
|
|
|
|
|
image_shape: [3, 224, 224]
|
|
|
|
|
save_inference_dir: "./inference"
|
|
|
|
|
# 使用retrival的方式进行评测
|
|
|
|
|
eval_mode: "retrieval"
|
|
|
|
|
```
|