Yolov5训练自己的数据集
一、环境搭建
##1.代码下载
在Github上搜索yolov5 pytorch版本即可,下载到本地并解压。
##
##2.安装配置环境
大家可以自己看一下,yolov5文件夹里面的,requirements.txt文件,里面即是所需要的配置环境,这时候我们只需要运行pip install -r requirements.txt
文件,那么系统就可以按照文件里面的来配置环境啦。当然这建立在你已经下载好cuda和cudnn是的基础上,补充一点:在按照requirements.txt下载pytorch时,可能会出现无法下载的情况,这时候我们只要在pytorch官网上搜索与自己的cuda版本匹配的pytorch即可。(pytorch官网)
#数据集的准备
使用labelImg标注好自己的数据集,(labelImg是专门用来标注的软件,百度搜索下载即可,对了,yolov5标签的格式是txt格式,因此,这点在标注数据集的时候请注意,**链接:https://pan.baidu.com/s/1gqhvkbTM5Ht8Wm-pNA09Mw
提取码:csdn*这边附一个链接,直接下载就好了)
YOLOv5中 train/valid/.txt 文件中保存的是,训练集以及测试集路径,通过split脚本可以生成,yolov5的标签格式是 txt格式,英因此需要将xml格式的标签转换为txt格式,通过xml_to_label脚本完成,最后将图片以及txt格式的标签放到obj文件夹下面即可
split.py脚本
import os
import random
trainval_percent = 0.2 # 训练和验证集所占比例,剩下的0.1就是测试集的比例
train_percent = 0.8 # 训练集所占比例,可自己进行调整
xmlfilepath = r'J:\yolov5-zahban1\yolov5-zhaban\data\annotation'
total_xml = os.listdir(xmlfilepath)
print(type(total_xml[1]))
# total_xml= listtotal_xml
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
ftrainval = open('yolov5-zhaban/data/valid.txt', 'w')
ftrain = open('yolov5-zhaban/data/train.txt', 'w')
for i in range(0, num):
# os.path.splitext(total_xml[i])[1] = '.jpg'
total_xml[i] =total_xml[i].split('.')[0]
name = "J:\yolov5-zahban1\yolov5-zhaban\data\obj/" + total_xml[i] + ".jpg"+ '\n'
if i in trainval:
ftrainval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
label_label脚本
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=['train','valid']
classes = ["cup", "bottle"]
def convert(size, box):
dw = 1./size[0]
dh = 1./size[1]
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
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(image_id): # 转换这一张图片的坐标表示方式(格式),即读取xml文件的内容,计算后存放在txt文件中。
in_file = open('annotation/%s'% image_id)
image_id=image_id.split('.')[0]
out_file = open('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')
for image_set in sets:
if not os.path.exists('yolov5-zhaban/data/labels/'):
os.makedirs('yolov5-zhaban/data/labels/') # 新建一个 labels 文件夹,用于存放yolo格式的标签文件:000001.txt
image_ids = open('%s.txt' % image_set).read().strip().split()# 读取txt文件中 存放的图片的 id:000001
for image_id in image_ids:
image_id=image_id.split('/')[-1]
image_id=image_id.split('.')[0]
image_id=image_id+".xml"
convert_annotation(image_id) # 转换这一张图片的坐标表示方式(格式)
并将数据集文件按如下分布,
好了,以上就是,前期的准备工作了,其实对于,yolov5来说,个人感觉前期的数据准备消耗了大量的时间,后面的训练反而很简单。
#二、开始训练
因为train.py文件里面训练默认的是coco128.yaml,所以我们在data里面找到coco128.yaml文件按照下面的提示修改即可。
# COCO 2017 dataset http://cocodataset.org - first 128 training images
# Train command: python train.py --data coco128.yaml
# Default dataset location is next to /yolov5:
# /parent_folder
# /coco128
# /yolov5
# download command/URL (optional)
download: https://github.com/ultralytics/yolov5/releases/download/v1.0/coco128.zip
# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: D:\yolov5-zahban1\data\train.txt # 128 images **#改成自己train.txt文件所在的绝对路径**
val: D:\yolov5-zahban1\data\valid.txt # 128 images **#改成自己test.txt文件所在的绝对路径**
# number of classes
nc: 2 **#自己数据集里面的类数**
# class names
names: ['mouse', 'tongue'] **#自己数据集的种类**
在models文件下面的yolov5s.yaml文件下将nc(种类数)修改成自己的种类数即可。
```python
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path') #预训练权重文件
parser.add_argument('--cfg', type=str, default='', help='model.yaml path') #使用s模型
parser.add_argument('--data', type=str, default='data/coco128.yaml', help='data.yaml path')
parser.add_argument('--hyp', type=str, default='data/hyp.scratch.yaml', help='hyperparameters path')
parser.add_argument('--epochs', type=int, default=30) #迭代次数,显卡不行适当减小
parser.add_argument('--batch-size', type=int, default=2, help='total batch size for all GPUs')#同上,显卡不行,适当减小
parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='[train, test] image sizes')
parser.add_argument('--rect', action='store_true', help='rectangular training')
parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
parser.add_argument('--notest', action='store_true', help='only test final epoch')
parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
parser.add_argument('--name', default='', help='renames results.txt to results_name.txt if supplied')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset')
parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')
parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')
parser.add_argument('--logdir', type=str, default='runs/', help='logging directory')
parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')
opt = parser.parse_args()
在train文件里面,我们也需要根据自己的实际情况,进行修改的,如上提示
然后点击运行,不出意外的情况下,就可以训练啦,哈哈哈~~~
#三、训练完成,检验效果。
首先,恭喜你走到这一步,
训练完成后,你就可以看到你的权重文件以及训练结果啦,那么这时候在detect.py文件里面,修改以下参数就好啦
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+', type=str, default='best.pt', help='model.pt path(s)') **#将run里面的权重文件复制都到根目录就好了**
parser.add_argument('--source', type=str, default='inference/images', help='source') # file/folder, 0 for webcam
parser.add_argument('--output', type=str, default='inference/output', help='output folder') # output folder
parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
parser.add_argument('--conf-thres', type=float, default=0.4, help='object confidence threshold')
parser.add_argument('--iou-thres', type=float, default=0.5, help='IOU threshold for NMS')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--view-img', action='store_true', help='display results')
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--update', action='store_true', help='update all models')
opt = parser.parse_args()
print(opt)
将自己需要测试的图片放在下图所示的文件夹中,在pycharm里面的终端运行python detect.py文件,就好啦
在output里面就能看到测试结果啦!~~~
新手博主,第一次记录自己的过程,中间肯定有很多漏洞的地方,烦请各位大佬指正,当然如果你也是小白,那么欢迎私聊我,咱们一块探讨!抱拳了铁子。
9.30更,早晨想根据kmean聚类一组新的框来训练自己的数据集,然后聚类之后按照原有的格式改变,如下# anchors anchors: -[106,57, 113,168] -[213,171, 327,179] -[447,185, 552,260]
结果运行报错,` File “train.py”, line 81, in train
model = Model(opt.cfg, ch=3, nc=nc).to(device) # create 如果没有,则重新开始
File “D:\yolov5-zahban1\yolov5-zhaban\models\yolo.py”, line 78, in init
self.model, self.save = parse_model(deepcopy(self.yaml), ch=[ch]) # model, savelist, ch_out
File “D:\yolov5-zahban1\yolov5-zhaban\models\yolo.py”, line 229, in parse_model
m_ = nn.Sequential(*[m(*args) for _ in range(n)]) if n > 1 else m(*args) # module
File “D:\yolov5-zahban1\yolov5-zhaban\models\yolo.py”, line 30, in init
a = torch.tensor(anchors).float().view(self.nl, -1, 2)
TypeError: new(): invalid data type ‘str’
找了很长时间,发现原来是在 — 的后面需要加一个空格,不然程序在读入框数据时会将横线也都进去,改后如下图:
2021 0612 这里提供一下yolov5s的预训练权重文件
链接:https://pan.baidu.com/s/1tgURSYQqcx3Z9kVm8PHcjw
提取码:c2gr
复制这段内容后打开百度网盘手机App,操作更方便哦