YOLOv8简洁地训练自己的数据集

一.虚拟环境

1.使用Anaconda创建虚拟环境

打开Anaconda prompt,输入

conda create -n your_env_name python=3.9 #your_env_name为你想创建的环境名。
#python=3.9为你想要的python版本,例如可以python=3.8等

2.进入虚拟环境中

使用命令

activate your_env_name

注:base为你的基础环境,我预先创建了一个叫做pytorch的虚拟环境,使用activate pytroch即可进入

二.环境配置

YOLOv8的公司已经将yolov8的源码集成到了包中,我们只需ultralytics安装包便可

pip install ultralytics

建议安装环境时python版本>=3.8比较合适,同时需要安装pytorch版本>=1.7

若是没有安装pytorch,参考这篇文章https://blog.csdn.net/qq_38140292/article/details/114157146#:~:text=%E4%BA%94%E3%80%81%E5%AE%89%E8%A3%85pytorch%201%E3%80%81%E6%89%93%E5%BC%80PyCharm%EF%BC%8C%E8%BF%9B%E5%85%A5%E5%88%9A%E5%88%9A%E5%88%9B%E5%BB%BA%E7%9A%84%E5%B7%A5%E7%A8%8B%E9%87%8C%EF%BC%8C%E6%89%93%E5%BC%80Terminal%E7%AA%97%E5%8F%A3%EF%BC%9A,2%E3%80%81%E5%9C%A8PyCharm%E7%9A%84Terminal%E7%AA%97%E5%8F%A3%E4%B8%AD%E9%94%AE%E5%85%A5cd%20%E5%91%BD%E4%BB%A4%EF%BC%8C%E5%88%87%E6%8D%A2%E7%9B%AE%E5%BD%95%E5%88%B0PyTorch%E5%AE%89%E8%A3%85%E5%8C%85%E6%89%80%E5%9C%A8%E7%9A%84%E5%9C%B0%E5%9D%80%EF%BC%8C%E7%84%B6%E5%90%8E%E5%88%86%E5%88%AB%E6%89%A7%E8%A1%8Cpip%20install%E5%91%BD%E4%BB%A4%E5%AE%89%E8%A3%85%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6%EF%BC%8C%E5%85%88%E5%AE%89%E8%A3%85torch%EF%BC%8C%E5%86%8D%E5%AE%89%E8%A3%85torchvision%EF%BC%8C%E6%9C%9F%E9%97%B4%E4%BC%9A%E4%B8%80%E8%B5%B7%E4%B8%8B%E8%BD%BD%E6%89%80%E9%9C%80%E8%A6%81%E7%9A%84%E4%BE%9D%E8%B5%96%E5%8C%85

三.数据集

1.数据集来源

我的数据集来自于极客https://www.cvmart.net/dataSets/detail/449?utm_campaign=zywang

该数据集包含 12,500 张带有细胞类型标签 (CSV) 的增强血细胞图像 (JPEG)。4 种不同细胞类型中的每一种都有大约 3,000 张图像,这些图像被分组到 4 个不同的文件夹中(根据细胞类型)。细胞类型是嗜酸性粒细胞、淋巴细胞、单核细胞和中性粒细胞。该数据集附带一个额外的数据集,其中包含原始 410 幅图像(预增强)以及两个额外的子类型标签(WBC 与 WBC),以及这 410 幅图像中每个单元格的边界框(JPEG + XML 元数据)。更具体地说,“dadataset-master”文件夹包含 410 张带有子类型标签和边界框(JPEG + XML)的血细胞图像,而“dataset2-master”文件夹包含 2,500 个增强图像以及 4 个额外的子类型标签(JPEG + CSV)。

其中dadataset-master文件夹是我们需要的yolov8任务的数据集

2.数据集处理

我的原数据集为两个文件,其中Annotations为xml文件为label文件,JEPGImages为图片文件

由于训练yolov8模型时xml格式文件并不支持训练,所以要先将xml数据集改为yolo格式的数据集,用一个xml转yolo脚本即可

import os
import xml.etree.ElementTree as ET

def convert_voc_to_yolo(xml_path, classes, output_folder):
    tree = ET.parse(xml_path)
    root = tree.getroot()

    image_filename = root.find('filename').text
    image_width = float(root.find('size/width').text)
    image_height = float(root.find('size/height').text)

    yolo_lines = []

    for obj in root.findall('object'):
        class_name = obj.find('name').text
        class_index = classes.index(class_name)
        bbox = obj.find('bndbox')
        xmin = float(bbox.find('xmin').text)
        ymin = float(bbox.find('ymin').text)
        xmax = float(bbox.find('xmax').text)
        ymax = float(bbox.find('ymax').text)

        # 计算中心坐标和宽度/高度的相对值
        x_center = (xmin + xmax) / (2.0 * image_width)
        y_center = (ymin + ymax) / (2.0 * image_height)
        width = (xmax - xmin) / image_width
        height = (ymax - ymin) / image_height

        # 将信息格式化为 YOLO 格式的一行文本
        yolo_line = f"{class_index} {x_center} {y_center} {width} {height}"
        yolo_lines.append(yolo_line)

    # 将 YOLO 格式的信息写入文本文件
    yolo_file_path = os.path.join(output_folder, os.path.splitext(image_filename)[0] + '.txt')
    with open(yolo_file_path, 'w') as yolo_file:
        for line in yolo_lines:
            yolo_file.write(line + '\n')

