【picodet 训练流程】

picodet训练流程

  • 一、Train
    • 1. 环境搭建
    • 2. 准备数据
      • 2.1 数据位置
      • 2.2 数据读取和标签读取
        • 2.2.1yml 文件位置
        • 2.2.2数据集路径文件生成
      • 3. 修改模型相应参数
        • 3.1 参数文件位置
    • 4. 训练
  • 二、Eval
    • 1.评估时,只需输入以下命令,即可得到该模型在eval_list中的评估结果:
  • 三、Infer
  • 四、Export
  • 五、Export2onnx


一、Train

1. 环境搭建

安装其他依赖

cd PaddleDetection                
pip install -r requirements.txt  

编译安装paddledet

python setup.py install     

2. 准备数据

2.1 数据位置

picodet/data/ 

2.2 数据读取和标签读取

2.2.1yml 文件位置

picodet/data/ 

2.2.2数据集路径文件生成

"""
   生成训练集和测试集txt文本
   可随机选取
"""

import os
import random
import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-d', '--dataset', type=str, required=True, help='dataset relative path')
parser.add_argument('-t', '--txt', type=str, required=True, help='txt relative path')
parser.add_argument('-r', '--ratio', type=float, default=1.0, help='Percentage of training sets 0<=ratio<=1')
args = parser.parse_args()


def create_txt(data_path, train_path, eval_path, ratio):
    path_list = list()
    i = 0
    for home, dirs, files in os.walk(data_path):
        for filename in files:
            if filename.split('.')[-1] == 'jpg':
                path_jpg = os.path.join(home, filename)
                path_xml1 = os.path.join(home, 'outputs/' + filename.split('.')[0] + '.xml')
                path_xml2 = os.path.join(home, filename.split('.')[0] + '.xml')
                if os.path.exists(path_xml1):
                    i = i + 1
                    path_list.append((path_jpg, path_xml1))
                elif os.path.exists(path_xml2):
                    i = i + 1
                    path_list.append((path_jpg, path_xml2))
                else:
                    print("no such file:" + path_jpg + "   xml.")
    seed = 1
    random.seed(seed)
    # random.shuffle(path_list)
    f_train = open(train_path, 'w')
    f_eval = open(eval_path, 'w')
    for e, content in enumerate(path_list):
        img, xml = content
        text = img + ' ' + xml + '\n'
        if e < len(path_list) * ratio:
            f_train.write(text)
        else:
            f_eval.write(text)
    f_train.close()
    f_eval.close()
    print("Total has " + str(i) + " images.")
    print("over")


data_path = "/home/sq/Desktop/picodet/data/" + args.dataset
train_path = "/home/sq/Desktop/picodet/PaddleDetection-release-2.4/dataset/" + args.txt + "/train_list.txt"
eval_path = "/home/sq/Desktop/picodet/PaddleDetection-release-2.4/dataset/" + args.txt + "eval_list.txt"

if args.ratio < 0 or args.ratio > 1:
    print("Please enter ratio greater than 0 but less than 1")
else:
    create_txt(data_path, train_path, eval_path, args.ratio)

调用方法

python get_txt.py -d fish -t s416_7/s416_7_220922 -r 1.0  

生成文件 train_list.txt

/home/sq/Desktop/picodet/data/20220623/ahd_3_20210508_183507990/0732.jpg /home/sq/Desktop/picodet/data/20220623/ahd_3_20210508_183507990/outputs/0732.xml
/home/sq/Desktop/picodet/data/20220623/ahd_3_20210508_180102968/1020.jpg /home/sq/Desktop/picodet/data/20220623/ahd_3_20210508_180102968/outputs/1020.xml
/home/sq/Desktop/picodet/data/20220623/ahd_5_20210508_210941744/1016.jpg /home/sq/Desktop/picodet/data/20220623/ahd_5_20210508_210941744/outputs/1016.xml
 picodet/PaddleDetection-release-2.4/dataset/s_416/
 lable_list.txt
car
bus
pedestrian
tricycle
truck
special_vehicle
rider

3. 修改模型相应参数

3.1 参数文件位置

picodet/PaddleDetection-release-2.4/configs/datasets/s416_7/
s416_7_220922.yml

s416_7_220922.yml 修改内容

metric: VOC
map_type: 11point
num_classes: 7    #修改类别数

