在实际项目中,我们经常会遇到一些特殊场景,比如工业质检中的零件缺陷检测、医疗影像中的病灶区域识别,这些场景往往无法直接用现成的COCO数据集来训练模型。这时候就需要自己动手构建专属的数据集。
我去年做过一个PCB板缺陷检测的项目,当时最大的挑战就是找不到合适的数据集。市面上的公开数据集要么类别不匹配,要么图像质量达不到要求。最后我们只能自己搭建拍摄环境,采集了3000多张带缺陷的PCB板图像,手动标注了每一处缺陷区域。
自定义数据集的好处很明显:
推荐使用Python 3.8+和PyTorch 1.12+的组合,这个版本组合经过实测最稳定。我的开发环境是这样的:
安装核心依赖包:
bash复制pip install ultralytics torch==1.12.1+cu113 torchvision==0.13.1+cu113 --extra-index-url https://download.pytorch.org/whl/cu113
pip install labelme opencv-python pillow
对于分割任务,我强烈推荐使用LabelMe。相比其他工具,它有这几个优势:
安装方法很简单:
bash复制pip install labelme
labelme # 启动图形界面
采集图像时要注意这几个关键点:
我建议先用手机或普通相机采集原始素材,然后用OpenCV做简单的预处理:
python复制import cv2
def preprocess(image_path):
img = cv2.imread(image_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (640, 640)) # 调整到YOLOv8的默认输入尺寸
return img
标注质量直接影响模型效果,这里分享几个实用技巧:
标注完成后,目录结构应该是这样的:
code复制dataset/
├── images/
│ ├── train/
│ │ ├── img1.jpg
│ │ └── img2.jpg
│ └── val/
│ ├── img3.jpg
│ └── img4.jpg
└── labels/
├── train/
│ ├── img1.json
│ └── img2.json
└── val/
├── img3.json
└── img4.json
YOLOv8-Seg需要特定的txt格式,每个标注文件包含:
转换脚本示例:
python复制import json
import os
from pathlib import Path
def convert_labelme_to_yolo(json_file, output_dir):
with open(json_file) as f:
data = json.load(f)
img_width = data['imageWidth']
img_height = data['imageHeight']
txt_lines = []
for shape in data['shapes']:
label = shape['label']
points = shape['points']
# 归一化处理
normalized_points = []
for x, y in points:
nx = x / img_width
ny = y / img_height
normalized_points.extend([nx, ny])
line = f"{class_map[label]} " + " ".join(map(str, normalized_points))
txt_lines.append(line)
output_path = output_dir / (Path(json_file).stem + '.txt')
with open(output_path, 'w') as f:
f.write("\n".join(txt_lines))
针对小样本数据集,建议使用这些增强方法:
可以用Albumentations库实现:
python复制import albumentations as A
transform = A.Compose([
A.Rotate(limit=15, p=0.5),
A.RandomBrightnessContrast(p=0.2),
A.GaussNoise(var_limit=(10.0, 50.0), p=0.3),
A.HorizontalFlip(p=0.5),
], bbox_params=A.BboxParams(format='yolo'))
data.yaml示例:
yaml复制path: /path/to/dataset
train: images/train
val: images/val
names:
0: defect_type1
1: defect_type2
2: defect_type3
yolov8s-seg.yaml关键参数:
yaml复制nc: 3 # 类别数
scales:
s: [0.33, 0.50, 1024] # 小模型配置
m: [0.67, 0.75, 1024] # 中模型配置
l: [1.00, 1.00, 1024] # 大模型配置
经过多次实验,我总结出这些经验:
启动训练的命令:
python复制from ultralytics import YOLO
model = YOLO('yolov8s-seg.yaml') # 从零开始训练
# 或者
model = YOLO('yolov8s-seg.pt') # 使用预训练权重
results = model.train(
data='data.yaml',
epochs=100,
batch=16,
imgsz=640,
device=0 # 使用GPU
)
重点关注这几个指标:
验证脚本:
python复制metrics = model.val(
data='data.yaml',
split='val',
conf=0.25, # 置信度阈值
iou=0.6 # IOU阈值
)
print(metrics.box.map) # 检测mAP
print(metrics.box.map50) # 检测mAP@0.5
print(metrics.seg.map) # 分割mAP
推理代码示例:
python复制results = model.predict(
source='test.jpg',
conf=0.5,
save=True,
show_labels=True,
show_conf=True
)
# 可视化结果
for result in results:
masks = result.masks # 分割掩码
boxes = result.boxes # 检测框
keypoints = result.keypoints # 关键点(如果有)
在工业项目中使用时,建议将模型导出为ONNX格式:
python复制model.export(format='onnx', dynamic=True, simplify=True)