From a9f78ebae0ce083b181264831c7fd93c853356e7 Mon Sep 17 00:00:00 2001 From: dongshuilong Date: Sat, 23 Oct 2021 19:51:30 +0800 Subject: [PATCH] add classification and recognition model training docs --- .../models_training/classification.md | 302 ++++++++++++++++ docs/zh_CN_tmp/models_training/recognition.md | 326 ++++++++++++++++++ 2 files changed, 628 insertions(+) create mode 100644 docs/zh_CN_tmp/models_training/classification.md create mode 100644 docs/zh_CN_tmp/models_training/recognition.md diff --git a/docs/zh_CN_tmp/models_training/classification.md b/docs/zh_CN_tmp/models_training/classification.md new file mode 100644 index 00000000..ad6befa8 --- /dev/null +++ b/docs/zh_CN_tmp/models_training/classification.md @@ -0,0 +1,302 @@ +# 图像分类 +--- +图像分类是根据图像的语义信息将不同类别图像区分开来,是计算机视觉中重要的基本问题,也是图像检测、图像分割、物体跟踪、行为分析等其他高层视觉任务的基础。图像分类在很多领域有广泛应用,包括安防领域的人脸识别和智能视频分析等,交通领域的交通场景识别,互联网领域基于内容的图像检索和相册自动归类,医学领域的图像识别等。 + +一般来说,图像分类通过手工特征或特征学习方法对整个图像进行全部描述,然后使用分类器判别物体类别,因此如何提取图像的特征至关重要。在深度学习算法之前使用较多的是基于词袋(Bag of Words)模型的物体分类方法。而基于深度学习的图像分类方法,可以通过有监督或无监督的方式学习层次化的特征描述,从而取代了手工设计或选择图像特征的工作。深度学习模型中的卷积神经网络(Convolution Neural Network, CNN)近年来在图像领域取得了惊人的成绩,CNN直接利用图像像素信息作为输入,最大程度上保留了输入图像的所有信息,通过卷积操作进行特征的提取和高层抽象,模型输出直接是图像识别的结果。这种基于"输入-输出"直接端到端的学习方法取得了非常好的效果,得到了广泛的应用。 + +图像分类是计算机视觉里很基础但又重要的一个领域,其研究成果一直影响着计算机视觉甚至深度学习的发展,图像分类有很多子领域,如多标签分类、细粒度分类等,此处只对单标签图像分类做一个简述。 + +具体图像分类算法介绍详见[文档](../algorithm_introduction/classificaiton_models.md)。 + +## 一、数据集介绍 + +### 1.1 ImageNet-1k + +ImageNet项目是一个大型视觉数据库,用于视觉目标识别软件研究。该项目已手动注释了1400多万张图像,以指出图片中的对象,并在至少100万张图像中提供了边框。ImageNet-1k是ImageNet数据集的子集,其包含1000个类别。训练集包含1281167个图像数据,验证集包含50000个图像数据。2010年以来,ImageNet项目每年举办一次图像分类竞赛,即ImageNet大规模视觉识别挑战赛(ILSVRC)。挑战赛使用的数据集即为ImageNet-1k。到目前为止,ImageNet-1k已经成为计算机视觉领域发展的最重要的数据集之一,其促进了整个计算机视觉的发展,很多计算机视觉下游任务的初始化模型都是基于该数据集训练得到的权重。 + +### 1.2 CIFAR-10/CIFAR-100 + +CIFAR-10数据集由10个类的60000个彩色图像组成,图像分辨率为32x32,每个类有6000个图像,其中训练集5000张,验证集1000张,10个不同的类代表飞机、汽车、鸟类、猫、鹿、狗、青蛙、马、轮船和卡车。CIFAR-100数据集是CIFAR-10的扩展,由100个类的60000个彩色图像组成,图像分辨率为32x32,每个类有600个图像,其中训练集500张,验证集100张。由于这两个数据集规模较小,因此可以让研究人员快速尝试不同的算法。这两个数据集也是图像分类领域测试模型好坏的常用数据集。 + +## 二、图像分类的流程 + +将准备好的训练数据做相应的数据预处理后经过图像分类模型,模型的输出与真实标签做交叉熵损失函数,该损失函数描述了模型的收敛方向,遍历所有的图片数据输入模型,对最终损失函数通过某些优化器做相应的梯度下降,将梯度信息回传到模型中,更新模型的权重,如此循环往复遍历多次数据,即可得到一个图像分类的模型。 + +### 2.1 数据及其预处理 + +数据的质量及数量往往可以决定一个模型的好坏。在图像分类领域,数据包括图像及标签。在大部分情形下,带有标签的数据比较匮乏,所以数量很难达到使模型饱和的程度,为了可以使模型学习更多的图像特征,图像数据在进入模型之前要经过很多图像变换或者数据增强,来保证输入图像数据的多样性,从而保证模型有更好的泛化能力。PaddleClas提供了训练ImageNet-1k的标准图像变换,也提供了8中数据增强的方法,相关代码可以[数据处理](../../../ppcls/data/preprocess),配置文件可以参考[数据增强配置文件](../../../ppcls/configs/ImageNet/DataAugment)。 + +### 2.2 模型准备 + +在数据确定后,模型往往决定了最终算法精度的上限,在图像分类领域,经典的模型层出不穷,PaddleClas提供了35个系列共164个ImageNet预训练模型。具体的精度、速度等指标请参考[骨干网络和预训练模型库](../ImageNet_models_cn.md)。 + +### 2.3 模型训练 + +在准备好数据、模型后,便可以开始迭代模型并更新模型的参数。经过多次迭代最终可以得到训练好的模型来做图像分类任务。图像分类的训练过程需要很多经验,涉及很多超参数的设置,PaddleClas提供了一些列的[训练调优方法](../models/Tricks.md),可以快速助你获得高精度的模型。 + +### 2.4 模型评估 + +当训练得到一个模型之后,如何确定模型的好坏,需要将模型在验证集上进行评估。评估指标一般是Top1-Acc或者Top5-Acc,该指标越高往往代表模型性能越好。 + +## 三、使用方法介绍 + +请参考[安装指南](../../zh_CN/tutorials/install.md)配置运行环境,并根据[快速开始](../../zh_CN/tutorials/quick_start_new_user.md)文档准备flower102数据集,本章节下面所有的实验均以flower102数据集为例。 + +PaddleClas目前支持的训练/评估环境如下: +```shell +└── CPU/单卡GPU +    ├── Linux +    └── Windows + +└── 多卡GPU + └── Linux +``` + +### 3.1 基于CPU/单卡GPU上的训练与评估 + +在基于CPU/单卡GPU上训练与评估,推荐使用`tools/train.py`与`tools/eval.py`脚本。关于Linux平台多卡GPU环境下的训练与评估,请参考[3.2. 基于Linux+GPU的模型训练与评估](#3.2)。 + + + +#### 3.1.1 模型训练 + +准备好配置文件之后,可以使用下面的方式启动训练。 + +``` +python3 tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Arch.pretrained=False \ + -o Global.device=gpu +``` + +其中,`-c`用于指定配置文件的路径,`-o`用于指定需要修改或者添加的参数,其中`-o Arch.pretrained=False`表示不使用预训练模型,`-o Global.device=gpu`表示使用GPU进行训练。如果希望使用CPU进行训练,则需要将`Global.device`设置为`cpu`。 + +更详细的训练配置,也可以直接修改模型对应的配置文件。具体配置参数参考[配置文档](config_description.md)。 + +运行上述命令,可以看到输出日志,示例如下: + +* 如果在训练中使用了mixup或者cutmix的数据增广方式,那么日志中将不会打印top-1与top-k(默认为5)信息: + ``` + ... + [Train][Epoch 3/20][Avg]CELoss: 6.46287, loss: 6.46287 + ... + [Eval][Epoch 3][Avg]CELoss: 5.94309, loss: 5.94309, top1: 0.01961, top5: 0.07941 + ... + ``` + +* 如果训练过程中没有使用mixup或者cutmix的数据增广,那么除了上述信息外,日志中也会打印出top-1与top-k(默认为5)的信息: + + ``` + ... + [Train][Epoch 3/20][Avg]CELoss: 6.12570, loss: 6.12570, top1: 0.01765, top5: 0.06961 + ... + [Eval][Epoch 3][Avg]CELoss: 5.40727, loss: 5.40727, top1: 0.07549, top5: 0.20980 + ... + ``` + +训练期间也可以通过VisualDL实时观察loss变化,详见[VisualDL](../extension/VisualDL.md)。 + +#### 3.1.2 模型微调 + +根据自己的数据集路径设置好配置文件后,可以通过加载预训练模型的方式进行微调,如下所示。 + +``` +python3 tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Arch.pretrained=True \ + -o Global.device=gpu +``` + +其中`Arch.pretrained`设置为`True`表示加载ImageNet的预训练模型,此外,`Arch.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。 + +我们也提供了大量基于`ImageNet-1k`数据集的预训练模型,模型列表及下载地址详见[模型库概览](../models/models_intro.md)。 + + + +#### 3.1.3 模型恢复训练 + +如果训练任务因为其他原因被终止,也可以加载断点权重文件,继续训练: + +``` +python3 tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Global.checkpoints="./output/MobileNetV3_large_x1_0/epoch_5" \ + -o Global.device=gpu +``` + +其中配置文件不需要做任何修改,只需要在继续训练时设置`Global.checkpoints`参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。 + +**注意**: + +* `-o Global.checkpoints`参数无需包含断点权重文件的后缀名,上述训练命令会在训练过程中生成如下所示的断点权重文件,若想从断点`5`继续训练,则`Global.checkpoints`参数只需设置为`"../output/MobileNetV3_large_x1_0/epoch_5"`,PaddleClas会自动补充后缀名。output目录下的文件结构如下所示: + + ```shell + output + ├── MobileNetV3_large_x1_0 + │   ├── best_model.pdopt + │   ├── best_model.pdparams + │   ├── best_model.pdstates + │   ├── epoch_1.pdopt + │   ├── epoch_1.pdparams + │   ├── epoch_1.pdstates + . + . + . + ``` + + + +#### 3.1.4 模型评估 + +可以通过以下命令进行模型评估。 + +```bash +python3 tools/eval.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model +``` + +上述命令将使用`./configs/quick_start/MobileNetV3_large_x1_0.yaml`作为配置文件,对上述训练得到的模型`./output/MobileNetV3_large_x1_0/best_model`进行评估。你也可以通过更改配置文件中的参数来设置评估,也可以通过`-o`参数更新配置,如上所示。 + +可配置的部分评估参数说明如下: +* `Arch.name`:模型名称 +* `Global.pretrained_model`:待评估的模型预训练模型文件路径 + +**注意:** 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[1.3 模型恢复训练](#1.3)。 + + + +### 3.2. 基于Linux+多卡GPU的模型训练与评估 + +如果机器环境为Linux+GPU,那么推荐使用`paddle.distributed.launch`启动模型训练脚本(`tools/train.py`)、评估脚本(`tools/eval.py`),可以更方便地启动多卡训练与评估。 + +#### 3.2.1 模型训练 + +参考如下方式启动模型训练,`paddle.distributed.launch`通过设置`gpus`指定GPU运行卡号: + +```bash +# PaddleClas通过launch方式启动多卡多进程训练 + +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch \ + --gpus="0,1,2,3" \ + tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml +``` + +输出日志信息的格式同上,详见[3.1.1 模型训练](#3.1.1)。 + +#### 3.2.2 模型微调 + +根据自己的数据集配置好配置文件之后,可以加载预训练模型进行微调,如下所示。 + +```shell +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch \ + --gpus="0,1,2,3" \ + tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Arch.pretrained=True +``` + +其中`Arch.pretrained`为`True`或`False`,当然也可以设置加载预训练权重文件的路径,使用时需要换成自己的预训练模型权重文件路径,也可以直接在配置文件中修改该路径。 + +30分钟玩转PaddleClas[尝鲜版](./quick_start_new_user.md)与[进阶版](./quick_start_professional.md)中包含大量模型微调的示例,可以参考该章节在特定的数据集上进行模型微调。 + + + +#### 3.2.3 模型恢复训练 + +如果训练任务因为其他原因被终止,也可以加载断点权重文件继续训练。 + +``` +export CUDA_VISIBLE_DEVICES=0,1,2,3 + +python3 -m paddle.distributed.launch \ + --gpus="0,1,2,3" \ + tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Global.checkpoints="./output/MobileNetV3_large_x1_0/epoch_5" \ + -o Global.device=gpu +``` + +其中配置文件不需要做任何修改,只需要在训练时设置`Global.checkpoints`参数即可,该参数表示加载的断点权重文件路径,使用该参数会同时加载保存的模型参数权重和学习率、优化器等信息,详见[3.1.3 模型恢复训练](#3.1.3)。 + +#### 3.2.4 模型评估 + +可以通过以下命令进行模型评估。 + +```bash +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch \ + tools/eval.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model +``` + +参数说明详见[1.4 模型评估](#1.4)。 + + + +### 3.3 使用预训练模型进行模型预测 + +模型训练完成之后,可以加载训练得到的预训练模型,进行模型预测。在模型库的 `tools/infer/infer.py` 中提供了完整的示例,只需执行下述命令即可完成模型预测: + +```python +python3 tools/infer.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Infer.infer_imgs=dataset/flowers102/jpg/image_00001.jpg \ + -o Global.pretrained_model=./output/MobileNetV3_large_x1_0/best_model +``` + +参数说明: ++ `Infer.infer_imgs`:待预测的图片文件路径或者批量预测时的图片文件夹。 ++ `Global.pretrained_model`:模型权重文件路径,如 `./output/MobileNetV3_large_x1_0/best_model` + + + +### 3.4 使用inference模型进行模型推理 + +通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。接下来介绍如何用预测引擎进行推理: +首先,对训练好的模型进行转换: + +```bash +python3 tools/export_model.py \ + -c ./ppcls/configs/quick_start/MobileNetV3_large_x1_0.yaml \ + -o Global.pretrained_model=output/MobileNetV3_large_x1_0/best_model +``` + + +其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[3.1.3 模型恢复训练](#3.1.3))。 + +上述命令将生成模型结构文件(`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理: + +进入deploy目录下: + +```bash +cd deploy +``` + +执行命令进行预测,由于默认class_id_map_file是ImageNet数据集的映射文件,所以此处需要置None。 + +```bash +python3 python/predict_cls.py \ + -c configs/inference_cls.yaml \ + -o Global.infer_imgs=../dataset/flowers102/jpg/image_00001.jpg \ + -o Global.inference_model_dir=../inference/ \ + -o PostProcess.Topk.class_id_map_file=None + + +其中: ++ `Global.infer_imgs`:待预测的图片文件路径。 ++ `Global.inference_model_dir`:inference模型结构文件路径,如 `../inference/inference.pdmodel` ++ `Global.use_tensorrt`:是否使用 TesorRT 预测引擎,默认值:`False` ++ `Global.use_gpu`:是否使用 GPU 预测,默认值:`True` ++ `Global.enable_mkldnn`:是否启用`MKL-DNN`加速,默认为`False`。注意`enable_mkldnn`与`use_gpu`同时为`True`时,将忽略`enable_mkldnn`,而使用GPU运行。 ++ `Global.use_fp16`:是否启用`FP16`,默认为`False`。 + + +**注意**: 如果使用`Transformer`系列模型,如`DeiT_***_384`, `ViT_***_384`等,请注意模型的输入数据尺寸,需要设置参数`resize_short=384`, `resize=384`。 + +* 如果你希望提升评测模型速度,使用gpu评测时,建议开启TensorRT加速预测,使用cpu评测时,建议开启MKL-DNN加速预测。 +``` diff --git a/docs/zh_CN_tmp/models_training/recognition.md b/docs/zh_CN_tmp/models_training/recognition.md new file mode 100644 index 00000000..8018b8ce --- /dev/null +++ b/docs/zh_CN_tmp/models_training/recognition.md @@ -0,0 +1,326 @@ +# 图像识别 +--- +在PaddleClas中,图像识别,是指给定一张查询图像,系统能够识别该查询图像类别。广义上,图像分类也是图像识别的一种。但是与普通图像识别不同的是,图像分类只能判别出模型已经学习的类别,如果需要添加新的类别,分类模型只能重新训练。PaddleClas中的图像识别,**对于陌生类别,只需要更新相应的检索库**,就能够正确的识别出查询图像的类别,而无需重新训练模型,这大大增加了识别系统的可用性,同时降低了更新模型的需求,方便用户部署应用。 + +对于一张待查询图片,PaddleClas中的图像识别流程主要分为三部分: + +1. 主体检测:对于给定一个查询图像,主体检测器首先检测出图像的物体,从而去掉无用背景信息,提高识别精度。 +2. 特征提取:对主体检测的各个候选区域,通过特征模型,进行特征提取 +3. 特征检索:将提取的特征与特征库中的向量进行相似度比对,得到其标签信息 + +其中特征库,需要利用已经标注好的图像数据集提前建立。完整的图像识别系统,如下图所示 + +
+ +
+体验整体图像识别系统,或查看特征库建立方法,详见[图像识别快速开始文档](../../zh_CN/tutorials/quick_start_recognition.md)。其中,**图像识别快速开始文档**主要讲解整体流程的使用过程。以下内容,主要对上述三个步骤的训练部分进行介绍。 + +首先,请参考[安装指南](./install.md)配置运行环境。 + +具体目录如下: + +- [主体检测](#主体检测) +- [特征模型训练](特征模型训练) + - [2.1. 特征模型数据准备与处理](#特征模型数据准备与处理) + - [2. 特征模型基于单卡GPU上的训练与评估](#特征模型基于单卡GPU上的训练与评估) + - [2.1 特征模型训练](#特征模型训练) + - [2.2 特征模型恢复训练](#模型恢复训练) + - [2.3 特征模型评估](#特征模型评估) + - [3. 特征模型导出inference模型](#特征导出inference模型) +- [特征检索](#特征检索) +- [基础知识](#基础知识) + + + +## 一、主体检测 + + + +## 二、特征模型训练 + + + +### 2.1 特征模型数据的准备与处理 + +* 进入PaddleClas目录。 + +```bash +## linux or mac, $path_to_PaddleClas表示PaddleClas的根目录,用户需要根据自己的真实目录修改 +cd $path_to_PaddleClas +``` + +* 进入`dataset`目录,为了快速体验PaddleClas图像检索模块,此处使用的数据集为[CUB_200_2011](http://vision.ucsd.edu/sites/default/files/WelinderEtal10_CUB-200.pdf),其是一个包含200类鸟的细粒度鸟类数据集。首先,下载CUB_200_2011数据集,下载方式请参考[官网](http://www.vision.caltech.edu/visipedia/CUB-200-2011.html)。 + +```shell +# linux or mac +cd dataset + +# 将下载后的数据拷贝到此目录 +cp {数据存放的路径}/CUB_200_2011.tgz . + +# 解压 +tar -xzvf CUB_200_2011.tgz + +#进入CUB_200_2011目录 +cd CUB_200_2011 +``` + +该数据集在用作图像检索任务时,通常将前100类当做训练集,后100类当做测试集,所以此处需要将下载的数据集做一些后处理,来更好的适应PaddleClas的图像检索训练。 + +```shell +#新建train和test目录 +mkdir train && mkdir test + +#将数据分成训练集和测试集,前100类作为训练集,后100类作为测试集 +ls images | awk -F "." '{if(int($1)<101)print "mv images/"$0" train/"int($1)}' | sh +ls images | awk -F "." '{if(int($1)>100)print "mv images/"$0" test/"int($1)}' | sh + +#生成train_list和test_list +tree -r -i -f train | grep jpg | awk -F "/" '{print $0" "int($2) " "NR}' > train_list.txt +tree -r -i -f test | grep jpg | awk -F "/" '{print $0" "int($2) " "NR}' > test_list.txt +``` + +至此,现在已经得到`CUB_200_2011`的训练集(`train`目录)、测试集(`test`目录)、`train_list.txt`、`test_list.txt`。 + +数据处理完毕后,`CUB_200_2011`中的`train`目录下应有如下结构: + +``` +├── 1 +│   ├── Black_Footed_Albatross_0001_796111.jpg +│   ├── Black_Footed_Albatross_0002_55.jpg + ... +├── 10 +│   ├── Red_Winged_Blackbird_0001_3695.jpg +│   ├── Red_Winged_Blackbird_0005_5636.jpg +... +``` + +`train_list.txt`应为: + +``` +train/99/Ovenbird_0137_92639.jpg 99 1 +train/99/Ovenbird_0136_92859.jpg 99 2 +train/99/Ovenbird_0135_93168.jpg 99 3 +train/99/Ovenbird_0131_92559.jpg 99 4 +train/99/Ovenbird_0130_92452.jpg 99 5 +... +``` +其中,分隔符为空格" ", 三列数据的含义分别是训练数据的路径、训练数据的label信息、训练数据的unique id。 + +测试集格式与训练集格式相同。 + +**注意**: + +* 当gallery dataset和query dataset相同时,为了去掉检索得到的第一个数据(检索图片本身无须评估),每个数据需要对应一个unique id,用于后续评测mAP、recall@1等指标。关于gallery dataset与query dataset的解析请参考[图像检索数据集介绍](#图像检索数据集介绍), 关于mAP、recall@1等评测指标请参考[图像检索评价指标](#图像检索评价指标)。 + +返回`PaddleClas`根目录 + +```shell +# linux or mac +cd ../../ +``` + + + +### 2.2 特征模型GPU上的训练与评估 + +在基于单卡GPU上训练与评估,推荐使用`tools/train.py`与`tools/eval.py`脚本。 + + + +#### 2.2.1 特征模型训练 + +准备好配置文件之后,可以使用下面的方式启动图像检索任务的训练。PaddleClas训练图像检索任务的方法是度量学习,关于度量学习的解析请参考[度量学习](#度量学习)。 + +```shell +# 单卡GPU +python3 tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ + -o Arch.Backbone.pretrained=True \ + -o Global.device=gpu +# 多卡GPU +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ + -o Arch.Backbone.pretrained=True \ + -o Global.device=gpu +``` + +其中,`-c`用于指定配置文件的路径,`-o`用于指定需要修改或者添加的参数,其中`-o Arch.Backbone.pretrained=True`表示Backbone部分使用预训练模型,此外,`Arch.Backbone.pretrained`也可以指定具体的模型权重文件的地址,使用时需要换成自己的预训练模型权重文件的路径。`-o Global.device=gpu`表示使用GPU进行训练。如果希望使用CPU进行训练,则需要将`Global.device`设置为`cpu`。 + +更详细的训练配置,也可以直接修改模型对应的配置文件。具体配置参数参考[配置文档](config_description.md)。 + +运行上述命令,可以看到输出日志,示例如下: + + ``` + ... + [Train][Epoch 1/50][Avg]CELoss: 6.59110, TripletLossV2: 0.54044, loss: 7.13154 + ... + [Eval][Epoch 1][Avg]recall1: 0.46962, recall5: 0.75608, mAP: 0.21238 + ... + ``` +此处配置文件的Backbone是MobileNetV1,如果想使用其他Backbone,可以重写参数`Arch.Backbone.name`,比如命令中增加`-o Arch.Backbone.name={其他Backbone}`。此外,由于不同模型`Neck`部分的输入维度不同,更换Backbone后可能需要改写此处的输入大小,改写方式类似替换Backbone的名字。 + +在训练Loss部分,此处使用了[CELoss](../../../ppcls/loss/celoss.py)和[TripletLossV2](../../../ppcls/loss/triplet.py),配置文件如下: + +``` +Loss: + Train: + - CELoss: + weight: 1.0 + - TripletLossV2: + weight: 1.0 + margin: 0.5 +``` + +最终的总Loss是所有Loss的加权和,其中weight定义了特定Loss在最终总Loss的权重。如果想替换其他Loss,也可以在配置文件中更改Loss字段,目前支持的Loss请参考[Loss](../../../ppcls/loss)。 + + + +#### 2.2.2 特征模型恢复训练 + +如果训练任务因为其他原因被终止,也可以加载断点权重文件,继续训练: + +```shell +# 单卡 +python3 tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ + -o Global.checkpoints="./output/RecModel/epoch_5" \ + -o Global.device=gpu +# 多卡 +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch tools/train.py \ + -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ + -o Global.checkpoints="./output/RecModel/epoch_5" \ + -o Global.device=gpu +``` + +其中配置文件不需要做任何修改,只需要在继续训练时设置`Global.checkpoints`参数即可,表示加载的断点权重文件路径,使用该参数会同时加载保存的断点权重和学习率、优化器等信息。 + +**注意**: + +* `-o Global.checkpoints`参数无需包含断点权重文件的后缀名,上述训练命令会在训练过程中生成如下所示的断点权重文件,若想从断点`5`继续训练,则`Global.checkpoints`参数只需设置为`"./output/RecModel/epoch_5"`,PaddleClas会自动补充后缀名。 + + ```shell + output/ + └── RecModel + ├── best_model.pdopt + ├── best_model.pdparams + ├── best_model.pdstates + ├── epoch_1.pdopt + ├── epoch_1.pdparams + ├── epoch_1.pdstates + . + . + . + ``` + + + +#### 2.2.3 特征模型评估 + +可以通过以下命令进行模型评估。 + +```bash +# 单卡 +python3 tools/eval.py \ + -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ + -o Global.pretrained_model=./output/RecModel/best_model +# 多卡 +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch tools/eval.py \ + -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ + -o Global.pretrained_model=./output/RecModel/best_model +``` + +上述命令将使用`./configs/quick_start/MobileNetV1_retrieval.yaml`作为配置文件,对上述训练得到的模型`./output/RecModel/best_model`进行评估。你也可以通过更改配置文件中的参数来设置评估,也可以通过`-o`参数更新配置,如上所示。 + +可配置的部分评估参数说明如下: +* `Arch.name`:模型名称 +* `Global.pretrained_model`:待评估的模型的预训练模型文件路径,不同于`Global.Backbone.pretrained`,此处的预训练模型是整个模型的权重,而`Global.Backbone.pretrained`只是Backbone部分的权重。当需要做模型评估时,需要加载整个模型的权重。 +* `Metric.Eval`:待评估的指标,默认评估recall@1、recall@5、mAP。当你不准备评测某一项指标时,可以将对应的试标从配置文件中删除;当你想增加某一项评测指标时,也可以参考[Metric](../../../ppcls/metric/metrics.py)部分在配置文件`Metric.Eval`中添加相关的指标。 + +**注意:** + +* 在加载待评估模型时,需要指定模型文件的路径,但无需包含文件后缀名,PaddleClas会自动补齐`.pdparams`的后缀,如[2.2.2 特征模型恢复训练](#特征模型恢复训练)。 + +* Metric learning任务一般不评测TopkAcc。 + + + +### 2.3 特征模型导出inference模型 + +通过导出inference模型,PaddlePaddle支持使用预测引擎进行预测推理。对训练好的模型进行转换: + +```bash +python3 tools/export_model.py \ + -c ./ppcls/configs/quick_start/MobileNetV1_retrieval.yaml \ + -o Global.pretrained_model=output/RecModel/best_model \ + -o Global.save_inference_dir=./inference +``` + +其中,`Global.pretrained_model`用于指定模型文件路径,该路径仍无需包含模型文件后缀名(如[2.2.2 特征模型恢复训练](#特征模型恢复训练))。当执行后,会在当前目录下生成`./inference`目录,目录下包含`inference.pdiparams`、`inference.pdiparams.info`、`inference.pdmodel`文件。`Global.save_inference_dir`可以指定导出inference模型的路径。此处保存的inference模型在embedding特征层做了截断,即模型最终的输出为n维embedding特征。 + +上述命令将生成模型结构文件(`inference.pdmodel`)和模型权重文件(`inference.pdiparams`),然后可以使用预测引擎进行推理。使用inference模型推理的流程可以参考[基于Python预测引擎预测推理](https://github.com/PaddlePaddle/PaddleClas/blob/develop/docs/zh_CN/inference.md)。 + + + +## 三、特征检索 + +PaddleClas图像检索部分目前支持的环境如下: + +```shell +└── CPU/单卡GPU +    ├── Linux +    ├── MacOS +    └── Windows +``` + +此部分使用了[Faiss](https://github.com/facebookresearch/faiss)作为检索库,其是一个高效的特征检索及聚类的库。此库中集成了多种相似度检索算法,以满足不同的检索场景。在PaddleClas中,支持三种检索算法: + +- **HNSW32**: 一种图索引方法。检索精度较高,速度较快。但是特征库只支持添加图像功能,不支持删除图像特征功能。(默认方法) +- **IVF**:倒排索引检索方法。速度较快,但是精度略低。特征库支持增加、删除图像特功能。 +- **FLAT**: 暴力检索算法。精度最高,但是数据量大时,检索速度较慢。特征库支持增加、删除图像特征功能。 + +详细介绍请参考[Faiss](https://github.com/facebookresearch/faiss)官方文档。 + +具体安装方法如下: + +```python +pip install faiss-cpu==1.7.1post2 +``` + +若使用时,不能正常引用,则`uninstall` 之后,重新`install`,尤其是`windows`下。 + + + +## 四、基础知识 + +图像检索指的是给定一个包含特定实例(例如特定目标、场景、物品等)的查询图像,图像检索旨在从数据库图像中找到包含相同实例的图像。不同于图像分类,图像检索解决的是一个开集问题,训练集中可能不包含被识别的图像的类别。图像检索的整体流程为:首先将图像中表示为一个合适的特征向量,其次,对这些图像的特征向量用欧式距离或余弦距离进行最近邻搜索以找到底库中相似的图像,最后,可以使用一些后处理技术对检索结果进行微调,确定被识别图像的类别等信息。所以,决定一个图像检索算法性能的关键在于图像对应的特征向量的好坏。 + + +- 度量学习(Metric Learning) + +度量学习研究如何在一个特定的任务上学习一个距离函数,使得该距离函数能够帮助基于近邻的算法 (kNN、k-means等) 取得较好的性能。深度度量学习 (Deep Metric Learning )是度量学习的一种方法,它的目标是学习一个从原始特征到低维稠密的向量空间 (嵌入空间,embedding space) 的映射,使得同类对象在嵌入空间上使用常用的距离函数 (欧氏距离、cosine距离等) 计算的距离比较近,而不同类的对象之间的距离则比较远。深度度量学习在计算机视觉领域取得了非常多的成功的应用,比如人脸识别、商品识别、图像检索、行人重识别等。 + + +- 图像检索数据集介绍 + + - 训练集合(train dataset):用来训练模型,使模型能够学习该集合的图像特征。 + - 底库数据集合(gallery dataset):用来提供图像检索任务中的底库数据,该集合可与训练集或测试集相同,也可以不同,当与训练集相同时,测试集的类别体系应与训练集的类别体系相同。 + - 测试集合(query dataset):用来测试模型的好坏,通常要对测试集的每一张测试图片进行特征提取,之后和底库数据的特征进行距离匹配,得到识别结果,后根据识别结果计算整个测试集的指标。 + + +- 图像检索评价指标 + + + - 召回率(recall):表示预测为正例且标签为正例的个数 / 标签为正例的个数 + + - recall@1:检索的top-1中预测正例且标签为正例的个数 / 标签为正例的个数 + - recall@5:检索的top-5中所有预测正例且标签为正例的个数 / 标签为正例的个数 + + + - 平均检索精度(mAP) + + - AP: AP指的是不同召回率上的正确率的平均值 + - mAP: 测试集中所有图片对应的AP的的平均值 -- GitLab