YOLOV8训练自己的数据集

一、环境部署

1、系统环境

系统环境建议是Linux环境,因为自己尝试过Win11系统,会有报错。

2、项目copy到系统

conda create -n yolov8 python=3.8
conda activate yolov8
git clone https://n.fastcloud.me/ultralytics/ultralytics.git
cd ultralytics
pip install -r requirement.txt
pip install ultralytics

 二、训练自己的数据集并测试

1、下载预训练权重

进到GitHub - ultralytics/ultralytics: NEW - YOLOv8 🚀 in PyTorch > ONNX > OpenVINO > CoreML > TFLite下载自己需要的预训练权重文件,一般和YOLOV5的版本差不多

2、准备数据集

(1)、数据集准备的话,可以直接准备YOLO格式的数据集,直接划分数据集训练、验证和测试集,下面是我的划分数据集的代码,仅供参考!

代码需要注意的是:

1、file_path = "./datasets/man/imgs",这个是图像储存的位置
2、txt_path = "./datasets/man/txt",这个是数据集TXT储存的位置
3、new_file_path = "./datasets/test",这个是划分完以后存储的位置(里面包含了train、val、test,在各个子文件夹下面有相应的images和label【也就是图片和标签文件夹】)
4、split_data(file_path, txt_path, new_file_path, train_rate=0.7, val_rate=0.2, test_rate=0.1),这个是调用划分的函数,训练集:验证集:测试集=7:2:1。

import os
import shutil
import random

random.seed(0)


def split_data(file_path, xml_path, new_file_path, train_rate, val_rate, test_rate):
    each_class_image = []
    each_class_label = []
    for image in os.listdir(file_path):
        each_class_image.append(image)
    for label in os.listdir(xml_path):
        each_class_label.append(label)
    data = list(zip(each_class_image, each_class_label))
    total = len(each_class_image)
    random.shuffle(data)
    each_class_image, each_class_label = zip(*data)
    train_images = each_class_image[0:int(train_rate * total)]
    val_images = each_class_image[int(train_rate * total):int((train_rate + val_rate) * total)]
    test_images = each_class_image[int((train_rate + val_rate) * total):]
    train_labels = each_class_label[0:int(train_rate * total)]
    val_labels = each_class_label[int(train_rate * total):int((train_rate + val_rate) * total)]
    test_labels = each_class_label[int((train_rate + val_rate) * total):]

    for image in train_images:
        print(image)
        old_path = file_path + '/' + image
        new_path1 = new_file_path + '/' + 'train' + '/' + 'images'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + image
        shutil.copy(old_path, new_path)

    for label in train_labels:
        print(label)
        old_path = xml_path + '/' + label
        new_path1 = new_file_path + '/' + 'train' + '/' + 'labels'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + label
        shutil.copy(old_path, new_path)

    for image in val_images:
        old_path = file_path + '/' + image
        new_path1 = new_file_path + '/' + 'val' + '/' + 'images'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + image
        shutil.copy(old_path, new_path)

    for label in val_labels:
        old_path = xml_path + '/' + label
        new_path1 = new_file_path + '/' + 'val' + '/' + 'labels'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + label
        shutil.copy(old_path, new_path)

    for image in test_images:
        old_path = file_path + '/' + image
        new_path1 = new_file_path + '/' + 'test' + '/' + 'images'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + image
        shutil.copy(old_path, new_path)

    for label in test_labels:
        old_path = xml_path + '/' + label
        new_path1 = new_file_path + '/' + 'test' + '/' + 'labels'
        if not os.path.exists(new_path1):
            os.makedirs(new_path1)
        new_path = new_path1 + '/' + label
        shutil.copy(old_path, new_path)


if __name__ == '__main__':
    file_path = "./datasets/man/imgs"
    txt_path = "./datasets/man/txt"
    new_file_path = "./datasets/test"
    split_data(file_path, txt_path, new_file_path, train_rate=0.7, val_rate=0.2, test_rate=0.1)

 (2)、数据集的格式也可以是VOC的格式,这样的话需要将xml的文件格式转为YOLO的txt格式,下面是我的格式转换代码【xml转txt】,仅供参考!

代码需要注意的是:

1、classes需要填写的是自己的类别

2、filenames是输入输出文件夹设置

import xml.etree.ElementTree as ET

import pickle
import os
from os import listdir, getcwd
from os.path import join
import glob

classes = ["vertical","horizontal"]


