feature_extraction.md 15.1 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-方法)
H
HydrogenSulfate 已提交
9
  - [3.1 PP-ShiTuV2](#31-pp-shituv2)
10 11 12 13
    - [3.1.1 Backbone](#311-backbone)
    - [3.1.2 Neck](#312-neck)
    - [3.1.3 Head](#313-head)
    - [3.1.4 Loss](#314-loss)
H
HydrogenSulfate 已提交
14
- [4. 实验部分](#4-实验部分)
H
HydrogenSulfate 已提交
15
  - [4.1 PP-ShiTuV2](#41-pp-shituv2)
H
HydrogenSulfate 已提交
16 17 18 19 20 21 22 23 24
- [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 已提交
25

S
stephon 已提交
26
<a name="1"></a>
S
sibo2rr 已提交
27

H
HydrogenSulfate 已提交
28
## 1. 摘要
S
sibo2rr 已提交
29

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

S
stephon 已提交
32
<a name="2"></a>
S
stephon 已提交
33

H
HydrogenSulfate 已提交
34 35
## 2. 介绍

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

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

S
stephon 已提交
45
<a name="3"></a>
S
stephon 已提交
46

H
HydrogenSulfate 已提交
47 48
## 3. 方法

H
HydrogenSulfate 已提交
49
### 3.1 PP-ShiTuV2
50 51

#### 3.1.1 Backbone
H
HydrogenSulfate 已提交
52

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

H
HydrogenSulfate 已提交
55
#### 3.1.2 Neck
56 57 58

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

H
HydrogenSulfate 已提交
59
#### 3.1.3 Head
60 61 62

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

H
HydrogenSulfate 已提交
63
#### 3.1.4 Loss
64 65 66

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 已提交
67 68 69 70
<a name="4"></a>

## 4. 实验部分

H
HydrogenSulfate 已提交
71
### 4.1 PP-ShiTuV2
72

H
HydrogenSulfate 已提交
73
我们对原有的训练数据进行了合理扩充与优化,最终使用如下 16 个公开数据集的汇总:
74 75 76 77 78 79 80 81 82

| 数据集                 | 数据量  |  类别数  | 场景  |                                      数据集地址                                      |
| :--------------------- | :-----: | :------: | :---: | :----------------------------------------------------------------------------------: |
| 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 已提交
83 84 85
| 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)            |
86
| Fashion Product Images |  44441  |    47    | 商品  | [地址](https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset) |
H
HydrogenSulfate 已提交
87 88 89 90 91
| 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)       |
92
| Products-10k           | 141931  |   9691   | 商品  |                       [地址](https://products-10k.github.io/)                        |
H
HydrogenSulfate 已提交
93
| CompCars               |  16016  |   431    | 车辆  |     [地址](http://​​​​​​http://ai.stanford.edu/~jkrause/cars/car_dataset.html​)      |
94 95 96 97
| **Total**              | **6M**  | **192K** |   -   |                                          -                                           |

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

H
HydrogenSulfate 已提交
98 99 100 101 102 103 104 105 106
  | 模型       | 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)      |
107 108

* 预训练模型地址:[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)
109
* 采用的评测指标为:`Recall@1``mAP`
110 111 112
* 速度评测机器的 CPU 具体信息为:`Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz`
* 速度指标的评测条件为: 开启 MKLDNN, 线程数设置为 10

H
HydrogenSulfate 已提交
113
<a name="5"></a>
S
sibo2rr 已提交
114

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

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

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

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

H
HydrogenSulfate 已提交
123
### 5.1 数据准备
S
sibo2rr 已提交
124

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

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

H
HydrogenSulfate 已提交
129 130
- 修改类别数:
  ```yaml
131 132 133 134
  Head:
    name: ArcMargin
    embedding_size: 512
    class_num: 185341    # 此处表示类别数
H
HydrogenSulfate 已提交
135 136 137
  ```
- 修改训练数据集配置:
  ```yaml
138 139 140 141 142
  Train:
    dataset:
      name: ImageNetDataset
      image_root: ./dataset/     # 此处表示train数据所在的目录
      cls_label_path: ./dataset/train_reg_all_data.txt  # 此处表示train数据集label文件的地址
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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
- 单机单卡训练
  ```shell
  export CUDA_VISIBLE_DEVICES=0
  python3.7 tools/train.py \
  -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml
  ```
- 单机多卡训练
  ```shell
  export CUDA_VISIBLE_DEVICES=0,1,2,3
  python3.7 -m paddle.distributed.launch \
  --gpus="0,1,2,3" tools/train.py \
  -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml
  ```
**注意:**
配置文件中默认采用`在线评估`的方式,如果你想加快训练速度,可以关闭`在线评估`功能,只需要在上述命令的后面,增加 `-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 \
  -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml \
  -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 \
  -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml \
  -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 211 212 213
  ```shell
  export CUDA_VISIBLE_DEVICES=0
  python3.7 tools/eval.py \
  -c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml \
  -o Global.pretrained_model="output/RecModel/best_model"
  ```
S
stephon 已提交
214

B
Bin Lu 已提交
215
- 多卡评估
H
HydrogenSulfate 已提交
216 217 218 219 220 221 222 223
  ```shell
  export CUDA_VISIBLE_DEVICES=0,1,2,3
  python3.7 -m paddle.distributed.launch \
  --gpus="0,1,2,3" tools/eval.py \
  -c  ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml \
  -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 \
B
Bin Lu 已提交
236 237
-c ppcls/configs/GeneralRecognition/GeneralRecognition_PPLCNet_x2_5.yaml \
-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 268
在实际使用过程中,仅仅得到特征可能并不能满足业务需求。如果想进一步通过特征检索来进行图像识别,可以参照文档[向量检索](./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)
2. [ArcFace: Additive Angular Margin Loss for Deep Face Recognition](https://arxiv.org/abs/1801.07698)