paddleDetection目标检测(准备数据,选择模型,训练模型,评估,预测,模型压缩和模型部署)

参考链接:
https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.0-rc/docs/tutorials/DetectionPipeline.md

文教程以路标数据集为例,使用yoloV3算法详细说明paddleDetection全流程使用教程,包含:准备数据,选择模型,训练模型,评估,预测,模型压缩和模型部署。

数据准备
关于数据准备的请参考:

注意:
(1)数据集中路径名、文件名不要包含空格,尽量不要使用中文
(2)用户数据,建议在训练前仔细检查 数据,避免因数据标注格式错误或图像数据不完整造成训练过程中的中断
(2)如果图像尺寸太大的话,在不限制读入数据尺寸情况下,占用内存较多,会造成内存/显存溢出,请合理设置batch_size,可从小到大尝试

用户数据转换示例
第一种方法
第一步:按照下面的形式,组织自己的数据

├── annotations
│   ├── road0.xml
│   ├── road1.xml
│   ├── road10.xml
│   |   ...
├── images
│   ├── road0.jpg
│   ├── road1.jpg
│   ├── road2.jpg
│   |   ...

第二步,将数据划分为训练集和测试集

# 生成 label_list.txt 文件
>>echo "speedlimit\ncrosswalk\ntrafficlight\nstop" > label_list.txt