def convert_folder_to_yolo(xml_folder, classes, output_folder):
    os.makedirs(output_folder, exist_ok=True)

    for xml_file in os.listdir(xml_folder):
        if xml_file.endswith('.xml'):
            xml_path = os.path.join(xml_folder, xml_file)
            convert_voc_to_yolo(xml_path, classes, output_folder)

# Example usage:
xml_folder_path = 'D:/Allpythonproject/cv-haut/Blood/archive (1)/dataset-master/dataset-master/Annotations'
output_folder_path = 'D:/Allpythonproject/cv-haut/Blood/archive (1)/dataset-master/dataset-master/output'
class_names = ["RBC"]

convert_folder_to_yolo(xml_folder_path, class_names, output_folder_path)

其中xml_folder_path为你xml格式数据集的地址,out_folder_path为你输出yolo格式存入的地址,class_names为你的类别数,在我的数据集中只标注了一个叫RBC的标注。你可以根据你的类别数进行修改

在进行划分后我们要对训练集进行划分,其中图片和标签要一一对应

import os
import random
import shutil

def split_and_clean_dataset(images_folder, labels_folder, output_folder, split_ratio=0.8):
    os.makedirs(output_folder, exist_ok=True)

    # 创建主文件夹
    output_images_folder = os.path.join(output_folder, 'images')
    output_labels_folder = os.path.join(output_folder, 'labels')
    os.makedirs(output_images_folder, exist_ok=True)
    os.makedirs(output_labels_folder, exist_ok=True)

    # 获取所有图像文件名
    image_files = [f for f in os.listdir(images_folder) if f.endswith('.jpg')]
    random.shuffle(image_files)

    # 划分训练集和验证集
    split_index = int(split_ratio * len(image_files))
    train_files = image_files[:split_index]
    val_files = image_files[split_index:]

    # 创建训练集和验证集的子文件夹
    train_images_folder = os.path.join(output_images_folder, 'train')
    val_images_folder = os.path.join(output_images_folder, 'val')
    train_labels_folder = os.path.join(output_labels_folder, 'train')
    val_labels_folder = os.path.join(output_labels_folder, 'val')
    os.makedirs(train_images_folder, exist_ok=True)
    os.makedirs(val_images_folder, exist_ok=True)
    os.makedirs(train_labels_folder, exist_ok=True)
    os.makedirs(val_labels_folder, exist_ok=True)

    # 复制图像和标签到相应的文件夹,并检查匹配性
    for file_name in train_files:
        image_path = os.path.join(images_folder, file_name)
        label_name = file_name.replace('.jpg', '.txt')
        label_path = os.path.join(labels_folder, label_name)

        if os.path.exists(label_path):
            shutil.copy(image_path, train_images_folder)
            shutil.copy(label_path, train_labels_folder)
        else:
            print(f"Warning: Label not found for {file_name}. Skipping.")

    for file_name in val_files:
        image_path = os.path.join(images_folder, file_name)
        label_name = file_name.replace('.jpg', '.txt')
        label_path = os.path.join(labels_folder, label_name)

        if os.path.exists(label_path):
            shutil.copy(image_path, val_images_folder)
            shutil.copy(label_path, val_labels_folder)
        else:
            print(f"Warning: Label not found for {file_name}. Skipping.")

# 用法示例:
images_folder_path = 'JPEGImages/'
labels_folder_path = 'output/'
output_folder_path = 'Formost'

split_and_clean_dataset(images_folder_path, labels_folder_path, output_folder_path)

其中images_folder_path为你存放图像的路径,labels_folder_path为你上一步保存yolo格式的路径,output_folder_path为你最终要存放最终数据集的文件夹,在运行之前我已经创建好了一个名叫Formost的文件夹。

最终训练集结构如下

——————-Formost
————images
——train
——val
————labels
——train
——val

其中Formost为主文件夹,主文件夹下有两个次文件夹images和labels,这两个文件夹下又有两个文件夹train和val分别存放训练集和验证集

四.训练模型

1.创建yaml文件

yolov8命令行中“data”参数可以指定yaml文件,故需创建一个包含类别数和数据集路径的yaml文件

train: "D:/Allpythonproject/cv-haut/Blood/archive (1)/dataset-master/dataset-master/Formost/images/train"
val: "D:/Allpythonproject/cv-haut/Blood/archive (1)/dataset-master/dataset-master/Formost/images/val"
nc: 1
names:
  0: EOSINOPHIL

其中train和val要换成你第二步数据集处理后图片的训练集和验证集的绝对路径。nc为你的类别数跟你原本xml文件中的类别数保持一致,像我的类别数就只有一类即可填1。names你可以为你要检测的类别物命名,在此我的类别数为EOSINOPHIL,则在预测时预测的名字就叫做EOSINOPHIL

我的yaml文件存放在了与数据集同等的目录下,v8.yaml为我创建的yaml文件

2.使用命令行训练模型

打开pycharm中的terminal或者cmd都可以,使用cd命令切换到你存放yaml文件的地方输入

yolo task=detect mode=train model=yolov8n.pt data=v8.yaml batch=16 epochs=20 imgsz=640 workers=16 device=0

其中data参数为你创建的yaml文件,model为你的预训练模型,有5种预训练模型可供你选择,若想深入了解可以看这篇博客https://blog.csdn.net/qq_37553692/article/details/130898732

五.训练完毕

训练完之后,yolov8会在你主目录下创建一个叫做runs的文件夹,runs文件夹会有以下文件

weights文件夹里为你训练的模型参数,至此,训练完毕

  • 22
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值