从零开始配置yolov3(keras)训练测试自己的数据

参考:https://github.com/qqwweee/keras-yolo3

本文使用anaconda创建虚拟环境,达到与其它环境隔离的目的,前提是装好anaconda,如果有不清楚的,查一下其它教程

在github教程中,推荐的环境是

  • Python 3.5.2
  • Keras 2.1.5
  • tensorflow 1.6.0

除此之外,本文使用的是keras版本的yolo3,不是直接利用darknet进行训练,两者的区别后续有空研究一下

1 创建yolo环境

conda creat -n yolo python=3.6

更换conda源,下载软件的时候会快些

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
conda config --set show_channel_urls yes

创建后进入yolo环境,并安装Keras和tensorflow,我这块安装的是gpu版本的tensorflow

source activate yolo
pip install keras==2.1.5
pip install tensorflow-gpu==1.6.0  #如果是gpu版本
pip install tensorflow==1.6.0      #如果是cpu版本

2 安装依赖

在训练的过程中,会有很多依赖,所以提前安装一遍

pip install Pillow
pip install matplotlib
conda install ffmpeg
pip install opencv-contrib-python

注意opencv要安装contrib版本的,否则直接用conda install -c menpo opencv3安装后,在打开MP4文件时会报如下的错误

Unable to stop the stream: Invalid argument

3 制作数据集

首先把github上的代码克隆下来,我们在home目录下新建一个yolov3的文件夹,然后复制

mkdir yolov3
cd yolov3
git clone https://github.com/qqwweee/keras-yolo3
cd keras-yolov3

首先利用lableImg工具标注自己的图片,生成对应的xml文件,具体标注方法这里不再赘述,然后按照以下的格式创建VOC数据集

#在keras-yolo3下创建
VOCdevkit
└── VOC2007
    ├── Annotations
    ├── ImageSets
    │   ├── Layout
    │   ├── Main
    │   └── Segmentation
    ├── JPEGImages
    └── labels

其中,把刚才标注好的JPG图片放入JPEGImages文件夹中,将xml标注文件放在Annotations文件夹中

接下来要在Main中生成4个txt文件,其中test.txt是测试集,train.txt是训练集,val.txt是验证集,trainval.txt是训练和验证集。为了操作方便,我们直接在VOC2007下新建一个create_ImageSets.py的文件,内容如下

import os
import random

trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = '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)

if not os.path.exists(txtsavepath):
    print('not exist...{}'.format(txtsavepath))
    os.makedirs(txtsavepath)

ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('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:
            ftest.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)

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

接下来修改yolov3文件夹下的voc_annotation.py文件,将classes修改为自己的类别,然后运行生成yolo格式的标注文件

python voc_annotation.py

这样在主目录下生成以下三个文件

2007_test.txt
2007_train.txt
2007_val.txt

至此,训练数据准备完毕

4 修改配置文件

4.1 darknet预训练模型(不推荐)

wget https://pjreddie.com/media/files/darknet53.conv.74

下载完毕后,重命名为darknet53.weights,然后运行convert.py文件,将模型转化为keras框架的h5文件(不需要修改darknet53.cfg,采用默认值即可)

python convert.py -w darknet53.cfg darknet53.weights model_data/yolo_weights.h5

第一次运行时可能会报错

ImportError: `save_weights` requires h5py.

解决方法如下

pip install h5py

然后再运行上边的指令,运行成功后会显示生成并保存Keras weights文件到model_data/yolo_weights.h5

4.2 yolo预训练模型(推荐)

上述方法产生的是darknet的预训练模型,不清楚什么原因,训练得到的模型什么也检测不到,因此建议使用下边的这个预训练模型

wget https://pjreddie.com/media/files/yolov3.weights
python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5

4.3 修改类别文件

找到model_data/voc_classes.txt文件,将里边的类别修改为自己的类别

4.4 修改anchor文件

我们知道yolo是利用9个anchor来检测目标的位置,因此这9个anchor设置的好坏,会直接影响到训练与检测效果。

我们使用kmeans方法来聚类得到与我们数据集接近的anchors,在keras-yolov3下边有一个kmeans.py文件,打开后将filename改为2007_train.txt(2处),保存运行该脚本,会得到9个anchors的坐标值以及准确率。记下这9个坐标值,然后打开model_data中的yolo_anchors.txt,按照文本中的格式,将9个anchors值依次写入即可。

5 开始训练

首先将train.py中的annotation_path修改一下,原文是train.txt,我们改为2007_train.txt

训练时,直接运行python train.py文件即可,由于我的服务器有多块显卡,且有多人使用,因此,我再train.py文件开头增加显卡设置的代码,这样不影响别人使用

import os
# 使用第三张与第四张GPU卡
os.environ["CUDA_VISIBLE_DEVICES"] = "2, 3"

然后运行python train.py就可以开始训练了,在训练时,如果报如下的错

Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

则是因为显存不足,将train.py中的batch_size大小改小,默认是32,可改为16或8或4试试,当然可设置的越大越好

6 测试模型

训练完成时,在logs/000/文件夹下,会生成trained_weights_final.h5,我们将其拷贝出来,复制到model_data文件夹下,并重命名为yolo.h5,新建一个文件夹video,存放我们的测试视频,如test.mp4,将结果保存为result.mp4

首先将yolo.py的第25行classes_path路径改为voc_classes.txt,否则会报ValueError: Dimension 0 in both shapes must be equal, 的错误

由于编码器的原因,我们在yolo.py文件中将第177行,将

video_FourCC    = int(vid.get(cv2.CAP_PROP_FOURCC))

改为

video_FourCC    = cv2.VideoWriter_fourcc(*"mp4v")

然后运行如下指令

python yolo_video.py --input=test.mp4 --output=result.mp4 --classes=model_data/voc_classes.txt

即可以显示出测试视频,并保存运行结果

你可能感兴趣的:(人工智能)