TrainDataset:
  !VOCDataSet
    dataset_dir: /home/sq/Desktop/picodet/PaddleDetection-release-2.4/dataset/s416_7/s416_7_220922   #修改数据路径
    anno_path: train_list.txt    
    label_list: label_list.txt
    data_fields: ['image', 'gt_bbox', 'gt_class', 'difficult']

EvalDataset:
  !VOCDataSet
    dataset_dir: /home/sq/Desktop/picodet/PaddleDetection-release-2.4/dataset/s416_7/s416_7_220922#修改数据路径
    anno_path: eval_list.txt
    label_list: label_list.txt
    data_fields: ['image', 'gt_bbox', 'gt_class', 'difficult']

TestDataset:
  !ImageFolder
    anno_path: /home/sq/Desktop/picodet/PaddleDetection-release-2.4/dataset/s416_7/s416_7_220922/label_list.txt
picodet/PaddleDetetion-release-2.4/configs/picodet

- picodet_s_416_coco_lcnet.yml
_BASE_: [
  '../datasets/s416_7/s416_7_220922.yml#修改数据路径',  
  '../runtime.yml',
  '_base_/picodet_v2.yml',
  '_base_/optimizer_300e.yml',
  '_base_/picodet_416_reader.yml',
]

pretrain_weights:
weights:
find_unused_parameters: True
use_ema: true
epoch: 301  #修改训练轮数
snapshot_epoch: 10 #修改多少轮保存一次参数

LCNet:
  scale: 0.75
  feature_maps: [3, 4, 5]

LCPAN:
  out_channels: 96

PicoHeadV2:
  conv_feat:
    name: PicoFeat
    feat_in: 96
    feat_out: 96
    num_convs: 2
    num_fpn_stride: 4
    norm_type: bn
    share_cls_reg: True
    use_se: True
  feat_in_chan: 96

TrainReader:
  batch_size: 16  #修改

LearningRate:
  base_lr: 0.05
  schedulers:
  - !CosineDecay
    max_epochs: 300
  - !LinearWarmup
    start_factor: 0.1
    steps: 300
picodet/PaddleDetection-release-2.4/configs/
runtime.yml 
use_gpu: true
use_xpu: false
log_iter: 100
save_dir: s416_7/s416_7_220922 #修改保存路径
snapshot_epoch: 10
print_flops: false

# Exporting the model
export:
  post_process: False  # Whether post-processing is included in the network when export model.
  nms: False           # Whether NMS is included in the network when export model.
  benchmark: True    # It is used to testing model performance, if set `True`, post-process and NMS will not be exported.
picodet/PaddleDetetion-release-2.4/configs/picodet/_base_/
- optimizer_300e.yml 
epoch: 300 #修改epoch

LearningRate:
  base_lr: 0.05
  schedulers:
  - !CosineDecay
    max_epochs: 300 #修改
  - !LinearWarmup
    start_factor: 0.1
    steps: 300

OptimizerBuilder:
  optimizer:
    momentum: 0.9
    type: Momentum
  regularizer:
    factor: 0.00004
    type: L2
picodet/PaddleDetetion-release-2.4/configs/picodet/_base_/
- Picodet_416_reader.yml 
worker_num: 6
eval_height: &eval_height 416
eval_width: &eval_width 416
eval_size: &eval_size [*eval_height, *eval_width]

TrainReader:
  sample_transforms:
  - Decode: {}
  - RandomCrop: {}
  - RandomFlip: {prob: 0.5}
  - RandomDistort: {}
  batch_transforms:
  - BatchRandomResize: {target_size: [352, 384, 416, 448, 480], random_size: True, random_interp: True, keep_ratio: False}
  - NormalizeImage: {is_scale: true, mean: [0.485,0.456,0.406], std: [0.229, 0.224,0.225]}
  - Permute: {}
  - PadGT: {}
  batch_size: 16 #修改
  shuffle: true
  drop_last: true


EvalReader:
  sample_transforms:
  - Decode: {}
  - Resize: {interp: 2, target_size: *eval_size, keep_ratio: False}
  - NormalizeImage: {is_scale: true, mean: [0.485,0.456,0.406], std: [0.229, 0.224,0.225]}
  - Permute: {}
  batch_transforms:
  - PadBatch: {pad_to_stride: 32}
  batch_size: 8 #修改
  shuffle: false


