当前位置: 首页 > article >正文

YOLO入门教程(三)——训练自己YOLO11实例分割模型并预测【含教程源码+一键分类数据集 + 故障排查】

目录

  • 引言
  • 前期准备
  • Step0 环境部署
    • 1.安装OpenCV
    • 2.安装Pytorch
    • 3.安装Ultralytics
  • Step1 打标训练
  • Step2 格式转换
  • Step3 整理训练集
  • Step4 训练数据集
    • 4.1创建yaml文件
    • 4.2训练
    • 4.3预测
    • 4.4故障排查
      • 4.4.1OpenCV版本故障,把OpenCV版本升级到4.0以上
      • 4.4.2NumPy版本故障,把NumPy降低版本到1.26.4
      • 4.4.3没有安装ultralytics模块
      • 4.4.4Arial.ttf下载超时
      • 4.4.5‘torchvision::nms‘
      • 4.4.6其他报错
  • 参考博客

引言

YOLO(You Only Look Once)作为一个目标检测算法,支持训练和预测实例分割模型,其标注要求是点集合和txt文件,本文教程主要介绍如何训练自己的YOLO模型,LabelMe点集标注的标签如何训练。

前期准备

在开始前建议先下载YOLO11训练源码,安装Anaconda,VSCode,LabelMe并配置好Python环境,OpenCV3.10环境,PyTorch即可开始训练自己的数据集。

Step0 环境部署

已经配置好了的可以跳过

1.安装OpenCV

下载所需版本的OpenCV包,将安装好的.whl文件拷贝到.\Anaconda3\Lib\site-packages文件夹中,并将原来的OpenCV卸载
pip uninstall opencv-python
pip uninstall opencv-contrib-python
cd .\Anaconda3\Lib\site-packages
pip install msgpack-python
pip install msgpack
pip install x.whl

2.安装Pytorch

根据CUDA版本和onnx版本选择pytorch套件

pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

3.安装Ultralytics

必须要先安装CUDA版本的pytorch套件再安装YOLO环境

pip install ultralytics

Step1 打标训练

使用LabelMe软件进行打标签,会在原图路径下生成.json标签文件。
在这里插入图片描述

实例分割需要尽可能多点包围缺陷如下所示

在这里插入图片描述

Step2 格式转换

LabelMe生成的.json标签文件格式不适用于YOLO训练,需要转换格式为.txt标签文件,利用以下代码将.json标签文件归一化为YOLO可直接训练的.txt标签文件。

import json
import os
 
class_name =  ['background','dot','line','worn']
json_dir = './source/json'
labels_dir = './source/labels'

def labelme2yolo_seg(class_name, json_dir, labels_dir):
    """
        此函数用来将labelme软件标注好的json格式转换为yolov_seg中使用的txt格式
        :param json_dir: labelme标注好的*.json文件所在文件夹
        :param labels_dir: 转换好后的*.txt保存文件夹
        :param class_name: 数据集中的类别标签
        :return:
    """
    list_labels = []  # 存放json文件的列表
 
    # 0.创建保存转换结果的文件夹
    if (not os.path.exists(labels_dir)):
        os.mkdir(labels_dir)
 
    # 1.获取目录下所有的labelme标注好的Json文件,存入列表中
    for files in os.listdir(json_dir):  # 遍历json文件夹下的所有json文件
        file = os.path.join(json_dir, files)  # 获取一个json文件
        list_labels.append(file)  # 将json文件名加入到列表中
 
    for labels in list_labels:  # 遍历所有json文件la
        with open(labels, "r") as f:
            file_in = json.load(f)
            shapes = file_in["shapes"]
            print(labels)
 
        txt_filename = os.path.basename(labels).replace(".json", ".txt")
        txt_path = os.path.join(labels_dir, txt_filename)  # 使用labels_dir变量指定保存路径
 
        with open(txt_path, "w+") as file_handle:
            for shape in shapes:
                line_content = []  # 初始化一个空列表来存储每个形状的坐标信息
                line_content.append(str(class_name.index(shape['label'])))  # 添加类别索引
                # 添加坐标信息
                for point in shape["points"]:
                    x = point[0] / file_in["imageWidth"]
                    y = point[1] / file_in["imageHeight"]
                    line_content.append(str(x))
                    line_content.append(str(y))
                # 使用空格连接列表中的所有元素,并写入文件
                file_handle.write(" ".join(line_content) + "\n")