# 生成 train.txt、valid.txt和test.txt列表文件
>>ls images/*.png | shuf > all_image_list.txt
>>awk -F"/" '{print $2}' all_image_list.txt | awk -F".png" '{print $1}'  | awk -F"\t" '{print "images/"$1".png annotations/"$1".xml"}' > all_list.txt

# 训练集、验证集、测试集比例分别约80%、10%、10%。
>>head -n 88 all_list.txt > test.txt
>>head -n 176 all_list.txt | tail -n 88 > valid.txt
>>tail -n 701 all_list.txt > train.txt

# 删除不用文件
>>rm -rf all_image_list.txt all_list.txt



最终数据集文件组织结构为:

├── annotations
│   ├── road0.xml
│   ├── road1.xml
│   ├── road10.xml
│   |   ...
├── images
│   ├── road0.jpg
│   ├── road1.jpg
│   ├── road2.jpg
│   |   ...
├── label_list.txt
├── test.txt
├── train.txt
└── valid.txt

# label_list.txt 是类别名称列表,文件名必须是 label_list.txt
>>cat label_list.txt
crosswalk
speedlimit
stop
trafficlight

# train.txt 是训练数据集文件列表,每一行是一张图像路径和对应标注文件路径,以空格分开。注意这里的路径是数据集文件夹内的相对路径。
>>cat train.txt
./images/road839.png ./annotations/road839.xml
./images/road363.png ./annotations/road363.xml
...

# valid.txt 是验证数据集文件列表,每一行是一张图像路径和对应标注文件路径,以空格分开。注意这里的路径是数据集文件夹内的相对路径。
>>cat valid.txt
./images/road218.png ./annotations/road218.xml
./images/road681.png ./annotations/road681.xml

第二种方法
VOC数据集格式
文件夹目录如下:

---VOC
    ------creat_txt.py
    ------txt_write.py
    ------Annotations
         ---------n个xml文件
    ------ImagesSet
         ---------Main
              --------trainval.txt
              --------train.txt
              --------test.txt
              --------val.txt
    ------JPEGImages
         ---------n个img文件

生成VOC数据集的txt文件
分别将这两个python文件放在voc文件夹下。

生成Main文件夹下的txt文件
运行creat_txt.py将会生成Main文件夹下的trainval.txt、train.txt、val.txt、test.txt四个txt文件。

creat_txt.py

import os
import random
#需要根据自己的目录进行修改
trainval_percent = 0.95  # 训练集验证集总占比
train_percent = 0.9  # 训练集在trainval_percent里的train占比
xmlfilepath = r'VOC2007\Annotations'
txtsavepath = r'\VOC2007\ImageSets/Main'
total_xml = os.listdir(xmlfilepath)

num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)

ftrainval = open(r'/VOC2007\ImageSets\Main\trainval.txt', 'w')
ftest = open(r'VOC2007\ImageSets\Main\test.txt', 'w')
ftrain = open(r'VOC2007\ImageSets\Main\train.txt', 'w')
fval = open(r'VOC2007\ImageSets\Main\val.txt', 'w')

for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftrain.write(name)
        else:
            fval.write(name)
    else:
        ftest.write(name)

ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

生成包含jpg和xml信息的txt文件
运行txt_write.py根据在Main文件夹中划分好的数据集进行位置索引,生成含有图像及对应的XML文件的地址信息的文件。
txt_write.py(不需要修改路径)

import os
import re
import random

devkit_dir = './'
output_dir = './'

def get_dir(devkit_dir,  type):
    return os.path.join(devkit_dir, type)

def walk_dir(devkit_dir):
    filelist_dir = get_dir(devkit_dir, 'ImageSets/Main')
    annotation_dir = get_dir(devkit_dir, 'Annotations')
    img_dir = get_dir(devkit_dir, 'JPEGImages')
    trainval_list = []
    train_list = []
    val_list = []
    test_list = []

    added = set()

    for _, _, files in os.walk(filelist_dir):
        for fname in files:
            print(fname)
            img_ann_list = []
            if re.match('trainval.txt', fname):
                img_ann_list = trainval_list
            elif re.match('train.txt', fname):
                img_ann_list = train_list
            elif re.match('val.txt', fname):
                img_ann_list = val_list
            elif re.match('test.txt', fname):
                img_ann_list = test_list
            else:
                continue
            fpath = os.path.join(filelist_dir, fname)
            for line in open(fpath):
                name_prefix = line.strip().split()[0]
                print(name_prefix)

                added.add(name_prefix)
                #ann_path = os.path.join(annotation_dir, name_prefix + '.xml')
                ann_path = annotation_dir + '/' + name_prefix + '.xml'
                print(ann_path)
                #img_path = os.path.join(img_dir, name_prefix + '.jpg')
                img_path = img_dir + '/' + name_prefix + '.jpg'
                assert os.path.isfile(ann_path), 'file %s not found.' % ann_path
                assert os.path.isfile(img_path), 'file %s not found.' % img_path
                img_ann_list.append((img_path, ann_path))
            print(img_ann_list)

    return trainval_list, train_list, val_list, test_list


def prepare_filelist(devkit_dir, output_dir):
    trainval_list = []
    train_list = []
    val_list = []
    test_list = []

    trainval, train, val, test = walk_dir(devkit_dir)

    trainval_list.extend(trainval)
    train_list.extend(train)
    val_list.extend(val)
    test_list.extend(test)
    #print(trainval)
    with open(os.path.join(output_dir, 'trainval.txt'), 'w') as ftrainval:
        for item in trainval_list:
            ftrainval.write(item[0] + ' ' + item[1] + '\n')

    with open(os.path.join(output_dir, 'train.txt'), 'w') as ftrain:
        for item in train_list:
            ftrain.write(item[0] + ' ' + item[1] + '\n')

    with open(os.path.join(output_dir, 'val.txt'), 'w') as fval:
        for item in val_list:
            fval.write(item[0] + ' ' + item[1] + '\n')

    with open(os.path.join(output_dir, 'test.txt'), 'w') as ftest:
        for item in test_list:
            ftest.write(item[0] + ' ' + item[1] + '\n')


if __name__ == '__main__':
    prepare_filelist(devkit_dir, output_dir)

创建label_list
图片说明

修改预训练模型的Configs配置
在paddleDetection文件夹中操作。

修改num_classes
修改所用模型ssd_mobilenet_v1_voc.yml配置文件,在PaddleDetection-release-0.2\configs\ssd路径下找到配置文件,修改为自己数据集的的num_classes:
num_classes = (label_class) + 1(background)

图片说明

修改pascalvoc_label
修改voc.py运行文件,在PaddleDetection-release-0.2\ppdet\data\source路径下找到配置文件,修改
修改为自己模型的label:
图片说明

模型选择
PaddleDetection中提供了丰富的模型库,具体可在模型库中查看各个模型的指标,您可依据实际部署算力的情况,选择合适的模型。

本教程选用YOLOv3作为训练模型。

训练和模型评估
请参考此链接:

模型训练和预测

推理部署
在模型部署之前,如果您需要对模型进行压缩,PaddleDetection提供了基于PaddleSlim 进行模型压缩的完整教程和实验结果,详细请参考:量化、剪枝、蒸馏、搜索 。
详细部署文档请参考PaddleDetection预测部署文档。这里以PaddleServing部署方式为例说明。

安装paddle-serving-client和paddle-serving-server

# 安装 paddle-serving-client
pip install paddle-serving-client -i https://mirror.baidu.com/pypi/simple

# 安装 paddle-serving-server
pip install paddle-serving-server -i https://mirror.baidu.com/pypi/simple

# 安装 paddle-serving-server-gpu
pip install paddle-serving-server-gpu -i https://mirror.baidu.com/pypi/simple

导出模型

python tools/export_serving_model.py -c configs/yolov3_mobilenet_v1_roadsign.yml -o use_gpu=true weights=output/yolov3_mobilenet_v1_roadsign/best_model --output_dir=./inference_model

以上命令会在./inference_model文件夹下生成一个yolov3_mobilenet_v1_roadsign文件夹:

inference_model
│   ├── yolov3_mobilenet_v1_roadsign
│   │   ├── infer_cfg.yml
│   │   ├── serving_client
│   │   │   ├── serving_client_conf.prototxt
│   │   │   ├── serving_client_conf.stream.prototxt
│   │   ├── serving_server
│   │   │   ├── conv1_bn_mean
│   │   │   ├── conv1_bn_offset
│   │   │   ├── conv1_bn_scale
│   │   │   ├── ...

启动PaddleServing服务

cd inference_model/yolov3_mobilenet_v1_roadsign/

# GPU
python -m paddle_serving_server_gpu.serve --model serving_server --port 9393 --gpu_ids 0

# CPU
python -m paddle_serving_server.serve --model serving_server --port 9393

注意:
遇到的一些问题:
1:/root/anaconda3/lib/python3.7/site-packages/paddle_serving_server/serving-cpu-avx-openblas-0.5.0/serving: /lib64/libstdcn `CXXABI_1.3.8' not found (required by /root/anaconda3/lib/python3.7/site-packages/paddle_serving_server/serving-cpu-av0/serving)

https://github.com/cdr/code-server/issues/347#issuecomment-482670081

2:
图片说明

测试部署的服务
准备label_list.txt文件

# 进入到导出模型文件夹
cd inference_model/yolov3_mobilenet_v1_roadsign/

# 将数据集对应的label_list.txt文件拷贝到当前文件夹下
cp ../../dataset/roadsign_voc/label_list.txt .

设置测试文件test_client.py中的prototxt文件路径为serving_client/serving_client_conf.prototxt 。
设置fetch为fetch=[“multiclass_nms_0.tmp_0”])

测试

# 进入目录
cd inference_model/yolov3_mobilenet_v1_roadsign/

测试代码 test_client.py 会自动创建output文件夹,并在output下生成bbox.jsonroad554.png两个文件

python ../../deploy/serving/test_client.py ../../demo/road554.png

————————————————
版权声明:本文为CSDN博主「老三是只猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhonglongshen/article/details/114661956
————————————————
版权声明:本文为CSDN博主「老三是只猫」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhonglongshen/article/details/114652177

全部评论

相关推荐

11-17 23:00
南昌大学 Java
我要娶个什么名:10元一天 0元提成😂
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务