def convert(size, box):
    dw = 1.0 / size[0]
    dh = 1.0 / 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)


# 注意如果是在windows系统下那么路径里的反斜杠\应该多写一个,否则会和python的‘\’产生语义冲突
def convert_annotation(path,image_name):
    in_file = open(path + '/xml/' + image_name[:-3] + 'xml', 'r', encoding='utf-8')

    out_file = open(path+'/txt/' + image_name[:-3] + 'txt', 'w', encoding='utf-8')  # 转换后的txt文件存放路径
    f = in_file
    xml_text = f.read()
    root = ET.fromstring(xml_text)
    f.close()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):
        cls = obj.find('name').text
        if cls not in classes:
            print(cls)
            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()

if __name__ == '__main__':

    filenames = os.listdir('datasets/man/xml')  # xml文件路径,这样输出的txt文件和xml一一对应

    for label_path in filenames:
        print(label_path)
        convert_annotation('datasets/man',label_path)

(3)、划分完之后的文件夹是下面的样式

3、训练前准备

先拿yolov8的n版本作为测试,如果需要换版本直接换下面的文件就行

(1)、先测试环境和项目有没有问题

运行下面的环境,会将图片进行预测保存到runs下的predict里面,model是预训练权重,source是要预测的图片,如果这个参数的值是一个文件夹形式,那么就是预测文件夹里所有的图片。

yolo task=detect mode=predict model=/root/ultralytics-main/yolov8m.pt source=/root/ultralytics-main/1.jpg device=0

(2)、设置data.yaml

我们整体的训练需要两个yaml,一个是存储数据集路径和类别的,一个是yolov8各个版本网络架构配置的yaml文件。这里我将数据集的命名为data.yaml,下面是详细代码,可以根据自己的数据集位置进行修改和配置。

# 直接修改下面的train/val/test即可,nc是类别数,names是各个类别的名字

# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
train: ./test/train/images  # train images (relative to 'path') 128 images
val: ./test/val/images  # val images (relative to 'path') 128 images
test: ./test/test/images  # test images (relative to 'path') 128 images

# Classes
nc: 2  # number of classes
names:
  0: vertical
  1: horizontal
  # class names

(3)、设置yolo8n.yaml

这里是设置yolo8n网络的文件,这里只需要修改类别数nc即可,如果选用不同版本的yolov8去找对应的网络配置文件即可。

# Ultralytics YOLO 🚀, GPL-3.0 license

# Parameters
nc: 2  # number of classes
depth_multiple: 0.33  # scales module repeats
width_multiple: 0.25  # scales convolution channels

# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4
  - [-1, 3, C2f, [128, True]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f, [256, True]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f, [1024, True]]
  - [-1, 1, SPPF, [1024, 5]]  # 9

# YOLOv8.0n head
head:
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
  - [-1, 3, C2f, [512]]  # 13

  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
  - [-1, 3, C2f, [256]]  # 17 (P3/8-small)

  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 12], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f, [512]]  # 20 (P4/16-medium)

  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 9], 1, Concat, [1]]  # cat head P5
  - [-1, 3, C2f, [1024]]  # 23 (P5/32-large)

  - [[15, 18, 21], 1, Detect, [nc]]  # Detect(P3, P4, P5)

4、进行训练

完成训练前的工作以后,就可以进行训练工作了,在运行训练工作的时候可以查看下面目录的文件

ultralytics-main/ultralytics/cfg/default.yaml

(1)、训练命令

这里的话,可以根据上面的参数说明进行配置,一般情况下,只改下面的部分就够用了。

yolo task=detect mode=train model=/root/ultralytics-main/datasets/yolo8n.yaml  data=/root/ultralytics-main/datasets/data.yaml epochs=100 batch=64 device=0 single_cls=True pretrained=/root/ultralytics-main/yolov8n.pt

5、预测

 预测的话,是需要等到训练进程完毕以后进行,训练的阶段的权重会保存一个best.pt和last.pt,就是map最好的一个和最后一次训练保存的一个。预测的时候和上面的3(1)的类似,就是替换掉权重和数据图像。

(1)、预测命令

yolo task=detect mode=predict model=runs/detect/train3/weights/best.pt source=data/images/1.jpg device=0

6、结语

至此,整个训练预测阶段完成。如果没有linux系统的话可以上网搜一下租显卡的平台,一般很便宜的。这篇文章仅用于自我学习记录,希望大家共同进步,有问题可以评论区见!

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

相识已是上上签

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值