if __name__ == '__main__':
    labelme2yolo_seg(class_name, json_dir, labels_dir)

json_dir替换成标签所在路径
labels_dir替换成新标签所在路径
class_name替换成标签

以上代码将Json标签转换为Txt多点标签用于实例分割训练

备注:转换后查看txt是否包含多点信息如下图所示
在这里插入图片描述

Step3 整理训练集

YOLO有数据集要求放置的格式要求,具体要求如下:

dataset/
├── train/
│ ├── images/
│ └── labels/
└── val/
├── images/
└── labels/

利用以下代码将快速将训练集整理好,划分为训练集和验证集:

import random
import shutil
import os
import shutil

#通过相对路径索引到数据集
source_floder_path = './source'
# 图片目标路径
images_folder = source_floder_path + '/images'
# 定义图片尾缀
image_suffix = ['.jpg']

# 标签目标路径
labels_folder = source_floder_path + '/labels'
# 定义标签尾缀
label_suffix = ['.txt']

def CollateDataset(image_dir,label_dir):  # image_dir:图片路径  label_dir:标签路径
    # 创建一个空列表来存储有效图片的路径
    valid_images = []
    # 创建一个空列表来存储有效 label 的路径
    valid_labels = []
    # 遍历 images 文件夹下的所有图片
    for image_name in os.listdir(image_dir):
        # 获取图片的完整路径
        image_path = os.path.join(image_dir, image_name)
        # 获取图片文件的扩展名
        ext = os.path.splitext(image_name)[-1]
        # 根据扩展名替换成对应的 label 文件名
        label_name = image_name.replace(ext, ".txt")
        # 获取对应 label 的完整路径
        label_path = os.path.join(label_dir, label_name)
        # 判断 label 是否存在
        if not os.path.exists(label_path):
            # # 删除图片
            # os.remove(image_path)
            print("there is no:", label_path)
        else:
            # 将图片路径添加到列表中
            valid_images.append(image_path)
            # 将 label 路径添加到列表中
            valid_labels.append(label_path)
    # 遍历每个有效图片路径
    for i in range(len(valid_images)):
        image_path = valid_images[i]
        label_path = valid_labels[i]
        # 随机生成一个概率
        r = random.random()
        # 判断图片应该移动到哪个文件夹
        # train:valid:test = 8:2:0
        if r < 0.0:
            # 移动到 test 文件夹
            destination = "./datasets/test"
        elif r < 0.1:
            # 移动到 valid 文件夹
            destination = "./datasets/valid"
        else:
            # 移动到 train 文件夹
            destination = "./datasets/train"
        # 创建目标文件夹中 images 和 labels 子文件夹
        os.makedirs(os.path.join(destination, "images"), exist_ok=True)
        os.makedirs(os.path.join(destination, "labels"), exist_ok=True)
        # 生成目标文件夹中图片的新路径
        image_destination_path = os.path.join(destination, "images", os.path.basename(image_path))
        # 移动图片到目标文件夹
        shutil.copy(image_path, image_destination_path)
        # 生成目标文件夹中 label 的新路径
        label_destination_path = os.path.join(destination, "labels", os.path.basename(label_path))
        # 移动 label 到目标文件夹
        shutil.copy(label_path, label_destination_path)

