文章目录

  • 前言
  • 1、必要环境
  • 2、安装
  • 2.1、创建python3.7虚拟环境
  • 2.2、 安装PaddlePaddle2.1
  • 2.3、安装PaddleDetection
  • 2.4、测试是否安装成功
  • 3、测试
  • 3.1、测试图片效果
  • 3.2、测试视频效果
  • 4、准备数据集
  • 4.1准备自己的VOC数据集
  • 4.2将数据集划分为训练集和测试集
  • 5、训练自己的数据集



前言

利用windows10系统搭建PaddleDetection2.0环境,并制作自己的VOC数据集,利用PPYOLOv2进行训练及测试


1、必要环境

本文使用 python3.7、cuda10.1、cudnn7.6.5

2、安装

2.1、创建python3.7虚拟环境

  1. conda create -n paddle3.7 python=3.7
  2. activate paddle3.7

2.2、 安装PaddlePaddle2.1

gpu版本:

  • python -m pip install paddlepaddle-gpu==2.1.0.post101 -f https://paddlepaddle.org.cn/whl/mkl/stable.html

cpu版本:

  • python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddle


测试是否安装成功

python
import paddle.fluid as fluid
fluid.install_check.run_check()

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddlepaddle_02


出现如上界面则证明安装成功,如果报错请先执行nvcc -V查看cuda版本是否与paddlepaddle对应

想使用旧版本的话可以自行去官网安装
地址:飞桨官网

2.3、安装PaddleDetection

  1. 进入github官网PaddlePaddle/PaddleDetection下载release2.1分支到本地
  2. 执行pip install pycocotools,pip install cython
  3. cd到PaddleDetection-release-2.1文件夹内执行pip install -r requirements.txt
  4. 执行 python setup.py install

    如出现如上界面则证明下载成功

2.4、测试是否安装成功

python ppdet/modeling/tests/test_architectures.py

出现如下界面则证明下载成功

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_数据集_03


路径报错的话进入test_architectures.py 将所有相对路径改为绝对路径

3、测试

3.1、测试图片效果

  1. 去官网下载模型权重,本文采用ppyolov2_r50vd权重,下载地址:ResNet50vd
  2. 执行如下命令测试图片效果 weights=后面换成自己的权重路径
python tools/infer.py -c configs/ppyolo/ppyolov2_r50vd_dcn_365e_coco.yml -o use_gpu=true weights=C:\Users\35415\.cache\paddle\weights\ppyolov2_r50vd_dcn_365e_coco.pdparams --infer_img=demo/000000014439_640x640.jpg

效果图

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddle_04

3.2、测试视频效果

  1. 导出预测模型
python tools/export_model.py -c configs/ppyolo/ppyolov2_r50vd_dcn_voc.yml -o weights=C:\Users\35415\.cache\paddle\weights\ppyolov2_r50vd_dcn_365e_coco.pdparams

导出模型后,会在output_inference路径下生成如下文件

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_数据集_05


执行如下代码,测试视频效果

python deploy/python/infer.py --video_file=demo/forest4.avi --model_dir=output_inference\ppyolov2_r50vd_dcn_voc --use_gpu=True  --thresh=0.1

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddlepaddle_06


ps :之前测试视频的时候源码是有bug的,作为小白,我和朋友调试了一下午…正准备放弃的时候去官网上瞅了一下,发现作者于3小时前更新了代码…

4、准备数据集

4.1准备自己的VOC数据集

voc数据集格式
   ├── VOCdevkit
   │   ├── VOC2007
   │   │   ├── Annotations  #存放所有xml文件
   │   │   ├── JPEGImages   #存放所有图片
   │   │   ├── ImageSets
   │   │   │   ├── Main
   │   │   │   │   ├── test.txt
   │   │   │   │   ├── trainval.txt
   │   │   │   │   ├── train.txt
   │   │   │   │   ├── val.txt

4.2将数据集划分为训练集和测试集

1.进入VOC2007文件夹内,运行create_txt.py将会在Main文件夹内生成trainval.txt、train.txt、val.txt、test.txt四个txt文件。

create_txt.py

import os
import random
#需要根据自己的目录进行修改
trainval_percent = 0.95  # 训练集验证集总占比
train_percent = 0.9  # 训练集在trainval_percent里的train占比
xmlfilepath = r'Annotations'
txtsavepath = r'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'ImageSets\Main\trainval.txt', 'w')
ftest = open(r'ImageSets\Main\test.txt', 'w')
ftrain = open(r'ImageSets\Main\train.txt', 'w')
fval = open(r'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()

2.在VOC2007文件夹内继续运行txt_write.py,生成包含jpg和xml信息的txt文件

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)

