diff --git a/deploy/pipeline/README.md b/deploy/pipeline/README.md index cbb2d86fbe0a985545f0c466886611a9c4eca729..19534194700f4dcc270e63840302303d784e508b 100644 --- a/deploy/pipeline/README.md +++ b/deploy/pipeline/README.md @@ -128,7 +128,7 @@ - [快速开始](docs/tutorials/ppvehicle_attribute.md) -- 二次开发教程 +- [二次开发教程](../../docs/advanced_tutorials/customization/ppvehicle_attribute.md) #### 违章检测 diff --git a/docs/advanced_tutorials/customization/pphuman_attribute.md b/docs/advanced_tutorials/customization/pphuman_attribute.md index 692a9dba57dba058db970995f2874732bab8e07d..75cdd4aebc22ddaae052c8f9be64e527d9f62fea 100644 --- a/docs/advanced_tutorials/customization/pphuman_attribute.md +++ b/docs/advanced_tutorials/customization/pphuman_attribute.md @@ -1,6 +1,6 @@ 简体中文 | [English](./pphuman_attribute_en.md) -# 属性识别任务二次开发 +# 行人属性识别任务二次开发 ## 数据准备 diff --git a/docs/advanced_tutorials/customization/pphuman_attribute_en.md b/docs/advanced_tutorials/customization/pphuman_attribute_en.md index fdfe74eb2b3c531a0e03cc6e2c7e8ad78114f0b3..1dd3813ec3ff4c5e9ce66a7952b773e49555e307 100644 --- a/docs/advanced_tutorials/customization/pphuman_attribute_en.md +++ b/docs/advanced_tutorials/customization/pphuman_attribute_en.md @@ -1,6 +1,6 @@ [简体中文](pphuman_attribute.md) | English -# Customized attribute recognition +# Customized Pedestrian Attribute Recognition ## Data Preparation @@ -51,7 +51,7 @@ After the annotation is completed, the model will use the detection box to inter -Model Training +## Model Training Once the data is annotated, it can be used for model training to complete the optimization of the customized model. diff --git a/docs/advanced_tutorials/customization/ppvehicle_attribute.md b/docs/advanced_tutorials/customization/ppvehicle_attribute.md new file mode 100644 index 0000000000000000000000000000000000000000..c40c9cb3059ed9834fff89af7a5a3e78cb5a4bec --- /dev/null +++ b/docs/advanced_tutorials/customization/ppvehicle_attribute.md @@ -0,0 +1,257 @@ +简体中文 | [English](./ppvehicle_attribute_en.md) + +# 车辆属性识别任务二次开发 + +## 数据准备 + +### 数据格式 + +车辆属性模型采用VeRi数据集的属性,共计10种车辆颜色及9种车型, 具体如下: +``` +# 车辆颜色 +- "yellow" +- "orange" +- "green" +- "gray" +- "red" +- "blue" +- "white" +- "golden" +- "brown" +- "black" + +# 车型 +- "sedan" +- "suv" +- "van" +- "hatchback" +- "mpv" +- "pickup" +- "bus" +- "truck" +- "estate" +``` + +在标注文件中使用长度为19的序列来表示上述属性。 + +举例: + +[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0] + +前10位中,位序号0的值为1,表示车辆颜色为`"yellow"`。 + +后9位中,位序号11的值为1,表示车型为`"suv"`。 + + +### 数据标注 + +理解了上面`数据格式`的含义后,就可以进行数据标注的工作。其本质是:每张车辆的图片,建立一组长度为19的标注项,分别对应各项属性值。 + +举例: + +对于一张原始图片, + +1) 使用检测框,标注图片中每台车辆的位置。 + +2) 每一个检测框(对应每辆车),包含一组19位的属性值数组,数组的每一位以0或1表示。对应上述19个属性分类。例如,如果颜色是'orange',则数组索引为1的位置值为1,如果车型是'sedan',则数组索引为10的位置值为1。 + +标注完成后利用检测框将每辆车截取成只包含单辆车的图片,则图片与19位属性标注建立了对应关系。也可先截取再进行标注,效果相同。 + + +## 模型训练 + +数据标注完成后,就可以拿来做模型的训练,完成自定义模型的优化工作。 + +其主要有两步工作需要完成:1)将数据与标注数据整理成训练格式。2)修改配置文件开始训练。 + +### 训练数据格式 + +训练数据包括训练使用的图片和一个训练列表train.txt,其具体位置在训练配置中指定,其放置方式示例如下: +``` +Attribute/ +|-- data 训练图片文件夹 +| |-- 00001.jpg +| |-- 00002.jpg +| `-- 0000x.jpg +`-- train.txt 训练数据列表 + +``` + +train.txt文件内为所有训练图片名称(相对于根路径的文件路径)+ 19个标注值 + +其每一行表示一辆车的图片和标注结果。其格式为: + +``` +00001.jpg 0,0,1,0,.... +``` + +注意:1)图片与标注值之间是以Tab[\t]符号隔开, 2)标注值之间是以逗号[,]隔开。该格式不能错,否则解析失败。 + +### 修改配置开始训练 + +首先执行以下命令下载训练代码(更多环境问题请参考[Install_PaddleClas](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.4/docs/en/installation/install_paddleclas_en.md)): + +```shell +git clone https://github.com/PaddlePaddle/PaddleClas +``` + +需要在[配置文件](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.4/ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml)中,修改的配置项如下: +```yaml +DataLoader: + Train: + dataset: + name: MultiLabelDataset + image_root: "dataset/VeRi/" # the root path of training images + cls_label_path: "dataset/VeRi/train_list.txt" # the location of the training list file + label_ratio: True + transform_ops: + ... + + Eval: + dataset: + name: MultiLabelDataset + image_root: "dataset/VeRi/" # the root path of evaluation images + cls_label_path: "dataset/VeRi/val_list.txt" # the location of the evaluation list file + label_ratio: True + transform_ops: + ... +``` + +注意: +1. 这里image_root路径+train.txt中图片相对路径,对应图片的完整路径位置。 +2. 如果有修改属性数量,则还需修改内容配置项中属性种类数量: +```yaml +# model architecture +Arch: + name: "PPLCNet_x1_0" + pretrained: True + use_ssld: True + class_num: 19 #属性种类数量 +``` + +然后运行以下命令开始训练。 + +``` +#多卡训练 +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch \ + --gpus="0,1,2,3" \ + tools/train.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml + +#单卡训练 +python3 tools/train.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml +``` + +训练完成后可以执行以下命令进行性能评估: +``` +#多卡评估 +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch \ + --gpus="0,1,2,3" \ + tools/eval.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml \ + -o Global.pretrained_model=./output/PPLCNet_x1_0/best_model + +#单卡评估 +python3 tools/eval.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml \ + -o Global.pretrained_model=./output/PPLCNet_x1_0/best_model +``` + + +### 模型导出 + +使用下述命令将训练好的模型导出为预测部署模型。 + +``` +python3 tools/export_model.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml \ + -o Global.pretrained_model=output/PPLCNet_x1_0/best_model \ + -o Global.save_inference_dir=deploy/models/PPLCNet_x1_0_vehicle_attribute_model +``` + +导出模型后,如果希望在PP-Vehicle中使用,则需要下载[预测部署模型](https://bj.bcebos.com/v1/paddledet/models/pipeline/vehicle_attribute_model.zip),解压并将其中的配置文件`infer_cfg.yml`文件,放置到导出的模型文件夹`PPLCNet_x1_0_vehicle_attribute_model`中。 + +使用时在PP-Vehicle中的配置文件`./deploy/pipeline/config/infer_cfg_ppvehicle.yml`中修改新的模型路径`model_dir`项,并开启功能`enable: True`。 +``` +VEHICLE_ATTR: + model_dir: [YOUR_DEPLOY_MODEL_DIR]/PPLCNet_x1_0_vehicle_attribute_infer/ #新导出的模型路径位置 + enable: True #开启功能 +``` +然后可以使用-->至此即完成新增属性类别识别任务。 + +## 属性增减 + +该过程与行人属性的增减过程相似,如果需要增加、减少属性数量,则需要: + +1)标注时需增加新属性类别信息或删减属性类别信息; + +2)对应修改训练中train.txt所使用的属性数量和名称; + +3)修改训练配置,例如``PaddleClas/blob/develop/ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml``文件中的属性数量,详细见上述`修改配置开始训练`部分。 + +增加属性示例: + +1. 在标注数据时在19位后继续增加新的属性标注数值; +2. 在train.txt文件的标注数值中也增加新的属性数值。 +3. 注意属性类型在train.txt中属性数值列表中的位置的对应关系需要固定。 + +
+ +
+ +删减属性同理。 + + +## 修改后处理代码 + +修改了属性定义后,pipeline后处理部分也需要做相应修改,主要影响结果可视化时的显示结果。 + +相应代码在[文件](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/deploy/pipeline/ppvehicle/vehicle_attr.py#L108)中`postprocess`函数。 + +其函数实现说明如下: + +```python + # 在类的初始化函数中,定义了颜色/车型的名称 + self.color_list = [ + "yellow", "orange", "green", "gray", "red", "blue", "white", + "golden", "brown", "black" + ] + self.type_list = [ + "sedan", "suv", "van", "hatchback", "mpv", "pickup", "bus", "truck", + "estate" + ] + + ... + + def postprocess(self, inputs, result): + # postprocess output of predictor + im_results = result['output'] + batch_res = [] + for res in im_results: + res = res.tolist() + attr_res = [] + color_res_str = "Color: " + type_res_str = "Type: " + color_idx = np.argmax(res[:10]) # 前10项表示各项颜色得分,取得分最大项作为颜色结果 + type_idx = np.argmax(res[10:]) # 后9项表示各项车型得分,取得分最大项作为车型结果 + + # 颜色和车型的得分都需要超过对应阈值,否则视为'UnKnown' + if res[color_idx] >= self.color_threshold: + color_res_str += self.color_list[color_idx] + else: + color_res_str += "Unknown" + attr_res.append(color_res_str) + + if res[type_idx + 10] >= self.type_threshold: + type_res_str += self.type_list[type_idx] + else: + type_res_str += "Unknown" + attr_res.append(type_res_str) + + batch_res.append(attr_res) + result = {'output': batch_res} + return result +``` diff --git a/docs/advanced_tutorials/customization/ppvehicle_attribute_en.md b/docs/advanced_tutorials/customization/ppvehicle_attribute_en.md new file mode 100644 index 0000000000000000000000000000000000000000..69fbc18fbf55081311978008d2b82c50f6f2634a --- /dev/null +++ b/docs/advanced_tutorials/customization/ppvehicle_attribute_en.md @@ -0,0 +1,271 @@ +[简体中文](ppvehicle_attribute.md) | English + +# Customized Vehicle Attribute Recognition + +## Data Preparation + +### Data Format + +We use the VeRi attribute annotation format, with a total of 10 color and 9 model attributes shown as follows. + +``` +# colors +- "yellow" +- "orange" +- "green" +- "gray" +- "red" +- "blue" +- "white" +- "golden" +- "brown" +- "black" + +# models +- "sedan" +- "suv" +- "van" +- "hatchback" +- "mpv" +- "pickup" +- "bus" +- "truck" +- "estate" +``` + +A sequence of length 19 is used in the annotation file to represent the above attributes. + +Examples: + +[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0] + +In the first 10 bits, the value of bit index 0 is 1, indicating that the vehicle color is `"yellow"`. + +In the last 9 bits, the value of bit index 11 is 1, indicating that the model is `"suv"`. + + +### Data Annotation + +After knowing the purpose of the above `Data format`, we can start to annotate data. The essence is that each single-vehicle image creates a set of 19 annotation items, corresponding to the attribute values at 19 positions. + +Examples: + +For an original image: + +1) Using bounding boxes to annotate the position of each vehicle in the picture. + +2) Each detection box (corresponding to each vehicle) contains 19 attribute values which are represented by 0 or 1. It corresponds to the above 19 attributes. For example, if the color is 'orange', then the index 1 bit of the array is 1. If the model is 'sedan', then the index 10 bit of the array is 1. + +After the annotation is completed, the model will use the detection box to intercept each vehicle into a single-vehicle picture, and its picture establishes a corresponding relationship with the 19 attribute annotation. It is also possible to cut into a single-vehicle image first and then annotate it. The results are the same. + + + +## Model Training + +Once the data is annotated, it can be used for model training to complete the optimization of the customized model. + +There are two main steps: 1) Organize the data and annotated data into the training format. 2) Modify the configuration file to start training. + +### Training Data Format + +The training data includes the images used for training and a training list called train.txt. Its location is specified in the training configuration, with the following example: + +``` +Attribute/ +|-- data Training images folder +|-- 00001.jpg +|-- 00002.jpg +| `-- 0000x.jpg +train.txt List of training data +``` + +train.txt file contains the names of all training images (file path relative to the root path) + 19 annotation values + +Each line of it represents a vehicle's image and annotation result. The format is as follows: + +``` +00001.jpg 0,0,1,0,.... +``` + +Note 1) The images are separated by Tab[\t], 2) The annotated values are separated by commas [,]. If the format is wrong, the parsing will fail. + + +### Modify The Configuration To Start Training + +First run the following command to download the training code (for more environmental issues, please refer to [Install_PaddleClas](https://github.com/PaddlePaddle/PaddleClas/blob/release/2.4/docs/en/installation/ install_paddleclas_en.md)): + +``` +git clone https://github.com/PaddlePaddle/PaddleClas +``` + +You need to modify the following configuration in the configuration file `PaddleClas/blob/develop/ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml` + +```yaml +DataLoader: + Train: + dataset: + name: MultiLabelDataset + image_root: "dataset/VeRi/" # the root path of training images + cls_label_path: "dataset/VeRi/train_list.txt" # the location of the training list file + label_ratio: True + transform_ops: + ... + + Eval: + dataset: + name: MultiLabelDataset + image_root: "dataset/VeRi/" # the root path of evaluation images + cls_label_path: "dataset/VeRi/val_list.txt" # the location of the training list file + label_ratio: True + transform_ops: + ... +``` + +Note: + +1. here image_root path and the relative path of the image in train.txt, corresponding to the full path of the image. +2. If you modify the number of attributes, the number of attribute types in the content configuration item should also be modified accordingly. + +```yaml +# model architecture +Arch: +name: "PPLCNet_x1_0" +pretrained: True +use_ssld: True +class_num: 19 # Number of attribute classes +``` + +Then run the following command to start training: + +```bash +#Multi-card training +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch \ + --gpus="0,1,2,3" \ + tools/train.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml + +#Single card training +python3 tools/train.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml +``` + +You can run the following commands for performance evaluation after the training is completed: + +``` +#Multi-card evaluation +export CUDA_VISIBLE_DEVICES=0,1,2,3 +python3 -m paddle.distributed.launch \ + --gpus="0,1,2,3" \ + tools/eval.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml \ + -o Global.pretrained_model=./output/PPLCNet_x1_0/best_model + +#Single card evaluation +python3 tools/eval.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml \ + -o Global.pretrained_model=./output/PPLCNet_x1_0/best_model +``` + +### Model Export + +Use the following command to export the trained model as an inference deployment model. + +``` +python3 tools/export_model.py \ + -c ./ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml \ + -o Global.pretrained_model=output/PPLCNet_x1_0/best_model \ + -o Global.save_inference_dir=deploy/models/PPLCNet_x1_0_vehicle_attribute_model +``` + +After exporting the model, if want to use it in PP-Vehicle, you need to download the [deploy infer model](https://bj.bcebos.com/v1/paddledet/models/pipeline/vehicle_attribute_model.zip) and copy `infer_cfg.yml` into the exported model folder `PPLCNet_x1_0_vehicle_attribute_model` . + +When you use the model, you need to modify the new model path `model_dir` entry and set `enable: True` in the configuration file of PP-Vehicle `. /deploy/pipeline/config/infer_cfg_ppvehicle.yml` . + +``` +VEHICLE_ATTR: + model_dir: [YOUR_DEPLOY_MODEL_DIR]/PPLCNet_x1_0_vehicle_attribute_infer/ #The exported model location + enable: True #Whether to enable the function +``` + +To this point, a new attribute category recognition task is completed. + + + +## Adding or deleting attributes + +This is similar to the increase and decrease process of pedestrian attributes. + +If the attributes need to be added or deleted, you need to + +1) New attribute category information needs to be added or deleted when annotating the data. + +2) Modify the number and name of attributes used in train.txt corresponding to the training. + +3) Modify the training configuration, for example, the number of attributes in the ``PaddleClas/blob/develop/ppcls/configs/PULC/vehicle_attribute/PPLCNet_x1_0.yaml`` file, for details, please see the ``Modify configuration to start training`` section above. + +Example of adding attributes. + +1. Continue to add new attribute annotation values after 19 values when annotating the data. +2. Add new attribute values to the annotated values in the train.txt file as well. +3. The above is the annotation and training process with 19 attributes. + +
+ +
+ + +The same applies to the deletion of attributes. + + +## Modifications to post-processing code + +After modifying the attribute definition, the post-processing part of the pipeline also needs to be modified accordingly, which mainly affects the display results when the results are visualized. + + +The code is at [file](https://github.com/PaddlePaddle/PaddleDetection/blob/develop/deploy/pipeline/ppvehicle/vehicle_attr.py#L108), that is, the `postprocess` function. + +The function implementation is described as follows: + +```python + # The name of the color/model is defined in the initialization function of the class + self.color_list = [ + "yellow", "orange", "green", "gray", "red", "blue", "white", + "golden", "brown", "black" + ] + self.type_list = [ + "sedan", "suv", "van", "hatchback", "mpv", "pickup", "bus", "truck", + "estate" + ] + + ... + + def postprocess(self, inputs, result): + # postprocess output of predictor + im_results = result['output'] + batch_res = [] + for res in im_results: + res = res.tolist() + attr_res = [] + color_res_str = "Color: " + type_res_str = "Type: " + color_idx = np.argmax(res[:10]) # The first 10 items represent the color scores, and the item with the largest score is used as the color result + type_idx = np.argmax(res[10:]) # The last 9 items represent the model scores, and the item with the largest score is used as the model result. + + # The score of color and model need to be larger than the corresponding threshold, otherwise it will be regarded as 'UnKnown' + if res[color_idx] >= self.color_threshold: + color_res_str += self.color_list[color_idx] + else: + color_res_str += "Unknown" + attr_res.append(color_res_str) + + if res[type_idx + 10] >= self.type_threshold: + type_res_str += self.type_list[type_idx] + else: + type_res_str += "Unknown" + attr_res.append(type_res_str) + + batch_res.append(attr_res) + result = {'output': batch_res} + return result +```