TestReader:
  inputs_def:
    image_shape: [1, 3, *eval_height, *eval_width]
  sample_transforms:
  - Decode: {}
  - Resize: {interp: 2, target_size: *eval_size, keep_ratio: False}
  - NormalizeImage: {is_scale: true, mean: [0.485,0.456,0.406], std: [0.229, 0.224,0.225]}
  - Permute: {}
  batch_size: 1

以s-416模型为例,只需修改epoch和snapshot_epoch参数,epoch表示训练轮数,snapshot_epoch表示每经过多少轮验证一次结果并保存此时的权重文件。
修改训练轮数时需要在optimizer_300e.yml中也修改epoch和max_epochs参数,若需要修改输出路径,进入runtime.yml中在对应的位置修改即可。

其中:
s416_7_220922.yml 主要说明了训练数据和验证数据的路径。
runtime.yml 主要说明了公共的运行参数,比如说是否使用GPU、每多少个epoch存储checkpoint等。
optimizer_300e.yml 主要说明了学习率和优化器的配置。
Picodet_v2.yml 主要说明模型、和主干网络的情况。
Picodet_416_reader.yml 主要说明数据读取器配置,如batch size,并发加载子进程数等,同时包含读取后预处理操作,如resize、数据增强等等。

4. 训练

在终端中输入下面的命令,即可开始训练:
单卡训练

# training on single-GPU
export CUDA_VISIBLE_DEVICES=0
python tools/train.py -c configs/picodet/picodet_s_320_coco_lcnet.yml --eval

多卡训练

# training on multi-GPU
export CUDA_VISIBLE_DEVICES=0,1,2,3
python -m paddle.distributed.launch --gpus 0,1,2,3 tools/train.py -c configs/picodet/picodet_s_320_coco_lcnet.yml --eval

若要边训练边评估,只需在最后加入–eval

python tools/train.py -c configs/picodet/picodet_s_320_coco_lcnet.yml--eval

若中途意外停止,可以从已保存的最后一次的权重(例如100)进行恢复训练:

python tools/train.py -c configs/picodet/picodet_s_320_coco_lcnet.yml \
	-r output/picodet_s_320_coco_lcnet/100   

二、Eval

1.评估时,只需输入以下命令,即可得到该模型在eval_list中的评估结果:

python tools/eval.py -c configs/ picodet/picodet_s_320_coco_lcnet.yml \ 
	-o weights=output/picodet_s_320_coco_lcnet/best_model.params  

三、Infer

python tools/infer.py -c configs/picodet/picodet_s_320_coco_lcnet.yml \  
                        --infer_img=demo/图片名称.png \                            
                        --output_dir=infer_output/ \                               
                        --draw_threshold=0.5 \                                     
                        -o weights=output/picodet_s_320_coco_lcnet/best_model \ 
                        --use_vdl=True      

其中–draw_threshold 是个可选参数. 根据 NMS 的计算,不同阈值会产生不同的结果 keep_top_k表示设置输出目标的最大数量,默认值为100,用户可以根据自己的实际情况进行设定。

四、Export

在模型训练过程中保存的模型文件是包含前向预测和反向传播的过程,在实际的工业部署则不需要反向传播,因此需要将模型进行导成部署需要的模型格式。 在PaddleDetection中提供了 tools/export_model.py脚本来导出模型。

python tools/export_model.py -c configs/picodet/picodet_s_320_coco_lcnet.yml \
	--output_dir=./inference_model \                                                   
	- o weights=output/picodet_s_320_coco_lcnet/best_model     

预测模型会导出到inference_model/ picodet_s_320_coco_lcnet目录下,分别为infer_cfg.yml, model.pdiparams, model.pdiparams.info,model.pdmodel

五、Export2onnx

首先安装Paddle2ONNX(高于或等于0.6版本):

pip install paddle2onnx

再使用下面的命令进行转换:

paddle2onnx --model_dir inference_model/ picodet_s_320_coco_lcnet \
                  --model_filename model.pdmodel \
                 --params_filename model.pdiparams \
                 --opset_version 11 \
                 --save_file picodet-s-320.onnx

再使用onnxsim对其进行简化:

 python -m onnxsim  picodet-s-320.onnx picodet-s-320-sim.onnx

你可能感兴趣的:(picodet,训练及部署,python,深度学习,人工智能)