提交 a5755ebf 编写于 作者: D dongshuilong

modify vehicle docs

上级 7af5f42d
# 车辆细粒度分类 # 车辆细粒度分类
细粒度分类,是对属于某一类基础类别的图像进行子类别的细粉,如各种鸟、各种花、各种矿石之间。顾名思义,车辆细粒度分类是对车辆的不同子类别进行分类。 细粒度分类,是对属于某一类基础类别的图像进行子类别的细粉,如各种鸟、各种花、各种矿石之间。顾名思义,车辆细粒度分类是对车辆的不同子类别进行分类。
其训练过程与车辆ReID相比,有以下不同: 其训练过程与车辆ReID相比,有以下不同:
- 数据集不同 - 数据集不同
- Loss设置不同 - Loss设置不同
其他部分请详见[车辆ReID](./vehicle_reid.md) 其他部分请详见[车辆ReID](./vehicle_reid.md)
整体配置文件:[ResNet50.yaml](../../../ppcls/configs/Vehicle/ResNet50.yaml) 整体配置文件:[ResNet50.yaml](../../../ppcls/configs/Vehicle/ResNet50.yaml)
## 数据集 ## 数据集
在此demo中,使用[CompCars](http://mmlab.ie.cuhk.edu.hk/datasets/comp_cars/index.html)作为训练数据集。 在此demo中,使用[CompCars](http://mmlab.ie.cuhk.edu.hk/datasets/comp_cars/index.html)作为训练数据集。
<img src="../../images/recognotion/vehicle/CompCars.png" style="zoom:50%;" /> <img src="../../images/recognotion/vehicle/CompCars.png" style="zoom:50%;" />
图像主要来自网络和监控数据,其中网络数据包含163个汽车制造商、1716个汽车型号的汽车。共**136,726**张全车图像,**27,618**张部分车图像。其中网络汽车数据包含bounding box、视角、5个属性(最大速度、排量、车门数、车座数、汽车类型)。监控数据包含**50,000**张前视角图像。 图像主要来自网络和监控数据,其中网络数据包含163个汽车制造商、1716个汽车型号的汽车。共**136,726**张全车图像,**27,618**张部分车图像。其中网络汽车数据包含bounding box、视角、5个属性(最大速度、排量、车门数、车座数、汽车类型)。监控数据包含**50,000**张前视角图像。
值得注意的是,此数据集中需要根据自己的需要生成不同的label,如本demo中,将不同年份生产的相同型号的车辆视为同一类,因此,类别总数为:431类。 值得注意的是,此数据集中需要根据自己的需要生成不同的label,如本demo中,将不同年份生产的相同型号的车辆视为同一类,因此,类别总数为:431类。
## Loss设置 ## Loss设置
与车辆ReID不同,在此分类中,Loss使用的是[TtripLet Loss](../../../ppcls/loss/triplet.py) + [ArcLoss](../../../ppcls/arch/gears/arcmargin.py),权重比例1:1。 与车辆ReID不同,在此分类中,Loss使用的是[TtripLet Loss](../../../ppcls/loss/triplet.py) + [ArcLoss](../../../ppcls/arch/gears/arcmargin.py),权重比例1:1。
# 车辆ReID # 车辆ReID
ReID,也就是 Re-identification,其定义是利用算法,在图像库中找到要搜索的目标的技术,所以它是属于图像检索的一个子问题。而车辆ReID就是给定一张车辆图像,找出同一摄像头不同的拍摄图像,或者不同摄像头下拍摄的同一车辆图像的过程。在此过程中,如何提取鲁棒特征,尤为重要。因此,此文档主要对车辆ReID中训练特征提取网络部分做相关介绍,内容如下:
ReID,也就是 Re-identification,其定义是利用算法,在图像库中找到要搜索的目标的技术,所以它是属于图像检索的一个子问题。而车辆ReID就是给定一张车辆图像,找出同一摄像头不同的拍摄图像,或者不同摄像头下拍摄的同一车辆图像的过程。在此过程中,如何提取鲁棒特征,尤为重要。因此,此文档主要对车辆ReID中训练特征提取网络部分做相关介绍,内容如下:
- 数据集及预处理方式 - 数据集及预处理方式
- Backbone的具体设置 - Backbone的具体设置
- Loss函数的相关设置 - Loss函数的相关设置
全部的超参数及具体配置:[ResNet50_ReID.yaml](../../../ppcls/configs/Vehicle/ResNet50_ReID.yaml) 全部的超参数及具体配置:[ResNet50_ReID.yaml](../../../ppcls/configs/Vehicle/ResNet50_ReID.yaml)
## 数据集及预处理 ## 数据集及预处理
### VERI-Wild数据集 ### VERI-Wild数据集
<img src="../../images/recognotion/vehicle/cars.JPG" style="zoom:50%;" /> <img src="../../images/recognotion/vehicle/cars.JPG" style="zoom:50%;" />
此数据集是在一个大型闭路电视监控系统,在无约束的场景下,一个月内(30*24小时)中捕获的。该系统由174个摄像头组成,其摄像机分布在200多平方公里的大型区域。原始车辆图像集包含1200万个车辆图像,经过数据清理和标注,采集了416314张40671个不同的车辆图像。[具体详见论文](https://github.com/PKU-IMRE/VERI-Wild) 此数据集是在一个大型闭路电视监控系统,在无约束的场景下,一个月内(30*24小时)中捕获的。该系统由174个摄像头组成,其摄像机分布在200多平方公里的大型区域。原始车辆图像集包含1200万个车辆图像,经过数据清理和标注,采集了416314张40671个不同的车辆图像。[具体详见论文](https://github.com/PKU-IMRE/VERI-Wild)
## 数据预处理 ## 数据预处理
由于原始的数据集中,车辆图像已经是由检测器检测后crop出的车辆图像,因此无需像训练`ImageNet`中图像crop操作。整体的数据增强方式,按照顺序如下: 由于原始的数据集中,车辆图像已经是由检测器检测后crop出的车辆图像,因此无需像训练`ImageNet`中图像crop操作。整体的数据增强方式,按照顺序如下:
- 图像`Resize`到224 - 图像`Resize`到224
- 随机水平翻转 - 随机水平翻转
- [AugMix](https://arxiv.org/abs/1912.02781v1) - [AugMix](https://arxiv.org/abs/1912.02781v1)
- Normlize:归一化到0~1 - Normlize:归一化到0~1
- [RandomErasing](https://arxiv.org/pdf/1708.04896v2.pdf) - [RandomErasing](https://arxiv.org/pdf/1708.04896v2.pdf)
在配置文件中设置如下,详见`transform_ops`部分: 在配置文件中设置如下,详见`transform_ops`部分:
```yaml ```yaml
DataLoader: DataLoader:
Train: Train:
dataset: dataset:
#具体使用的Dataset的的名称 # 具体使用的Dataset的的名称
name: "VeriWild" name: "VeriWild"
#使用此数据集的具体参数 # 使用此数据集的具体参数
image_root: "/work/dataset/VeRI-Wild/images/" image_root: "/work/dataset/VeRI-Wild/images/"
cls_label_path: "/work/dataset/VeRI-Wild/train_test_split/train_list_start0.txt" cls_label_path: "/work/dataset/VeRI-Wild/train_test_split/train_list_start0.txt"
#图像增广策略:ResizeImage、RandFlipImage等 # 图像增广策略:ResizeImage、RandFlipImage等
transform_ops: transform_ops:
- ResizeImage: - ResizeImage:
size: 224 size: 224
...@@ -67,37 +57,34 @@ DataLoader: ...@@ -67,37 +57,34 @@ DataLoader:
num_workers: 6 num_workers: 6
use_shared_memory: False use_shared_memory: False
``` ```
## Backbone的具体设置 ## Backbone的具体设置
具体是用`ResNet50`作为backbone,但在`ResNet50`基础上做了如下修改: 具体是用`ResNet50`作为backbone,但在`ResNet50`基础上做了如下修改:
- 对Last Stage(第4个stage),没有做下采样,即第4个stage的feature map和第3个stage的feature map大小一致,都是14x14。 - 对Last Stage(第4个stage),没有做下采样,即第4个stage的feature map和第3个stage的feature map大小一致,都是14x14。
- 在最后加入一个embedding 层,即1x1的卷积层,特征维度为512 - 在最后加入一个embedding 层,即1x1的卷积层,特征维度为512
具体代码:[ResNet50_last_stage_stride1](../../../ppcls/arch/backbone/variant_models/resnet_variant.py) 具体代码:[ResNet50_last_stage_stride1](../../../ppcls/arch/backbone/variant_models/resnet_variant.py)
在配置文件中Backbone设置如下: 在配置文件中Backbone设置如下:
```yaml ```yaml
Arch: Arch:
#使用RecModel模型进行训练,目前支持普通ImageNet和RecModel两个方式 # 使用RecModel模型进行训练,目前支持普通ImageNet和RecModel两个方式
name: "RecModel" name: "RecModel"
#使用的Backbone # 导出inference model的具体配置
infer_output_key: "features"
infer_add_softmax: False
# 使用的Backbone
Backbone: Backbone:
name: "ResNet50_last_stage_stride1" name: "ResNet50_last_stage_stride1"
pretrained: True pretrained: True
#使用此层作为Backbone的feature输出,name为具体层的full_name # 使用此层作为Backbone的feature输出,name为具体层的full_name
BackboneStopLayer: BackboneStopLayer:
name: "adaptive_avg_pool2d_0" name: "adaptive_avg_pool2d_0"
#Backbone的基础上,新增网络层。此模型添加1x1的卷积层(embedding) # Backbone的基础上,新增网络层。此模型添加1x1的卷积层(embedding)
Neck: Neck:
name: "VehicleNeck" name: "VehicleNeck"
in_channels: 2048 in_channels: 2048
out_channels: 512 out_channels: 512
#增加ArcMargin, 即ArcLoss的具体实现 # 增加ArcMargin, 即ArcLoss的具体实现
Head: Head:
name: "ArcMargin" name: "ArcMargin"
embedding_size: 512 embedding_size: 512
...@@ -105,15 +92,9 @@ Arch: ...@@ -105,15 +92,9 @@ Arch:
margin: 0.15 margin: 0.15
scale: 32 scale: 32
``` ```
## Loss的设置 ## Loss的设置
车辆ReID中,使用了[SupConLoss](https://arxiv.org/abs/2004.11362) + [ArcLoss](https://arxiv.org/abs/1801.07698),其中权重比例为1:1 车辆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) 具体代码详见:[SupConLoss代码](../../../ppcls/loss/supconloss.py)[ArcLoss代码](../../../ppcls/arch/gears/arcmargin.py)
在配置文件中设置如下: 在配置文件中设置如下:
```yaml ```yaml
...@@ -123,29 +104,25 @@ Loss: ...@@ -123,29 +104,25 @@ Loss:
weight: 1.0 weight: 1.0
- SupConLoss: - SupConLoss:
weight: 1.0 weight: 1.0
#SupConLoss的具体参数 # SupConLoss的具体参数
views: 2 views: 2
Eval: Eval:
- CELoss: - CELoss:
weight: 1.0 weight: 1.0
``` ```
## 其他相关设置 ## 其他相关设置
### Optimizer设置 ### Optimizer设置
```yaml ```yaml
Optimizer: Optimizer:
#使用的优化器名称 # 使用的优化器名称
name: Momentum name: Momentum
#优化器具体参数 # 优化器具体参数
momentum: 0.9 momentum: 0.9
lr: lr:
#使用的学习率调节具体名称 # 使用的学习率调节具体名称
name: MultiStepDecay name: MultiStepDecay
#学习率调节算法具体参数 # 学习率调节算法具体参数
learning_rate: 0.01 learning_rate: 0.01
milestones: [30, 60, 70, 80, 90, 100, 120, 140] milestones: [30, 60, 70, 80, 90, 100, 120, 140]
gamma: 0.5 gamma: 0.5
...@@ -155,16 +132,40 @@ Optimizer: ...@@ -155,16 +132,40 @@ Optimizer:
name: 'L2' name: 'L2'
coeff: 0.0005 coeff: 0.0005
``` ```
### Eval Metric设置
## Eval Metric设置
```yaml ```yaml
Metric: Metric:
Eval: Eval:
#使用Recallk和mAP两种评价指标 # 使用Recallk和mAP两种评价指标
- Recallk: - Recallk:
topk: [1, 5] topk: [1, 5]
- mAP: {} - mAP: {}
``` ```
### 其他超参数设置
```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"
```
...@@ -33,7 +33,7 @@ Arch: ...@@ -33,7 +33,7 @@ Arch:
Head: Head:
name: "ArcMargin" name: "ArcMargin"
embedding_size: 512 embedding_size: 512
class_num: 431 class_num: 30671
margin: 0.15 margin: 0.15
scale: 32 scale: 32
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册