def CopyImagesAndLabels(path):
    # 遍历源文件夹中的文件
    for filename in os.listdir(path):
        print(f"FileName is {filename}")
        # 将路径分隔符从 '\\' 替换为 '/'
        filename = filename.replace('\\', '/')
        # 检查文件是否为图片的后缀结尾
        for suffix in image_suffix:
            #图片移动到图片路径
            if filename.endswith(suffix):
                    # 拼接路径字符串
                    source_file = os.path.normpath(os.path.join(os.getcwd(), path, filename))
                    dest_file = os.path.normpath(os.path.join(os.getcwd(), images_folder, filename))

                    # 复制文件
                    if os.path.exists(source_file):
                        try:
                            # 复制文件
                             # 确保目标文件夹存在,递归创建目录
                            os.makedirs(os.path.dirname(dest_file), exist_ok=True)
                            print(f"Copying Image {source_file} to {dest_file}")
                            shutil.copy(source_file, dest_file)
                        except Exception as e:
                            print(f"Error: {e}") 
                            
        # 检查文件是否为标签的后缀结尾
        for suffix in label_suffix:
            #图片移动到图片路径
            if filename.endswith(suffix):
                    # 拼接路径字符串
                    source_file = os.path.normpath(os.path.join(os.getcwd(), path, filename))
                    dest_file = os.path.normpath(os.path.join(os.getcwd(), labels_folder, filename))

                    # 复制文件
                    print(f"Copy Label {source_file} to {dest_file}")
                    if os.path.exists(source_file):
                        try:
                            # 复制文件
                             # 确保目标文件夹存在,递归创建目录
                            os.makedirs(os.path.dirname(dest_file), exist_ok=True)
                            print(f"Copying Label {source_file} to {dest_file}")
                            shutil.copy(source_file, dest_file)
                            print("File copied successfully!")
                        except Exception as e:
                            print(f"Error: {e}")

    # 拷贝完成
    print("File copied successfully!")

if __name__ == '__main__':
    # 整理训练集
    CopyImagesAndLabels(source_floder_path)
    CollateDataset(images_folder, labels_folder)

source_floder_path替换成数据集所在路径
images_folder和labels_folder为图片集和标记集所在路径
image_suffix和label_suffix为图片集和标签集的尾缀
destination为最终训练集和验证集所在路径

以上代码只复制png和txt尾缀的数据集

备注:转换后可以在本地路径上检查是否整理成功

Step4 训练数据集

4.1创建yaml文件

在这里插入图片描述

Train/val替换成数据集所在绝对路径
Classes为标签数量与名称

4.2训练

# coding:utf-8
from ultralytics import YOLO
import torch
import cv2
import os

# 模型配置文件
model_yaml_path = "./yolo11-main/ultralytics/cfg/models/11/yolo11-seg.yaml"
# 数据集配置文件
data_yaml_path = os.path.normpath(os.path.join(os.getcwd(), './yolo11-main/ultralytics/cfg/datasets/mytrain.yaml'))
# 预训练模型
pre_model_name = os.path.normpath(os.path.join(os.getcwd(), './yolo11-main/weights/yolo11s-seg.pt'))
# 模型保存路径
save_model_name = os.path.normpath(os.path.join(os.getcwd(), './yolo11-main/runs/detect/mytrain_1120'))

if __name__ == '__main__':
    print(torch.__version__)  #注意,这里也是两个下划线
    print(cv2.__version__)
    # 加载预训练模型
    model = YOLO(model_yaml_path).load(pre_model_name)
    # 使用预训练权重结果更高 但是如果要论文的话建议不要用预训练权重
    # 不加载预训练模型
    # model = YOLOv(model_yaml_path)

    # 训练模型
    results = model.train(data=data_yaml_path, epochs=500, batch=8, name=save_model_name, imgsz=640, device='cuda:0')

data_yaml_path替换成4.1步骤下yaml的名称与路径
pre_model_name为预训练模型区别如下图

以下表格列出了训练参数解析参数及其参考含义
参数类型默认值说明
–datastrROOT/“data/coco128.yaml”数据集配置文件路径
–epochsint500训练总轮数
–batchint8所有 GPU 上的总批量大小,-1 表示自动批量大小

task:选择任务类型,可选[‘detect’, ‘segment’, ‘classify’, ‘init’]
mode: 选择是训练、验证还是预测的任务类型 可选[‘train’, ‘val’, ‘predict’]
model: 选择yolov8不同的模型配置文件,可选yolov8s.yaml、yolov8m.yaml、yolov8l.yaml、yolov8x.yaml
data: 选择生成的数据集配置文件
epochs:指的就是训练过程中整个数据集将被迭代多少次,显卡不行你就调小点。
batch:一次看完多少张图片才进行权重更新,梯度下降的mini-batch,显卡不行你就调小点。

4.3预测

from ultralytics import YOLO

# Load a pretrained YOLOv10n model
# model = YOLOv10("runs/detect/train_v10/weights/best.pt")
model = YOLO("./yolo11-main/runs/detect/mytrain_1120/weights/best.pt")