如果写入的txt文件为空,请仔细检查路径是否有问题

3.创建label_list

新建一个txt文件,命名为label_list,里面存放类别名称

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddlepaddle_07

5、训练自己的数据集

\PaddleDetection-release-2.1目录下创建changeppyolov2.py,用于更新anchor

changeppyolov2.py

import numpy as np
import pickle
num_class =2
with open(r'C:\Users\35415\.cache\paddle\weights\ppyolov2_r50vd_dcn_365e_coco.pdparams','rb') as f:
    obj = f.read()
weights = pickle. loads(obj, encoding= 'latin1')

weights['yolo_head.yolo_output.0.weight']=np.zeros([num_class*3+18,1024,1,1],dtype= 'float32')
weights[ 'yolo_head.yolo_output.0.bias' ]=np.zeros( [ num_class*3+18],dtype='float32')
weights['yolo_head.yolo_output.1.weight']=np.zeros([num_class*3+18,512,1,1],dtype='float32')
weights[ 'yolo_head.yolo_output.1.bias ' ]=np. zeros( [ num_class*3+18],dtype='float32')
weights['yolo_head.yolo_output.2.weight']=np.zeros([num_class*3+18,256,1,1],dtype='float32')
weights[ 'yolo_head.yolo_output.2.bias ' ]=np.zeros( [ num_class*3+18],dtype= 'float32')

f = open('model_final.pdparams','wb')
pickle.dump(weights,f)
f.close()
  1. 选择模型 本文使用的是(ppyolov2_r50vd_dcn_voc.yml)
  2. 修改configs\ppyolo\ppyolov2_r50vd_dcn_voc.yml内的参数snapshot_epoch(训练几次保存一次)本文这里写的是1
  3. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_数据集_08

  4. 修改 configs\datasets\voc.yml 内 num_classes (分类数) 有几个类别这里就写多少
  5. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddle_09

  6. 修改configs\datasets\voc.yml中的存放数据集的路径
  7. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_深度学习_10


  8. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_python_11

  9. 修改configs\ppyolo\_base_\optimizer_365e.yml 内的 epoch(训练次数) base_lr(学习率)=0.01/8*GPU_num
  10. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddle_12

  11. 可以修改 configs\ppyolo\_base_\ppyolov2_reader.ymll 内的 batck_size和worker_num,worker_num本文改为0
  12. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_数据集_13

  13. 修改 changeppyolov2.py 内的 num_classes,改为自己的类别数
  14. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddle_14

  15. 运行 changeppyolov2.py 更新权重文件中的类别 获取新权重文件
  16. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddle_15

  17. 修改 configs\ppyolo\_base_\ppyolov2_r50vd_dcn.yml 内的pretrain_weights指向刚更新的权重文件
  18. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_深度学习_16

  19. 运行如下代码获取anchor:
python tools/anchor_cluster.py -c configs/ppyolo/ppyolov2_r50vd_dcn_voc.yml -n 9 -s 640 -m v2 -i 1000

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddle_17

  1. 把anchor复制到configs\ppyolo\_base_\ppyolov2_r50vd_dcn.ymlconfigs\ppyolo_base_\ppyolov2_reader.yml
  2. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_深度学习_18


  3. PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_数据集_19

  4. 以上内容根据自己的输出结果着实修改
  5. 开始训练:
python tools/train.py -c configs/ppyolo/ppyolov2_r50vd_dcn_voc.yml

此时可能会报如下内存溢出的错误

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_python_20


此时我们需要进入configs\ppyolo\ppyolov2_r50vd_dcn_voc.yml 将batch_size修改为1,然后重新训练

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_python_21


PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_paddle_22

  1. 测试代码如下
python tools/infer.py -c configs/ppyolo/ppyolov2_r50vd_dcn_voc.yml -o use_gpu=True weights=D:\dmdm\Paddle
Detection-release-2.1\output\ppyolov2_r50vd_dcn_voc\48.pdparams --infer_img=demo/fire.jpg

如果想在某一批次下继续训练模型可在路径后面加上 -r checkpoint_path

python tools/train.py -c configs/ppyolo/ppyolov2_r50vd_dcn_voc.yml  -r output/ppyolov2_r50vd_dcn_voc/146.pdparams

效果图

PaddlePaddle 版本是否支持 paddlespeech 兼容问题 paddledetection2.0_深度学习_23

好啦,大功告成!

可选参数列表:https://github.com/PaddlePaddle/PaddleDetection/blob/release/0.2/docs/tutorials/GETTING_STARTED_cn.md#%E5%8F%AF%E9%80%89%E5%8F%82%E6%95%B0%E5%88%97%E8%A1%A8

如有问题,欢迎评论区交流!!