摘要:在本教程中,我们将详细介绍如何使用自定义数据集训练YOLOv8模型,并用Python代码评估模型性能。
正文:
一、准备自定义数据集
为了训练YOLOv8模型,我们需要一个标注好的自定义数据集。数据集应包含图像文件和对应的标注文件,标注文件中包含目标类别和边界框信息。以下是准备自定义数据集的步骤:
编写这些辅助函数后,您可以使用evaluate_model
函数评估YOLOv8模型在自定义数据集上的性能。根据评估结果,您可以进一步优化模型配置和训练参数,以提高模型性能。
create_y_true(true_labels, true_boxes, class_id)
:根据真实标签和边界框创建二进制标签向量。
create_y_pred(pred_labels, pred_boxes, pred_scores, class_id)
:根据预测标签、边界框和置信度分数创建预测向量。
-
收集图像:收集适用于您的任务的图像。图像数量越多,模型的泛化能力越强。确保图像具有多样性,以便模型能在各种场景下表现良好。
-
图像标注:使用标注工具(如labelImg)为图像中的目标创建边界框,并指定类别。将标注结果保存为XML或TXT格式。
-
划分数据集:将数据集划分为训练集、验证集和测试集。比例可以根据实际情况调整,通常可以采用80%的训练集,10%的验证集和10%的测试集。
-
转换标注格式:将标注文件转换为YOLOv8所需的格式。YOLOv8要求每个图像的标注信息存储在一个与图像同名的TXT文件中,每行包含一个目标的类别ID、中心点坐标(x,y)和宽高(w,h),数值归一化到0-1范围。可以编写Python脚本进行转换,如:
python">import os import xml.etree.ElementTree as ET def convert_annotation(input_path, output_path, class_names): tree = ET.parse(input_path) root = tree.getroot() size = root.find('size') width = int(size.find('width').text) height = int(size.find('height').text) with open(output_path, 'w') as f: for obj in root.iter('object'): class_name = obj.find('name').text class_id = class_names.index(class_name) bbox = obj.find('bndbox') x_min = int(bbox.find('xmin').text) y_min = int(bbox.find('ymin').text) x_max = int(bbox.find('xmax').text) y_max = int(bbox.find('ymax').text) x_center = (x_min + x_max) / 2.0 / width y_center = (y_min + y_max) / 2.0 / height w = (x_max - x_min) / width h = (y_max - y_min) / height f.write(f"{class_id} {x_center} {y_center} {w} {h}\n")
骤如下:
-
下载YOLOv8源代码:从YOLOv8官方仓库下载源代码,并按照说明安装依赖库。
-
修改配置文件:在
cfg
文件夹中复制一个现有的YOLOv8配置文件(如yolov8.cfg
),并根据自定义数据集进行修改。主要需要修改的部分包括:类别数(classes
)、锚框数(num
)、过滤器数(filters
)等。同时,请注意修改网络输入尺寸以适应您的数据集。 -
准备数据文件:创建一个包含训练集图像路径的文本文件(如
train.txt
),以及一个包含验证集图像路径的文本文件(如valid.txt
)。确保图像路径与标注文件路径一致。 -
修改数据配置文件:复制
data
文件夹中的coco.data
文件,将其重命名为custom.data
。修改custom.data
,以包含自定义数据集的类别数、类别名文件路径、训练集文件路径和验证集文件路径。 -
下载预训练权重:从YOLOv8官方仓库下载适用于您的YOLOv8配置的预训练权重文件(如
yolov8.conv.137
)。 -
开始训练:使用以下命令开始训练YOLOv8模型:
python">./darknet detector train path/to/custom.data path/to/your_yolov8.cfg path/to/yolov8.conv.137 -dont_show -map
训练过程中,模型的权重将定期保存到
backup
文件夹。当训练完成时,您可以选择最佳权重文件作为自定义YOLOv8模型。三、评估YOLOv8模型性能
要使用Python代码评估YOLOv8模型性能,我们可以使用mAP(mean Average Precision)指标。可以参考以下步骤:
-
导入依赖库:
python">import cv2 import numpy as np from sklearn.metrics import average_precision_score
编写评估函数:
python">def evaluate_model(test_image_paths, test_annotation_paths, model_config, model_weights, class_names, confidence_threshold=0.5): net = cv2.dnn.readNetFromDarknet(model_config, model_weights) layer_names = net.getLayerNames() output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()] input_size = (416, 416) scale_factor = 1 / 255.0 ap_scores = [] for image_path, annotation_path in zip(test_image_paths, test_annotation_paths): frame = cv2.imread(image_path) blob = cv2.dnn.blobFromImage(frame, scale_factor, input_size, swapRB=True, crop=False) net.setInput(blob) detections = net.forward(output_layers) true_labels, true_boxes = read_annotation(annotation_path) pred_labels, pred_boxes, pred_scores = process_detections(detections, frame, confidence_threshold) for class_id in range(len(class_names)): y_true = create_y_true(true_labels, true_boxes, class_id) y_pred = create_y_pred(pred_labels, pred_boxes, pred_scores, class_id) ap = average_precision_score(y_true, y_pred) ap_scores.append(ap) map_score = np.mean(ap_scores) return map_score
在这个函数中,我们首先加载YOLOv8模型及其权重。接着,针对测试集中的每张图像,我们执行目标检测并处理检测结果。随后,我们根据每个类别计算平均精度(AP),并计算mAP作为最终评估结果。
为了计算AP,我们需要实现以下辅助函数:
-
read_annotation(annotation_path)
:从标注文件中读取真实边界框和对应的类别标签。 -
process_detections(detections, frame, confidence_threshold)
:从检测结果中提取预测边界框、类别标签和置信度分数。
编写这些辅助函数后,您可以使用evaluate_model
函数评估YOLOv8模型在自定义数据集上的性能。根据评估结果,您可以进一步优化模型配置和训练参数,以提高模型性能。
在上述评估函数中,我们需要补充实现以下辅助函数,以便正确计算mAP。
详细
YOLOv8目标检测:自定义数据集训练与评估
- 读取标注文件:
python">def read_annotation(annotation_path): with open(annotation_path, "r") as f: lines = f.readlines() true_labels = [] true_boxes = [] for line in lines: data = line.strip().split() label = int(data[0]) box = [float(x) for x in data[1:]] true_labels.append(label) true_boxes.append(box) return true_labels, true_boxes
- 处理检测结果:
python">def process_detections(detections, frame, confidence_threshold): height, width, _ = frame.shape pred_labels = [] pred_boxes = [] pred_scores = [] for detection in detections: scores = detection[5:] class_id = np.argmax(scores) confidence = scores[class_id] if confidence > confidence_threshold: x_center, y_center, w, h = detection[:4] * np.array([width, height, width, height]) x_min = int(x_center - w / 2) y_min = int(y_center - h / 2) x_max = int(x_center + w / 2) y_max = int(y_center + h / 2) pred_labels.append(class_id) pred_boxes.append([x_min, y_min, x_max, y_max]) pred_scores.append(confidence) return pred_labels, pred_boxes, pred_scores
- 创建二进制标签向量:
python">def create_y_true(true_labels, true_boxes, class_id): y_true = [] for label, box in zip(true_labels, true_boxes): if label == class_id: y_true.append(box) else: y_true.append([0, 0, 0, 0]) return y_true
- 创建预测向量:
python">def create_y_pred(pred_labels, pred_boxes, pred_scores, class_id): y_pred = [] for label, box, score in zip(pred_labels, pred_boxes, pred_scores): if label == class_id: y_pred.append(np.concatenate((box, [score]))) else: y_pred.append([0, 0, 0, 0, 0]) return y_pred
现在我们已经补充了上述辅助函数,可以顺利地使用
evaluate_model
函数来评估YOLOv8模型在自定义数据集上的性能。在进行评估时,请确保您已经正确地设置了测试集图像路径和标注文件路径。通过不断优化模型配置和训练参数,您可以提高YOLOv8模型在自定义数据集上的性能。在实际应用中,您还可以使用训练好的模型进行实时目标检测。
更多内容及优化:YOLOv8目标检测:自定义数据集训练与评估