改作者都在讲解yolov3:https://blog.youkuaiyun.com/holmes_MX/article/details/81235687:
YOLOv3 训练自己的数据(解决网上提供的文章不能一次成功的问题)
置顶 2018年07月27日 15:33:03 holmes_MX 阅读数:2688
版权声明:原创博客未经允许请勿转载! https://blog.youkuaiyun.com/holmes_MX/article/details/81235687
0. 写本博客的目的
对于使用yolov3训练自己的数据,网上虽然文章多,但是经过实验发现,基本没有能一次运行的成功的。因此特写此文,记录自己在使用yolov3训练自己的数据时遇到的坑。
环境:ubuntu14 + CUDA8.0 + cudnn5.0 + GTX1050Ti (4G)
1. 制作数据
为了便于在多个目标检测框架(如Faster R-CNN,SSD等)中训练,制作数据时,推荐使用类似VOC(VOC-LIKE)数据。windows可以使用labelImg.exe来进行标注。具体这里不详细介绍了。
2. 下载+编译yolov3
从官方网址中下载yolov3源码。具体编译过程作者有介绍。这里简要介绍一下自己编译的过程。
假设yolov3在ubuntu中的路径为/home/XXX/darknet
1) 修改配置文件(Makefile)
Makefile文件中(下面是配置文件中的修改部分,或者需要注意的部分)
需要注意的是:是否使用GPU,是否使用CUDNN进行进一步加速,是否使用opencv。如果使用GPU时,需要注意CUDA的安装位置,如果使用opencv,需要注意opencv的位置。有关opencv的ubuntu安装,推荐一个靠谱的安装方式。对于需要注意的地方,在下面的Makefile中有相关注释。
-
GPU=1 ## using GPU for train or test -
CUDNN=0 ## using CUDNN to improve speed -
OPENCV=1 ## using opencv -
OPENMP=0 -
DEBUG=0 -
## the arch of your GPU -
ARCH = -gencode arch=compute_60,code=sm_60 \ -
-gencode arch=compute_61,code=sm_61 \ -
-gencode arch=compute_62,code=compute_62 -
#ARCH= -gencode arch=compute_30,code=sm_30 \ -
# -gencode arch=compute_35,code=sm_35 \ -
# -gencode arch=compute_50,code=[sm_50,compute_50] \ -
# -gencode arch=compute_52,code=[sm_52,compute_52] \ -
# -gencode arch=compute_60,code=sm_60 \ -
# -gencode arch=compute_61,code=sm_61 \ -
# -gencode arch=compute_61,code=compute_61 -
# -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated? -
# This is what I use, uncomment if you know your arch and want to specify -
# ARCH= -gencode arch=compute_52,code=compute_52 -
CFLAGS+=$(OPTS) -
ifeq ($(OPENCV), 1) -
COMMON+= -DOPENCV -
CFLAGS+= -DOPENCV -
LDFLAGS+= `pkg-config --libs opencv2.4` ## the position of your opencv -
COMMON+= `pkg-config --cflags opencv2.4` ## the position of your opencv -
endif
2) 编译
首先进入darknet所在目录,然后进行编译: make。为了提高编译速度可以使用make -j4 或者make -j8。(-j4 或者-j8依据自己的电脑配置)
注意:在训练自己的数据时,每次修改.c文件后,需要重新编译(修改配置文件不需要)。具体过程为:make clean 清除之前的编译,然后make或者make -j4。
3. 测试安装成功与否
1) 下载作者训练好的权重(在/home/XXX/darknet目录下)
具体为:
wget https://pjreddie.com/media/files/yolov3.weights
2) 进行测试
注意:如果出现问题,一般在下面命令前加上sudo,重新运行一下就可以了。
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
也可以使用该命令进行测试:
./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg
4. 训练自己的数据
在/home/XXX/darknet/目录下建立自己的数据集存放文件: myData
1) 将数据转为yolov3所需要的数据
这里给出VOC-LIKE数据中的格式: 在/home/XXX/darknet/myData中存放以下文件:
JEPGImages —— 存放图像
Annotations —— 存放图像对应的xml文件
ImagesSets/Main —— 存放训练/验证图像的名字(格式如 000001.jpg或者000001),里面包括train.txt。这里给出的格式是: 000000,因为下面的代码中给出了图像的格式。
2) yolov3提供了将VOC数据集转为YOLO训练所需要的格式的代码。这里提供一个修改版本的。
-
import xml.etree.ElementTree as ET -
import pickle -
import os -
from os import listdir, getcwd -
from os.path import join -
sets=[('myData', 'train')] -
classes = ["plane", "boat", "person"] # each category's name -
def convert(size, box): -
dw = 1./(size[0]) -
dh = 1./(size[1]) -
x = (box[0] + box[1])/2.0 - 1 -
y = (box[2] + box[3])/2.0 - 1 -
w = box[1] - box[0] -
h = box[3] - box[2] -
x = x*dw -
w = w*dw -
y = y*dh -
h = h*dh -
return (x,y,w,h) -
def convert_annotation(year, image_id): -
in_file = open('myData/Annotations/%s.xml'%(image_id)) -
out_file = open('myData/labels/%s.txt'%(image_id), 'w') -
tree=ET.parse(in_file) -
root = tree.getroot() -
size = root.find('size') -
w = int(size.find('width').text) -
h = int(size.find('height').text) -
for obj in root.iter('object'): -
difficult = obj.find('difficult').text -
cls = obj.find('name').text -
if cls not in classes or int(difficult)==1: -
continue -
cls_id = classes.index(cls) -
xmlbox = obj.find('bndbox') -
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) -
bb = convert((w,h), b) -
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n') -
wd = getcwd() -
for year, image_set in sets: -
if not os.path.exists('myData/labels/'): -
os.makedirs('myData/labels/') -
image_ids = open('myData/ImageSets/Main/%s.txt'%(image_set)).read().strip().split() -
list_file = open('myData/%s_%s.txt'%(year, image_set), 'w') -
for image_id in image_ids: -
list_file.write('%s/myData/JPEGImages/%s.jpg\n'%(wd, image_id)) -
convert_annotation(year, image_id) -
list_file.close()
运行后,会在/home/XXX/darknet/myData目录下生成一个labels文件夹一个txt文件(myData_train.txt)(内容是: 类别的编码和目标的相对位置)。
2) 修改配置文件
i) 修改/home/XXX/darknet/cfg下的voc.data和yolov3-voc.cfg文件
voc.data修改为:
-
classes= 3 ## the number of classes -
train = /home/XXX/darknet/myData/myData_train.txt ## depend on your choise -
names = /home/XXX/darknet/myData/myData.names ## depend on your choise -
backup = /home/XXX/darknet/myData/weights ## restore the trained model
yolov3-voc.cfg修改的地方为: .cfg文件中涉及[yolo]层的地方(共3处):
-
[convolutional] -
size=1 -
stride=1 -
pad=1 -
filters=24 ## anchors_num * (classes_num + 5) -
activation=linear -
[yolo] -
mask = 6,7,8 -
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 -
classes=3 ## classes_num -
num=9 -
jitter=.3 -
ignore_thresh = .5 -
truth_thresh = 1 -
random=0 ## multi-scale training (1 indicates using)
训练时,需要将yolov3-voc.cfg 修改为训练阶段:
-
[net] -
# Testing -
# batch=1 -
# subdivisions=1 -
# Training -
batch=16 ## depend on your GPU's size -
subdivisions=4 ## depend on your GPU's size -
#batch=8 -
#subdivisions=2 -
width=416 -
height=416 -
channels=3 -
momentum=0.9 -
decay=0.0005 -
angle=0 -
saturation = 1.5 -
exposure = 1.5 -
hue=.1
ii) 在/home/XXX/darknet/myData目录下添加文件: myData.names
在本博客中为:
-
plane -
boat -
person
注意:如果此时开始训练,会出现不能找到图像的问题(这是许多其他博客没有涉及的问题)。
解决方式为: 将训练所用的图像拷贝至/home/XXX/darknet/myData/labels中,然后运行就可以了。
刚开始训练时,loss值很大,这个是正常的现象(本博客开始训练时1000多,经过5000多次降到了3左右)。
There may be some mistakes in this blog. So, any suggestions and comments are welcome!
注释: 由于查看的文章过多,忘记了部分,导致不能一一列出来,还请见谅!
【Reference】
本文详细介绍如何使用YoloV3进行目标检测,包括环境搭建、数据准备、模型训练及测试全流程,解决常见问题,适合初学者快速上手。
2858

被折叠的 条评论
为什么被折叠?



