YOLO算法在windows下训练自己的数据集

本文最后更新于:2022年2月9日 上午

YOLO算法在windows下训练自己的数据集

背景基础

  • 已有在官方权重下,YOLOV3算法在识别物体上的测试效果

  • 特定数据集的制作与训练实现特有的目标检测

目的

xx目标的识别检测

方法

(1条消息) win10下yolov3训练自己的数据集_congcong7267的博客-CSDN博客

训练自己的数据集、

*   每种物体采集大概两三百张照片(距离、背景、光线)

*   标注图片中的目标,制作数据集

*   打开win10终端,cd进入darknet-master\\build\\darknet\\x64,darknet.exe detector train data/obj.data yolo-obj.cfg darknet53.conv.74 开始训练

生成权重文件移植到树莓派上进行测试

*   backup文件下最后一个权重文件复制到build\\darknet\\x64\

*   打开win10终端,cd进入然后运行darknet-master\\build\\darknet\\x64路径

*   输入:darknet.exe detector test data/obj.data yolo-obj.cfg yolo-obj\_100.weights(olo-obj\_100.weights为训练好的权重名)

*   终端会提醒你输入图片路径,然后你输入测试图片的绝对路径即可看到效果

实践

(2条消息) win10下yolov3训练自己的数据集_congcong7267的博客-CSDN博客

新建yolo-obj.cfg文件,将batch 改成64 :batch=64,subdivisions=64

在Darknet中,batch和subdivisions是结合使用的,例如设置batch=64,subdivisions=16,表示训练的过程中将一次性加载64张图片进内存,然后分16次完成前向传播,意思是每次4张,前向传播的循环过程中累加loss求平均,待64张图片都完成前向传播后,再一次性后传更新参数。(yolov3.cfg参数说明及调参经验 - 知乎 (zhihu.com))

接着根据训练类别数(classes),修改每个[yolo](三处)上面(即每个yolo的输出层)的第一个convolution里filters(滤波器)的大小 filters=(classes + 5)x3,每个[yolo](三处)下面 的classes修改为自己的类别数。

在build\darknet\x64\data\下新建obj.names文件,写入自己的类名

在build\darknet\x64\data\下新建obj.data文件

制作数据集

  • 图片批量顺序命名py脚本

  • 使用labelimg标注图片中的目标,生成xml文件

使用py脚本将xml文件转为txt文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import os
import xml.etree.ElementTree as ET

dirpath = r'E:\gongzuo\伪代码\darknet\build\darknet\x64\data\txt' # 原来存放xml文件的目录
newdir = r'E:\gongzuo\伪代码\darknet\build\darknet\x64\data\obj' # 修改label后形成的txt目录

if not os.path.exists(newdir):
os.makedirs(newdir)

dict_info = {'person': 0} # 有几个 属性 填写几个label names

for fp in os.listdir(dirpath):
if fp.endswith('.xml'):
root = ET.parse(os.path.join(dirpath, fp)).getroot()

xmin, ymin, xmax, ymax = 0, 0, 0, 0
sz = root.find('size')
width = float(sz[0].text)
height = float(sz[1].text)
filename = root.find('filename').text
for child in root.findall('object'): # 找到图片中的所有框

sub = child.find('bndbox') # 找到框的标注值并进行读取
label = child.find('name').text
label_ = dict_info.get(label)
if label_:
label_ = label_
else:
label_ = 0
xmin = float(sub[0].text)
ymin = float(sub[1].text)
xmax = float(sub[2].text)
ymax = float(sub[3].text)
try: # 转换成yolov3的标签格式,需要归一化到(0-1)的范围内
x_center = (xmin + xmax) / (2 * width)
x_center = '%.6f' % x_center
y_center = (ymin + ymax) / (2 * height)
y_center = '%.6f' % y_center
w = (xmax - xmin) / width
w = '%.6f' % w
h = (ymax - ymin) / height
h = '%.6f' % h
except ZeroDivisionError:
print(filename, '的 width有问题')
with open(os.path.join(newdir, fp.split('.xml')[0] + '.txt'), 'a+') as f:
f.write(' '.join([str(label_), str(x_center), str(y_center), str(w), str(h) + '\n']))
print('ok')

  • 将所有样本图片及对应的的txt文件)放到:build\darknet\x64\data\obj\

  • 在build\darknet\x64\data\下新建train.txt,训练图片的路径放入文件

  • 将darknet的预训练权重放入build\darknet\x64

预训练权重文件 密码:x5ht

  • 在\darknet路径下修改网络配置文件Makefile

  • 对比官方makefile修改:(其中C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.4/ 为自己的CUDA安装路径)

下载链接 提取码:jh1i))

*   GPU=1 CUDNN=1

*   NVCC=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.4/bin/nvcc

*   COMMON+= -DGPU -I/C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.4/include

*   LDFLAGS+= -L/C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.4/lib -lcuda -lcudart -lcublas -lcurand



* 打开cmd,cd进入darknet-master\build\darknet\x64路径,输入:darknet.exe detector train data/obj.data yolo-obj.cfg darknet53.conv.74 开始训练

*   avg loss接近0.XX且变化不大时可停止训练,将x64\\backup下的weight文件复制到\\x64下,cd进入darknet-master\\build\\darknet\\x64路径运行darknet.exe detector test data/obj.data yolo-obj.cfg yolo-obj_last.weights,程序会提示输入待检测图片的路径。

结果

  • 纵坐标平均loss(误差)接近0.545,即变化不大时可停止训练。横坐标batch(每batch(64)个样本更新一次参数)

  • 在YOLOv3中,Loss分为三个部分:

    • 1、一个是x、y、w、h部分带来的误差,也就是bbox带来的loss
    • 2、一个是置信度带来的误差,也就是obj带来的loss
    • 3、最后一个是类别带来的误差,也就是class带来的loss
  • 对比使用官方权重与自己训练的数据集检测目标时,由于检测结果受到样本数量的影响两者检测结果均不为理想。

  • avg loss(误差)接近0.219时,基本不再变化

####检测结果 ####

参数分析:

*   1623: 当前训练的迭代次数;

*   0.215670: 总体的 Loss(损失);

*   0.232835 avg: 平均 Loss, 这个数值应该越低越好, 一般来说, 一旦这个数值低于 0.060730 avg 就可以终止训练了;

*   0.001000 rate: 当前的学习率, 在.cfg文件中定义的;

*   9.07000 seconds: 当前批次训练花费的总时间;

*   103875 images: 这一行最后的这个数值是 9798*64 的大小, 表示到目前为止, 参与训练的图片的总量.