目录
2.1 在 yolov5目录下 新建文件夹 VOCData(可以自定义命名)
2.2在VOCData下新建两个文件夹 Annotations 以及 images
4.1 在 yolov5 目录下的 data 文件夹下 新建一个 myvoc.yaml文件(可以自定义命名)。
使用的环境:
pytorch: 1.10.0
python: 3.9
yolov5 v6.0
其中: 如果使用GPU,cuda版本要 >=10.1
下载yolov5
yolov5 v6.0官方要求 Python>=3.6 and PyTorch>=1.7
yolov5源码下载:https://github.com/ultralytics/yolov5
2.1 在 yolov5目录下 新建文件夹 VOCData(可以自定义命名)
2.2在VOCData下新建两个文件夹 Annotations 以及 images
images:用于存放要标注的图片(jpg格式)
Annotations :用于存放标注图片后产生的内容(这里采用XML格式)
2.3 labelimg的安装
打开anaconda prompt
输入:pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple
2.4 使用labelimg进行标注
首先新建一个predefined_classed.txt文件,在文件内写入待标注的类别。
在终端中进入到VOCData文件夹
输入如下的命令打开labelimg。这个命令的意思是打开labelimg工具;打开JPEGImage文件夹,初始化predefined_classes.txt里面定义的类。
labelimg predefined_classes.txt
运行如上的命令就会打开这个工具;如下
待标注图片数据的路径文件夹,选择images文件夹
保存类别标签的路径文件夹,选择Annotations 文件夹
这个按键可以说明我们标注的标签为voc格式,点击可以换成yolo或者createML格式。(这里选择voc格式)
点击View,会出现如图红色框框中的选项。最好和我一样把勾勾勾上。
Auto Save mode:切换到下一张图的时候,会自动保存标签。
Display Labels:会显示标注框和标签
Advanced Mode:标注的十字架会一直悬浮在窗口。
常用快捷键如下:
A:切换到上一张图片
D:切换到下一张图片
W:调出标注十字架
del :删除标注框框
Ctrl+u:选择标注的图片文件夹
Ctrl+r:选择标注好的label标签存在的文件夹
我们设置了标注的十字架一直在标注界面上,这里就不需要我们按快捷键w,然后选择我们需要标注的对象。按住鼠标左键拖出矩形框就可以了。如下图所示,当我们选定目标以后,就会加载出来predefined_classes.txt 定义自己要标注的所有类别(如果类别多,就不需要自己手打每个类别的名字)。打好的标签框框上会有该框框的类别。然后界面最右边会出现打好的类别标签。打好一张照片以后,快捷键D,就会进入下一张,这时候就会自动保存标签文件(voc格式会保存xml,yolo会保存txt格式)。
在Annotations 文件下可以看到以及标签的文件已经保存在这个目录下。
3.1. 划分训练集、验证集、测试集
在VOCData目录下创建程序 split_train_val.py
并运行
程序如下:
# coding:utf-8import osimport randomimport argparseparser = argparse.ArgumentParser()#xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下,注意以下为相对路径parser.add_argument('--xml_path', default='Annotations', type=str, help='input xml label path')#数据集的划分,地址选择自己数据下的ImageSets/Main,注意以下为相对路径parser.add_argument('--txt_path', default='ImageSets/Main', type=str, help='output txt label path')opt = parser.parse_args()trainval_percent = 1.0 # 训练集和验证集所占比例。 这里没有划分测试集train_percent = 0.9 # 训练集所占比例,可自己进行调整xmlfilepath = opt.xml_pathtxtsavepath = opt.txt_pathtotal_xml = os.listdir(xmlfilepath)if not os.path.exists(txtsavepath): os.makedirs(txtsavepath)num = len(total_xml)list_index = range(num)tv = int(num * trainval_percent)tr = int(tv * train_percent)trainval = random.sample(list_index, tv)train = random.sample(trainval, tr)file_trainval = open(txtsavepath + '/trainval.txt', 'w')file_test = open(txtsavepath + '/test.txt', 'w')file_train = open(txtsavepath + '/train.txt', 'w')file_val = open(txtsavepath + '/val.txt', 'w')for i in list_index: name = total_xml[i][:-4] + '\n' if i in trainval: file_trainval.write(name) if i in train: file_train.write(name) else: file_val.write(name) else: file_test.write(name)file_trainval.close()file_train.close()file_val.close()file_test.close()
程序运行完成后 会生成 ImagesSets\Main 文件夹,在这个文件夹中会生成 测试集、训练集、训练验证集、验证集 (由于这里没有分配测试集,所以测试集为空。若要分配测试集,需要更改第 14、15 行的代码,即更改对应的比例)
3.2. XML格式转yolo_txt格式
在VOCData目录下创建程序 text_to_yolo.py
并运行
程序如下:
# -*- coding: utf-8 -*-import xml.etree.ElementTree as ETimport osfrom os import getcwdsets = ['train', 'val', 'test']classes = ["bottle"] # 改为自己的类别abs_path = os.getcwd()print(abs_path)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, hdef convert_annotation(image_id): in_file = open('D:/Yolov5/yolov5/VOCData/Annotations/%s.xml' % (image_id), encoding='UTF-8') out_file = open('D:/Yolov5/yolov5/VOCData/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 # 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)) b1, b2, b3, b4 = b # 标注越界修正 if b2 > w: b2 = w if b4 > h: b4 = h b = (b1, b2, b3, b4) bb = convert((w, h), b) out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')wd = getcwd()for image_set in sets: # 这里是绝对路径,需要根据自己的情况修改 if not os.path.exists('D:/Yolov5/yolov5/VOCData/labels/'): os.makedirs('D:/Yolov5/yolov5/VOCData/labels/') image_ids = open('D:/Yolov5/yolov5/VOCData/ImageSets/Main/%s.txt' % (image_set)).read().strip().split() if not os.path.exists('D:/Yolov5/yolov5/VOCData/dataSet_path/'): os.makedirs('D:/Yolov5/yolov5/VOCData/dataSet_path/') list_file = open('D:/Yolov5/yolov5/VOCData/dataSet_path/%s.txt' % (image_set), 'w') for image_id in image_ids: list_file.write('D:/Yolov5/yolov5/VOCData/images/%s.jpg\n' % (image_id)) convert_annotation(image_id) list_file.close()
程序运行完成后,会生成 labels 文件夹和 dataSet_path 文件夹。
其中 labels 中为不同图像的标注文件。每个图像对应一个txt文件,文件每一行为一个目标的信息,分别为class, x_center, y_center, width, height,这种为 yolo_txt格式
dataSet_path文件夹包含三个数据集的txt文件,train.txt等txt文件为划分后图像所在位置的路径,如train.txt就含有所有训练集图像的路径。
4.1 在 yolov5 目录下的 data 文件夹下 新建一个 myvoc.yaml文件(可以自定义命名)。
内容是:
训练集(train.txt)的路径
验证集(val.txt)的路径
目标的类别数目
类别名称。
模板如下:
train: D:/Yolov5/yolov5/VOCData/dataSet_path/train.txtval: D:/Yolov5/yolov5/VOCData/dataSet_path/val.txt# number of classesnc: 2# class namesnames: ["bottle", "apple"]
4.2生成anchors
如果目录 yolov5/utils下有 autoanchor.py文件,那么就可以采用自动获取anchors。(yolov5版本偏低是没有的)
确保 yolov5/data/hyps/hyp.cratch.yaml中的anchors这行是注释掉的。
采用自动法的话,不用运行,训练时自动调用
4.3修改模型配置文件
在yolov5目录下的model文件夹下是模型的配置文件,有n、s、m、l、x版本,逐渐增大(随着架构的增大,训练时间也是逐渐增大)。
这里选择 yolov5s.yaml
打开 yolov5s.yaml,最好将yolov5s.yaml文件复制一份,然后将其重命名,我将其重命名为yolov5_bottle.yaml。所有冒号后面需要加一个空格。
找到train.py这个py文件。找到主函数,这里面有模型的主要参数,训练自己的模型需要修改如下几个参数就可以训练了。首先将weights权重的路径填写到对应的参数里面,然后将修好好的models模型的yolov5s.yaml文件路径填写到相应的参数里面,最后将data数据的hat.yaml文件路径填写到相对于的参数里面。这几个参数就必须要修改的参数。
还有几个需要根据自己的需求来更改的参数:首先是模型的训练轮次,这里是训练的100轮。
其次是输入图片的数量和工作的核心数,这里每个人的电脑都不一样,所以这里每个人和自己的电脑的性能来。这里可以根据我的电脑的配置做参考,我的电脑是拯救者2060版本的显卡,cpu的核心数是16核。我的电脑按默认的参数输入图片数量为16,工作核心为8的话就会出现GPU显存溢出的报错。每个人的电脑配置不一样,所以可以根据自己的电脑配置来修改参数。
或者在终端运行
python train.py --weights weights/yolov5s.pt --cfg models/yolov5s.yaml --data data/myvoc.yaml --epoch 200 --batch-size 8 --img 640 --device cpu
4.4训练过程
训练好的模型会被保存在 yolov5 目录下的 runs/train/weights/ 下
4.5训练可视化
训练时或者训练后可以利用 tensorboard 查看训练可视化
在终端中进入到yolov5的文件夹,输入tensorboard --logdir=runs/train/exp4,我的为exp4(即为第四次训练),需要根据自己的情况来定。
tensorboard --logdir=runs/train/exp4
就会出现一个网址地址,将那行网址复制下来到浏览器打开就可以看到训练的过程了
如果模型已经训练好了,但是我们还想用tensorbord查看此模型的训练过程,就需要输入如下的命令。就可以看到模型的训练结果了。
等数据训练好后,就会在主目录下产生一个run文件夹,在run/train/exp/weights目录下会产生两个权重文件,一个是最后一轮的权重文件,一个是最好的权重文件。找到主目录下的detect.py文件,打开该文件。然后找到主函数的入口,这里面有模型的主要参数。
第一行:需要将刚刚训练好的最好的权重传入到推理函数中去。然后就可以对图像视频进行推理。
第二行:对图片进行测试推理,将如下参数修改成图片的路径
运行detect.py就可以进行测试了。
测试结束以后,在run下面会生成一个detect目录,推理结果会保存在exp目录下。
对视频进行测试,和如上的图片的测试是一样的,只不过是将图片的路径改为视频的路径而已
利用摄像头进行测试只需将路径改写为0就好了。但是11报错如下。
解决方法:首先找到datasets.py这个py文件。 打开文件,找到第279行代码,给两个url参数加上str就可以了,如图所示,就可以完美运行电脑的摄像头了。
1.从0开始学视觉(5)——利用yolov5训练自己的目标检测模型_从0开始深度学习的博客-CSDN博客_yolov5训练自己的模型
Yolov5训练自己的数据集(详细完整版)_缔宇diyu的博客-CSDN博客_yolov5训练自己的数据集
来源地址:https://blog.csdn.net/weixin_58630603/article/details/125750945