feature_extraction.md 15.2 KB
Newer Older
H
HydrogenSulfate 已提交
1
简体中文|[English](../../en/image_recognition_pipeline/feature_extraction_en.md)
S
stephon 已提交
2
# 特征提取
S
sibo2rr 已提交
3 4 5

## 目录

H
HydrogenSulfate 已提交
6 7 8
- [1. 摘要](#1-摘要)
- [2. 介绍](#2-介绍)
- [3. 方法](#3-方法)
9 10 11 12
    - [3.1 Backbone](#31-backbone)
    - [3.2 Neck](#32-neck)
    - [3.3 Head](#33-head)
    - [3.4 Loss](#34-loss)
H
HydrogenSulfate 已提交
13 14 15 16 17 18 19 20 21 22
- [4. 实验部分](#4-实验部分)
- [5. 自定义特征提取](#5-自定义特征提取)
  - [5.1 数据准备](#51-数据准备)
  - [5.2 模型训练](#52-模型训练)
  - [5.3 模型评估](#53-模型评估)
  - [5.4 模型推理](#54-模型推理)
    - [5.4.1 导出推理模型](#541-导出推理模型)
    - [5.4.2 获取特征向量](#542-获取特征向量)
- [6. 总结](#6-总结)
- [7. 参考文献](#7-参考文献)
S
sibo2rr 已提交
23

S
stephon 已提交
24
<a name="1"></a>
S
sibo2rr 已提交
25

H
HydrogenSulfate 已提交
26
## 1. 摘要
S
sibo2rr 已提交
27

H
HydrogenSulfate 已提交
28
特征提取是图像识别中的关键一环,它的作用是将输入的图片转化为固定维度的特征向量,用于后续的[向量检索](./vector_search.md)。一个好的特征需要具备“相似度保持性”,即相似度高的图片对,其特征的相似度也比较高(特征空间中的距离比较近),相似度低的图片对,其特征相似度要比较低(特征空间中的距离比较远)。为此[Deep Metric Learning](../algorithm_introduction/metric_learning.md)领域内提出了不少方法用以研究如何通过深度学习来获得具有强表征能力的特征。
S
sibo2rr 已提交
29

S
stephon 已提交
30
<a name="2"></a>
S
stephon 已提交
31

H
HydrogenSulfate 已提交
32 33
## 2. 介绍

S
sibo2rr 已提交
34
为了图像识别任务的灵活定制,我们将整个网络分为 Backbone、 Neck、 Head 以及 Loss 部分,整体结构如下图所示:
S
stephon 已提交
35
![](../../images/feature_extraction_framework.png)
B
Bin Lu 已提交
36
图中各个模块的功能为:
S
sibo2rr 已提交
37

38 39 40 41
- **Backbone**: 用于提取输入图像初步特征的骨干网络,一般由配置文件中的 [`B.//ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml#L26-L29) 以及 [`B.//ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml#L30-L31) 字段共同指定。
- **Neck**: 用以特征增强及特征维度变换。可以是一个简单的 FC Layer,用来做特征维度变换;也可以是较复杂的 FPN 结构,用以做特征增强,一般由配置文件中的 [`N.//ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml#L32-L35)字段指定。
- **Head**: 用来将 `Neck` 的输出 feature 转化为 logits,让模型在训练阶段能以分类任务的形式进行训练。除了常用的 FC Layer 外,还可以替换为 [CosMargin](../../../ppcls/arch/gears/cosmargin.py), [ArcMargin](../../../ppcls/arch/gears/arcmargin.py), [CircleMargin](../../../ppcls/arch/gears/circlemargin.py) 等模块,一般由配置文件中的 [`H.//ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml#L36-L41) 字段指定。
- **Loss**: 指定所使用的 Loss 函数。我们将 Loss 设计为组合 loss 的形式,可以方便地将 Classification Loss 和 Metric learning Loss 组合在一起,一般由配置文件中的 [`L.//ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml#L44-L50) 字段指定。
S
sibo2rr 已提交
42

S
stephon 已提交
43
<a name="3"></a>
S
stephon 已提交
44

H
HydrogenSulfate 已提交
45 46
## 3. 方法

47
#### 3.1 Backbone
H
HydrogenSulfate 已提交
48

49 50
Backbone 部分采用了 [PP-LCNetV2_base](../models/PP-LCNetV2.md),其针对Intel CPU端的性能优化探索了多个有效的结构设计方案,最终实现了在不增加推理时间的情况下,进一步提升模型的性能,最终大幅度超越现有的 SOTA 模型。

51
#### 3.2 Neck
52 53 54

Neck 部分采用了 [BN Neck](../../../ppcls/arch/gears/bnneck.py),对 Backbone 抽取得到的特征的每个维度进行标准化操作,减少了同时优化度量学习损失和分类损失的难度。

55
#### 3.3 Head
56 57 58

Head 部分选用 [FC Layer](../../../ppcls/arch/gears/fc.py),使用分类头将 feature 转换成 logits 供后续计算分类损失。

59
#### 3.4 Loss
60 61 62

Loss 部分选用 [Cross entropy loss](../../../ppcls/loss/celoss.py)[TripletAngularMarginLoss](../../../ppcls/loss/tripletangularmarginloss.py),在训练时以分类损失和基于角度的三元组损失来指导网络进行优化。详细的配置文件见[GeneralRecognitionV2_PPLCNetV2_base.yaml](../../../ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml#L63-77)

H
HydrogenSulfate 已提交
63 64 65 66
<a name="4"></a>

## 4. 实验部分

H
HydrogenSulfate 已提交
67
我们对原有的训练数据进行了合理扩充与优化,最终使用如下 16 个公开数据集的汇总:
68 69 70 71 72 73 74 75 76

| 数据集                 | 数据量  |  类别数  | 场景  |                                      数据集地址                                      |
| :--------------------- | :-----: | :------: | :---: | :----------------------------------------------------------------------------------: |
| Aliproduct             | 2498771 |  50030   | 商品  |      [地址](https://retailvisionworkshop.github.io/recognition_challenge_2020/)      |
| GLDv2                  | 1580470 |  81313   | 地标  |               [地址](https://github.com/cvdfoundation/google-landmark)               |
| VeRI-Wild              | 277797  |  30671   | 车辆  |                    [地址](https://github.com/PKU-IMRE/VERI-Wild)                     |
| LogoDet-3K             | 155427  |   3000   | Logo  |              [地址](https://github.com/Wangjing1551/LogoDet-3K-Dataset)              |
| SOP                    |  59551  |  11318   | 商品  |              [地址](https://cvgl.stanford.edu/projects/lifted_struct/)               |
| Inshop                 |  25882  |   3997   | 商品  |            [地址](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion.html)             |
H
HydrogenSulfate 已提交
77 78 79
| bird400                |  58388  |   400    | 鸟类  |          [地址](https://www.kaggle.com/datasets/gpiosenka/100-bird-species)          |
| 104flows               |  12753  |   104    | 花类  |              [地址](https://www.robots.ox.ac.uk/~vgg/data/flowers/102/)              |
| Cars                   |  58315  |   112    | 车辆  |            [地址](https://ai.stanford.edu/~jkrause/cars/car_dataset.html)            |
80
| Fashion Product Images |  44441  |    47    | 商品  | [地址](https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset) |
H
HydrogenSulfate 已提交
81 82 83 84 85
| flowerrecognition      |  24123  |    59    | 花类  |         [地址](https://www.kaggle.com/datasets/aymenktari/flowerrecognition)         |
| food-101               | 101000  |   101    | 食物  |         [地址](https://data.vision.ee.ethz.ch/cvl/datasets_extra/food-101/)          |
| fruits-262             | 225639  |   262    | 水果  |            [地址](https://www.kaggle.com/datasets/aelchimminut/fruits262)            |
| inaturalist            | 265213  |   1010   | 自然  |           [地址](https://github.com/visipedia/inat_comp/tree/master/2017)            |
| indoor-scenes          |  15588  |    67    | 室内  |       [地址](https://www.kaggle.com/datasets/itsahmad/indoor-scenes-cvpr-2019)       |
86
| Products-10k           | 141931  |   9691   | 商品  |                       [地址](https://products-10k.github.io/)                        |
H
HydrogenSulfate 已提交
87
| CompCars               |  16016  |   431    | 车辆  |     [地址](http://​​​​​​http://ai.stanford.edu/~jkrause/cars/car_dataset.html​)      |
88 89 90 91
| **Total**              | **6M**  | **192K** |   -   |                                          -                                           |

最终的模型精度指标如下表所示:

H
HydrogenSulfate 已提交
92 93 94 95 96 97 98 99 100
  | 模型       | Aliproduct      | VeRI-Wild       | LogoDet-3k      | iCartoonFace    | SOP             | Inshop          |
  | :--------- | :-------------- | :-------------- | :-------------- | :-------------- | :-------------- | :-------------- |
  | -          | recall@1%(mAP%) | recall@1%(mAP%) | recall@1%(mAP%) | recall@1%(mAP%) | recall@1%(mAP%) | recall@1%(mAP%) |
  | PP-ShiTuV2 | 84.2(83.3)      | 87.8(68.8)      | 88.0(63.2)      | 53.6(27.5)      | 77.6(55.3)      | 90.8(74.3)      |

  | 模型       | gldv2           | imdb_face       | iNat            | instre          | sketch          | sop<sup>*</sup> |
  | :--------- | :-------------- | :-------------- | :-------------- | :-------------- | :-------------- | :-------------- |
  | -          | recall@1%(mAP%) | recall@1%(mAP%) | recall@1%(mAP%) | recall@1%(mAP%) | recall@1%(mAP%) | recall@1%(mAP%) |
  | PP-ShiTuV2 | 98.1(90.5)      | 35.9(11.2)      | 38.6(23.9)      | 87.7(71.4)      | 39.3(15.6)      | 98.3(90.9)      |
101 102

* 预训练模型地址:[general_PPLCNetV2_base_pretrained_v1.0.pdparams](https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/PPShiTuV2/general_PPLCNetV2_base_pretrained_v1.0.pdparams)
103
* 采用的评测指标为:`Recall@1``mAP`
104 105 106
* 速度评测机器的 CPU 具体信息为:`Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz`
* 速度指标的评测条件为: 开启 MKLDNN, 线程数设置为 10

H
HydrogenSulfate 已提交
107
<a name="5"></a>
S
sibo2rr 已提交
108

H
HydrogenSulfate 已提交
109
## 5. 自定义特征提取
S
sibo2rr 已提交
110

H
HydrogenSulfate 已提交
111
自定义特征提取,是指依据自己的任务,重新训练特征提取模型。
S
sibo2rr 已提交
112

113
下面基于 `GeneralRecognitionV2_PPLCNetV2_base.yaml` 配置文件,介绍主要的四个步骤:1)数据准备;2)模型训练;3)模型评估;4)模型推理
S
sibo2rr 已提交
114

H
HydrogenSulfate 已提交
115
<a name="5.1"></a>
B
Bin Lu 已提交
116

H
HydrogenSulfate 已提交
117
### 5.1 数据准备
S
sibo2rr 已提交
118

H
HydrogenSulfate 已提交
119
首先需要基于任务定制自己的数据集。数据集格式与文件结构详见[数据集格式说明](../data_preparation/recognition_dataset.md)
S
sibo2rr 已提交
120

H
HydrogenSulfate 已提交
121
准备完毕之后还需要在配置文件中修改数据配置相关的内容, 主要包括数据集的地址以及类别数量。对应到配置文件中的位置如下所示:
S
stephon 已提交
122

H
HydrogenSulfate 已提交
123 124
- 修改类别数:
  ```yaml
125
  Head:
126 127 128 129 130 131 132 133
    name: FC
    embedding_size: *feat_dim
    class_num: 192612  # 此处表示类别数
    weight_attr:
      initializer:
        name: Normal
        std: 0.001
    bias_attr: False
H
HydrogenSulfate 已提交
134 135 136
  ```
- 修改训练数据集配置:
  ```yaml
137 138 139 140 141
  Train:
    dataset:
      name: ImageNetDataset
      image_root: ./dataset/     # 此处表示train数据所在的目录
      cls_label_path: ./dataset/train_reg_all_data.txt  # 此处表示train数据集label文件的地址
142
      relabel: True
H
HydrogenSulfate 已提交
143 144 145
  ```
- 修改评估数据集中query数据配置:
  ```yaml
146 147 148 149 150
  Query:
    dataset:
      name: VeriWild
      image_root: ./dataset/Aliproduct/    # 此处表示query数据集所在的目录
      cls_label_path: ./dataset/Aliproduct/val_list.txt    # 此处表示query数据集label文件的地址
H
HydrogenSulfate 已提交
151 152 153
  ```
- 修改评估数据集中gallery数据配置:
  ```yaml
154 155 156 157 158
  Gallery:
    dataset:
      name: VeriWild
      image_root: ./dataset/Aliproduct/    # 此处表示gallery数据集所在的目录
      cls_label_path: ./dataset/Aliproduct/val_list.txt   # 此处表示gallery数据集label文件的地址
H
HydrogenSulfate 已提交
159 160 161 162 163 164 165
  ```

<a name="5.2"></a>

### 5.2 模型训练

模型训练主要包括启动训练和断点恢复训练的功能
S
sibo2rr 已提交
166

H
HydrogenSulfate 已提交
167 168 169 170
- 单机单卡训练
  ```shell
  export CUDA_VISIBLE_DEVICES=0
  python3.7 tools/train.py \
171
  -c ./ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml
H
HydrogenSulfate 已提交
172 173 174 175 176 177
  ```
- 单机多卡训练
  ```shell
  export CUDA_VISIBLE_DEVICES=0,1,2,3
  python3.7 -m paddle.distributed.launch \
  --gpus="0,1,2,3" tools/train.py \
178
  -c ./ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml
H
HydrogenSulfate 已提交
179 180 181 182 183 184 185 186 187 188
  ```
**注意:**
配置文件中默认采用`在线评估`的方式,如果你想加快训练速度,可以关闭`在线评估`功能,只需要在上述命令的后面,增加 `-o Global.eval_during_train=False`

训练完毕后,在 output 目录下会生成最终模型文件 `latest.pdparams``best_model.pdarams` 和训练日志文件 `train.log`。其中,`best_model` 保存了当前评测指标下的最佳模型,`latest` 用来保存最新生成的模型, 方便在任务中断的情况下从断点位置恢复训练。通过在上述训练命令的末尾加上`-o Global.checkpoint="path_to_resume_checkpoint"`即可从断点恢复训练,示例如下。

- 单机单卡断点恢复训练
  ```shell
  export CUDA_VISIBLE_DEVICES=0
  python3.7 tools/train.py \
189
  -c ./ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml \
H
HydrogenSulfate 已提交
190 191 192 193 194 195 196
  -o Global.checkpoint="output/RecModel/latest"
  ```
- 单机多卡断点恢复训练
  ```shell
  export CUDA_VISIBLE_DEVICES=0,1,2,3
  python3.7 -m paddle.distributed.launch \
  --gpus="0,1,2,3" tools/train.py \
197
  -c ./ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml \
H
HydrogenSulfate 已提交
198 199 200 201 202 203 204 205
  -o Global.checkpoint="output/RecModel/latest"
  ```

<a name="5.3"></a>

### 5.3 模型评估

除了训练过程中对模型进行的在线评估,也可以手动启动评估程序来获得指定的模型的精度指标。
S
sibo2rr 已提交
206

B
Bin Lu 已提交
207
- 单卡评估
H
HydrogenSulfate 已提交
208 209 210
  ```shell
  export CUDA_VISIBLE_DEVICES=0
  python3.7 tools/eval.py \
211
  -c ./ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml \
H
HydrogenSulfate 已提交
212 213
  -o Global.pretrained_model="output/RecModel/best_model"
  ```
S
stephon 已提交
214

B
Bin Lu 已提交
215
- 多卡评估
H
HydrogenSulfate 已提交
216 217 218 219
  ```shell
  export CUDA_VISIBLE_DEVICES=0,1,2,3
  python3.7 -m paddle.distributed.launch \
  --gpus="0,1,2,3" tools/eval.py \
220
  -c ./ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml \
H
HydrogenSulfate 已提交
221 222 223
  -o  Global.pretrained_model="output/RecModel/best_model"
  ```
**注:** 建议使用多卡评估。该方式可以利用多卡并行计算快速得到全部数据的特征,能够加速评估的过程。
S
stephon 已提交
224

H
HydrogenSulfate 已提交
225
<a name="5.4"></a>
S
sibo2rr 已提交
226

H
HydrogenSulfate 已提交
227
### 5.4 模型推理
S
sibo2rr 已提交
228

H
HydrogenSulfate 已提交
229
推理过程包括两个步骤: 1)导出推理模型;2)模型推理以获取特征向量
S
sibo2rr 已提交
230

H
HydrogenSulfate 已提交
231
#### 5.4.1 导出推理模型
S
sibo2rr 已提交
232

H
HydrogenSulfate 已提交
233 234 235
首先需要将 `*.pdparams` 模型文件转换成 inference 格式,转换命令如下。
```shell
python3.7 tools/export_model.py \
236
-c ./ppcls/configs/GeneralRecognitionV2/GeneralRecognitionV2_PPLCNetV2_base.yaml \
B
Bin Lu 已提交
237
-o Global.pretrained_model="output/RecModel/best_model"
S
stephon 已提交
238
```
H
HydrogenSulfate 已提交
239 240
生成的推理模型默认位于 `PaddleClas/inference` 目录,里面包含三个文件,分别为 `inference.pdmodel``inference.pdiparams``inference.pdiparams.info`
其中`inference.pdmodel` 用来存储推理模型的结构, `inference.pdiparams``inference.pdiparams.info` 用来存储推理模型相关的参数信息。
S
sibo2rr 已提交
241

H
HydrogenSulfate 已提交
242
#### 5.4.2 获取特征向量
S
sibo2rr 已提交
243

H
HydrogenSulfate 已提交
244
使用上一步转换得到的 inference 格式模型,将输入图片转换为对应的特征向量,推理命令如下。
S
sibo2rr 已提交
245

H
HydrogenSulfate 已提交
246
```shell
S
stephon 已提交
247
cd deploy
H
HydrogenSulfate 已提交
248
python3.7 python/predict_rec.py \
B
Bin Lu 已提交
249 250
-c configs/inference_rec.yaml \
-o Global.rec_inference_model_dir="../inference"
B
Bin Lu 已提交
251
```
B
Bin Lu 已提交
252
得到的特征输出格式如下图所示:
B
Bin Lu 已提交
253
![](../../images/feature_extraction_output.png)
B
Bin Lu 已提交
254

H
HydrogenSulfate 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267
在实际使用过程中,仅仅得到特征可能并不能满足业务需求。如果想进一步通过特征检索来进行图像识别,可以参照文档[向量检索](./vector_search.md)

<a name="6"></a>

## 6. 总结

特征提取模块作为图像识别中的关键一环,在网络结构的设计,损失函数的选取上有很大的改进空间。不同的数据集类型有各自不同的特点,如行人重识别、商品识别、人脸识别数据集的分布、图片内容都不尽相同。学术界根据这些特点提出了各种各样的方法,如PCB、MGN、ArcFace、CircleLoss、TripletLoss等,围绕的还是增大类间差异、减少类内差异的最终目标,从而有效地应对各种真实场景数据。

<a name="7"></a>

## 7. 参考文献

1. [PP-LCNet: A Lightweight CPU Convolutional Neural Network](https://arxiv.org/pdf/2109.15099.pdf)
268
2. [Bag of Tricks and A Strong Baseline for Deep Person Re-identification](https://openaccess.thecvf.com/content_CVPRW_2019/papers/TRMTMCT/Luo_Bag_of_Tricks_and_a_Strong_Baseline_for_Deep_Person_CVPRW_2019_paper.pdf)