Loading... ## 1、训练环境配置 为了运行 YOLOv8,首先需要配置适当的环境。这里建议利用 Anaconda 来创建一个虚拟环境,这样有助于隔离和管理项目依赖,避免潜在的版本冲突。 在虚拟环境中安装 PyTorch 框架,并安装 Ultralytics 库,YOLOv8 的核心算法和功能都包含在这个库中。为了方便国内用户快速安装,我们将使用清华大学提供的 Python 软件包索引镜像站。运行以下命令来安装 Ultralytics 库: ```bash pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple ``` ## 2、准备训练数据 在使用 YOLOv8 进行目标检测训练的过程中,采用 YOLO 数据格式通常是常见的选择。为了确保您的自定义数据集能够无缝对接 YOLOv8 的训练流程,接下来,我们将详细介绍如何将您的数据集转换为兼容的 YOLO 格式,确保数据集的结构和注释信息符合 YOLOv8 对输入数据的规范要求。 ### 数据集组织结构 我们数据集被组织在一个名为 `mydata` 的文件夹(名称自定义)中,其目录结构包含了利用标注的 XML 文件和对应的图片,以及为 YOLOv8 训练准备的 TXT 格式标签数据文件: - mydata: - data : 存储训练集、测试集、验证集的文件列表 - images : 存储数据集中的图片,是目标检测模型训练的视觉输入部分 - labels : 存储与图片对应的 YOLO 数据格式的 TXT 标签数据文件 - xml : 存储与图片对应的 XML 标注文件(可选,用来生成 labels 数据) - mask : 存储与图片对应的 MASK 标注文件(可选,用来生成 labels 数据) ### 将标注数据转化为 YOLO 数据格式 YOLO 数据格式是 YOLO 目标检测算法的图像标注格式,其注释文件以 .txt 结尾,包含类别索引和边界框(bounding box)的中心坐标、宽度和高度,这些值都被归一化到 [0,1]。 其文件内容的每一行代表图像中的一个目标,用空格隔开上述五个值(类别索引、x_center、y_center、width、height),如下所示: ``` 0 0.50625 0.37 0.245 0.54 1 0.71625 0.47 0.16 0.24 ``` 对于使用 VOC 数据格式的数据集,标注信息是通过 XML 文件提供的,每个 XML 文件对应一张图片,并且包含了图像中所有目标的具体位置和类别等信息。您可以参考以下代码将 VOC 格式的 XML 文件转换为 YOLO 数据格式的 TXT 标签文件: ```python import os import xml.etree.ElementTree as ET class_mapping = { 'cat': 0, 'dog': 1, } def convert_bbox(size, box): dw = 1. / size[0] dh = 1. / size[1] x = ((box[0] + box[1]) / 2.0) * dw y = ((box[2] + box[3]) / 2.0) * dw w = (box[1] - box[0]) * dh h = (box[3] - box[2]) * dh return (x, y, w, h) def voc2yolo(xml_label_path, yolo_txt_path): os.makedirs(yolo_txt_path, exist_ok=True) for filename in os.listdir(xml_label_path): if filename.endswith('.xml'): filepath = os.path.join(xml_label_path, filename) txt_name = os.path.splitext(filename)[0] + '.txt' txt_path = os.path.join(yolo_txt_path, txt_name) tree = ET.parse(filepath) root = tree.getroot() size = root.find('size') width = int(size.find('width').text) height = int(size.find('height').text) with open(txt_path, 'w') as f: for obj in root.iter('object'): class_name = obj.find('name').text if class_name in class_mapping: class_id = class_mapping[class_name] 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)) bbox = convert_bbox((width, height), b) print(f"Writing bounding box to {txt_path}") f.write(str(class_id) + " " + " ".join([str(a) for a in bbox]) + '\n') src_directory = "/home/detect/datasets/mydata/" images_path = os.path.join(src_directory, 'images') labels_path = os.path.join(src_directory, 'labels') xml_path = os.path.join(src_directory, 'xml') voc2yolo(xml_path, labels_path) ``` 对于图像分割任务的数据集,标注信息将以 png 文件的形式提供,每个 png 文件对应一张图片,包含了图像上的分割掩码(mask)信息,例如目标区域、类别等信息。您可以参考以下代码将 mask 转换为 YOLO 数据格式的 TXT 标签文件: ```python import os import cv2 def mask2yolo(mask_label_path, yolo_txt_path): os.makedirs(yolo_txt_path, exist_ok=True) for filename in os.listdir(mask_label_path): if filename.endswith('.png'): filepath = os.path.join(mask_label_path, filename) txt_name = os.path.splitext(filename)[0] + '.txt' txt_path = os.path.join(yolo_txt_path, txt_name) image = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE) _, thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY) contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) with open(txt_path, 'w') as f: for contour in contours: x, y, width, height = cv2.boundingRect(contour) x_center = (x + width / 2) / image.shape[1] y_center = (y + height / 2) / image.shape[0] width_norm = width / image.shape[1] height_norm = height / image.shape[0] print(f"Writing bounding box to {txt_path}") f.write(f"0 {x_center:.6f} {y_center:.6f} {width_norm:.6f} {height_norm:.6f}\n") src_directory = "/home/detect/datasets/mydata/" images_path = os.path.join(src_directory, 'images') labels_path = os.path.join(src_directory, 'labels') mask_path = os.path.join(src_directory, 'mask') mask2yolo(mask_path, labels_path) ``` ### 创建训练集和验证集 在准备用于YOLO模型训练的数据集时,我们通常需要分别创建包含训练集 (train) 和验证集 (val) 图像路径的文本文件。下面的代码段是自动执行此任务的脚本,它将查找指定图像目录下所有图像路径,然后将这些图像按照比例随机分配到训练集和验证集中,并生成训练集和验证集的划分文件。 ```python import os import random train_ratio = 0.9 image_dir = '/home/detect/datasets/mydata/images' train_txt_path = '/home/detect/datasets/mydata/data/train.txt' val_txt_path = '/home/detect/datasets/mydata/data/val.txt' os.makedirs(os.path.dirname(train_txt_path), exist_ok=True) os.makedirs(os.path.dirname(val_txt_path), exist_ok=True) supported_formats = ('.jpg', '.jpeg', '.png', '.bmp') image_paths = [os.path.abspath(os.path.join(dp, f)) for dp, dn, filenames in os.walk(image_dir) for f in filenames if f.endswith(supported_formats)] random.shuffle(image_paths) split_index = int(train_ratio * len(image_paths)) train_image_paths = image_paths[:split_index] val_image_paths = image_paths[split_index:] with open(train_txt_path, 'w') as file: for image_path in train_image_paths: file.write(f"{image_path}\n") with open(val_txt_path, 'w') as file: for image_path in val_image_paths: file.write(f"{image_path}\n") print(f"Training images have been written to {train_txt_path}, total: {len(train_image_paths)}") print(f"Validation images have been written to {val_txt_path}, total: {len(val_image_paths)}") ``` ## 3、相关配置文件 ### 数据集配置文件 创建包含数据集配置信息的 `.yaml` 文件,它提供了结构化的方法来存储训练集和验证集的划分文件路径,以及分类信息等其他与数据集相关的配置。以下是 `mydata.yaml` 文件的一个示例内容,其中包含 train.txt 和 val.txt 文件路径的条目,以及数据集的分类信息: ```yaml train: /home/detect/datasets/mydata/data/train.txt val: /home/detect/datasets/mydata/data/val.txt nc: 2 names: ['cat', 'dog'] ``` ### YOLO 模型配置文件 在 `ultralytics/cfg/models/v8/` 目录中,您可以找到各种 YOLOv8 模型的配置文件。您可以选择合适的模型配置文件,并根据自己的需求进行调整。 在本教程中,我们将遵循默认配置,因此不需要对其做任何更改。我们将直接使用这些预设参数,以便您能快速地上手并运行模型。 ## 4、YOLO 模型训练 ### 下载预训练权重 如果您的训练服务器能够顺畅访问 GitHub,在训练过程中,系统将会自动下载并载入相应的预训练模型权重进行初始化。 如若不然,则需要手动前往 [Ultralytics Assets](https://github.com/ultralytics/assets/releases) 下载您所需模型的预训练权重文件,并传输到训练服务器指定目录下。 ### 开始模型训练 使用我们自己的数据集进行 YOLOv8n 模型训练,持续 1000 个 epoch。训练设备可以通过设备参数进行指定,默认将自动选择,若GPU不可用,则使用 CPU 作为训练设备,否则将使用第一个可用的 GPU。 === "Python" ```python from ultralytics import YOLO model = YOLO("yolov8n.yaml") # 从 YAML 构建新模型 model = YOLO("yolov8n.pt") # 加载预训练模型权重 model = YOLO("yolov8n.yaml").load("yolov8n.pt") # YAML构建并加载权重 # 模型训练 results = model.train(data="mydata.yaml", epochs=1000, imgsz=640, batch=256) # 使用多 GPU 进行模型训练 results = model.train(data="mydata.yaml", epochs=1000, imgsz=640, batch=256, device=[0, 1]) ``` === "CLI" ```bash # 从 YAML 构建新模型,并开始模型训练 yolo detect train data=mydata.yaml model=yolov8n.yaml epochs=1000 imgsz=640 batch=256 # 加载预训练模型权重,并开始模型训练 yolo detect train data=mydata.yaml model=yolov8n.pt epochs=1000 imgsz=640 batch=256 # YAML构建并加载权重,同时开始模型训练 yolo detect train data=mydata.yaml model=yolov8n.yaml pretrained=yolov8n.pt epochs=1000 imgsz=640 batch=256 # YAML构建并加载权重,同时使用多 GPU 开始模型训练 yolo detect train data=mydata.yaml model=yolov8n.yaml pretrained=yolov8n.pt epochs=1000 imgsz=640 batch=256 device=0,1 ``` YOLOv8 迎来了对 Apple M1 和 M2 芯片的优化支持,允许用户通过 Metal Performance Shaders (MPS) 在这些平台上进行高效的训练。此外,它还支持从中断点恢复训练,并提供了改进的日志记录功能。 有关更多的功能选项和训练参数的详细配置,您可以参阅【[官方训练文档](https://docs.ultralytics.com/modes/train/)】以获取全面的指南和说明 ## 5、YOLO 模型推理 Ultralytics YOLOv8 提供了具有强大功能的预测模式,该模式专为在各种数据源上实现高性能实时推理而设计。 在推理过程中,Ultralytics YOLO 模型会返回 Python Results 对象的列表,或者在传递 `stream=True` 参数时,返回内存高效的 Python Results 对象生成器。官方推理示例代码如下: ```python from ultralytics import YOLO # Load a pretrained YOLOv8n model model = YOLO("yolov8n.pt") ''' Run batched inference on a list of images''' # return a list of Results objects results = model(["im1.jpg", "im2.jpg"]) # # return a generator of Results objects # results = model(["im1.jpg", "im2.jpg"], stream=True) for result in results: boxes = result.boxes # Boxes object for bounding box outputs masks = result.masks # Masks object for segmentation masks outputs keypoints = result.keypoints # Keypoints object for pose outputs probs = result.probs # Probs object for classification outputs obb = result.obb # Oriented boxes object for OBB outputs result.show() result.save(filename="result.jpg") ``` 此外,您还可以详细处理得到的 bounding box 输出信息。以下是简单的示例代码: ```python detect_output = {"boxes": [], "scores": [], "classes": [], "names": [], "masks": []} for result in results: detect_output["boxes"].append(result.boxes.xyxy.cpu()) detect_output["scores"].append(result.boxes.conf.cpu()) names = self.model.names classes = result.boxes.cls.cpu().numpy().astype(int) class_names = [names[c] for c in classes] detect_output["classes"].extend(classes) detect_output["names"].extend(class_names) if result.masks is not None: detect_output["masks"].extend(result.masks.numpy()) ``` 有关更多关于模型推理输入支持和结果对象的详细参数信息,请参阅【[官方预测文档](https://docs.ultralytics.com/modes/predict/)】以获取全面的指南和说明。 Last modification:September 4, 2024 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 如果觉得我的文章对你有用,请随意赞赏