# Perform object detection on an image
# results = model("test1.jpg")
# results = model.predict("ultralytics/assets/bus.jpg")
results = model.predict("./source/images/8.jpg")

# Display the results
results[0].show()
以下是预测的结果

在这里插入图片描述

4.4故障排查

4.4.1OpenCV版本故障,把OpenCV版本升级到4.0以上

ModuleNotFoundError: No module named ‘cv2’

下载所需版本的OpenCV包,将安装好的.whl文件拷贝到.\Anaconda3\Lib\site-packages文件夹中,并将原来的OpenCV卸载
pip uninstall opencv-python
pip uninstall opencv-contrib-python
cd .\Anaconda3\Lib\site-packages
pip install msgpack-python
pip install msgpack
pip install x.whl

出现引用cv循环情况则重装opencv-contrib-python

备注:版本cp后的数字代表了适配Python的版本。如果你的Python版本是3.9.11请务必选择cp39,其它依此类推。对于我们Windows64位系统,应当选择win_amd64系列。

4.4.2NumPy版本故障,把NumPy降低版本到1.26.4

A module that was compiled using NumPy 1.x cannot be run in NumPy 2.0.1 as it may crash. To support both 1.x and 2.x versions of NumPy, modules must be compiled with NumPy 2.0. Some module may need to rebuild instead e.g. with ‘pybind11>=2.12’.

pip uninstall numpy
pip install numpy==1.26.4

4.4.3没有安装ultralytics模块

New https://pypi.org/project/ultralytics/8.2.66 available 😃 Update with ‘pip install -U ultralytics’

pip install -U ultralytics

4.4.4Arial.ttf下载超时

解决yolov5环境配置报错Arial.ttf下载超时Downloading

4.4.5‘torchvision::nms‘

【问题解决】NotImplementedError: Could not run ‘torchvision::nms‘ with arguments from the ‘CUDA‘ backend
之前先执行pip install ultralytics指令再安装CUDA版本的pytorch套件

要先安装pytorch再安装yolo环境

4.4.6其他报错

其他报错可以搜索或者在YOLO官方常见问题文档中查找

参考博客

1.深度学习之目标检测从入门到精通——json转yolo格式
2.模型训练篇 | yolov10来了!手把手教你如何用yolov10训练自己的数据集(含网络结构 + 模型训练 + 模型推理等)
3.在win10下安装Anaconda环境并配置OpenCV
4.ModuleNotFoundError: No module named ‘torch‘ 解决方案
5.Labelme与YOLO标签格式互转,含实例分割和目标检测,轻松实现数据扩充


http://www.kler.cn/a/403707.html

相关文章:

  • 《Vue零基础入门教程》第四课: 应用实例
  • 数据库类型介绍
  • 深入解析生成对抗网络(GAN)
  • Java实现简单的搜索引擎
  • css水平居中+垂直居中
  • 【Nginx从入门到精通】05-安装部署-虚拟机不能上网简单排错
  • 通义千问综合代码能力测试:制作web版五子棋
  • MFC线程管理类
  • Python设计模式详解之4 —— 建造者模式
  • 【Anomaly Detection论文阅读记录】PaDiM与PatchCore模型的区别与联系
  • 内网渗透-隧道判断-SSH-DNS-icmp-smb-上线linux-mac
  • 网络安全问题概述
  • 三十一、构建完善微服务——API 网关
  • 初始Python篇(4)—— 元组、字典
  • 查找萤石云IOS Sdk中的编解码接口
  • 基于Lora通讯加STM32空气质量检测WIFI通讯-分享
  • Mistral 发布开源多模态模型 Pixtral Large,聊天助手 Le Chat 全面对标 ChatGPT
  • Palo Alto Networks PAN-OS身份认证绕过漏洞复现(CVE-2024-0012)
  • IM项目-----客户端部分未读消息实现
  • 修改仓库中子模块并推送到远程仓库的指定分支
  • 【Android踩过的坑】14.小米系统TTS无法生效的问题
  • 深入分析:固定参考框架在RViz中的作用与对数据可视化的影响 ros ubuntu20.04
  • 《Django 5 By Example》阅读笔记:p211-p236
  • Python什么事迭代器?
  • 游戏开发实现简易实用的ui框架
  • Jenkins更换主题颜色+登录页面LOGO图片