Yolov3训练自己的数据集
暑假参加一个比赛用到了Yolov3 darknet训练数据,一直想着要把它记录下来,拖到开学后好久啦才动手
第一篇blog就是你啦~
环境配置
- Ubuntu 18.04;
- cpu(电脑太垃圾,没有独显惨兮兮);
下载安装darknet
yolo官网 here https://pjreddie.com/
1、下载darknet,官网有提示哟,这里也贴出来吧
git clone https://github.com/pjreddie/darknet.git
cd darknet
make
2、修改Makefile文件
vi Makefile
我这里只能用cpu,如果你们可以用gpu就把GPU=0改为GPU=1
然后保存退出再
make
才能让你的修改生效
修改darknet里面的一些文件
1、修改/darknet/cfg/voc.data:
classes= 7 #类的个数
train = /darknet/scripts/2019_train.txt #2019_train.txt文件路径
valid = /darknet/scripts/2019_val.txt #2019_val.txt文件路径
names = data/voc.names
backup = backup #用来放后面训练生成的weights文件,没有就新建一个
2、修改 /darknet/data/voc.names :
写上自己的类名,一行一个,像下面这样
下载预训练权重文件
wget https://pjreddie.com/media/files/darknet53.conv.74
制作数据集
1、制作数据集文件结构
cd darknet/scripts #在这个目录下存放我们的数据集
mkdir VOCdevkit
cd VOCdevkit
mkdir VOC2019 #这里的年份你随意,但是前后要一致
cd VOC2019
mkdir Annotations #存放xml格式的数据
mkdir -p ImageSets/Main #存放训练数据集和验证数据集的图片名,Main里面就2个txt文件:train.txt val.txt
mkdir JPEGImages #存放原始图片在这里插入代码片
mkdir labels #存放每张图片的txt信息
文件结构就建好啦~
如下图
2、数据集的命名
!!!有些图片后缀名是.JPG,它后面生成的路径上的是.jpg,按理说不会有影响滴~
然而我又踩了一个坑,大小写不一致会出现: can’t load image
更改后缀名参考此处嘻嘻嘻~
更改之前最好备份,血淋淋的教训啊
3、数据集打标签
这里使用的工具是 labelImg 下载安装传送门biu~
下载好了后在终端运行以下代码打开labelImg
cd labelImg #有些是labelImg-master,反正自己康康呗
python labelImg.py
出现如下界面
然后点击 打开目录 注意这里不是点 打开文件 !!
(打开文件 打开的是单张图,这里快捷键Ctrl + A和Ctrl + D 都没用的)说多了都是泪啊!!
这里放几个快捷键吧,嘿嘿
上一张: Ctrl + A
下一张: Ctrl + D
创建一个矩形框:Ctrl + W
保存:Ctrl + S
3、标签打完后,放进对应的文件夹
Annotations : 放生成xml文件
JPEGImges: 放原始图片
4、生成训练所需的txt文件
首先 修改/darknet/scripts/voc_label.py :
#替换为自己的数据集,年份自己随意
sets=[('2019', 'train'),('2019','val')]
#修改为自己的类别
classes = ["fenda", "babaozhou", "hongniu", "kunlunshan", "chouzhi", "ADgai", "wanglaoji"]
#修改为自己的数据集用作训练(合并为train.txt)
os.system("cat 2019_train.txt 2019_val.txt > train.txt")
运行
python voc_label.py
生成2019_train.txt,2019_val.txt,train.txt等训练文件列表,这是在 scripts 目录下的
然后 需要生成 ImageSets/Main里面的两个txt文件:train.txt 和 val.txt
话不多说,直接上代码
import os
from os import listdir, getcwd
from os.path import join
if __name__=='__main__':
source_folder='/darknet/scripts/VOCdevkit/VOC2019/JPEGImages'
dest='/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/train.txt' # train.txt文件路径
dest2 = '/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/val.txt' # val.txt文件路径
file_list=os.listdir(source_folder)
train_file=open(dest,'a')
val_file = open(dest2, 'a')
for file_obj in file_list:
file_path=os.path.join(source_folder,file_obj)
file_name,file_extend=os.path.splitext(file_obj)
file_num=int(file_name)
if(file_num%50==0):
val_file.write(file_name+'\n')
else:
train_file.write(file_name+'\n')
train_file.close()
val_file.close()
运行这个程序,get it~
开始训练啦
停,先修改一下这个文件 /darknet/cfg/yolov3-voc.cfg:
查找yolo,共 四 处要修改:
# Testing(训练好模型后测试时下两行注释取消,训练时注释保留)
# batch=1
#subdivisions=1
# Training(测试时下两行添加注释)
batch=8
subdivisions=4
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1
(如上修改有一处)
[convolutional]
size=1
stride=1
pad=1
filters=36 #修改为 3*(classes+5),我用了7个类故为36
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=7 #修改为自己类别个数
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0 #如果显存大可设为1,显存小为0,关闭多尺度训练
(如上修改有三处,修改后保存)
这才开始训练啦~
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 -gpus #这是有gpu的
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 #cpu
训练时有好些参数呢,这里了解不深,参考了其他的文章
#训练过程参数意义:
Region xx: cfg文件中yolo-layer的索引;
Avg IOU:当前迭代中,预测的box与标注的box的平均交并比,越大越好,期望数值为1;
Class: 标注物体的分类准确率,越大越好,期望数值为1;
obj: 越大越好,期望数值为1;
No obj: 越小越好;
.5R: 以IOU=0.5为阈值时候的recall; recall = 检出的正样本/实际的正样本
0.75R: 以IOU=0.75为阈值时候的recall;
count:正样本数目。
检测图片
!!! 这里要先修改/darknet/cfg/yolov3-voc.cfg :
# Testing(取消下面两行注释)
batch=1
subdivisions=1
# Training(下面两行添加注释)
#batch=8
#subdivisions=4
width=416
height=416
channels=3
momentum=0.9
decay=0.0005
angle=0
saturation = 1.5
exposure = 1.5
hue=.1
保存再终端执行
./darknet detector test cfg/yolov3-voc.cfg backup/yolov3.weights data/xxx.jpg #此处是你要检测图像的路径
终于到底啦!
有些这个过程中遇到的问题以及解决方法会在后面的博客中贴出来~
第一次写博客,经验不多,有啥错误的欢迎下方留言指出!!