简介
当你完成了 Label Studio 的标注工作,点击“导出”时,你会发现导出的文件结构并不能直接用于 YOLOv8 训练。
YOLO 模型对数据集有严格的要求:训练/验证集必须物理隔离,且必须包含 data.yaml 配置文件。
手动整理几千张图片不仅耗时,还容易出错(比如把猫的标签对应到了狗的图上)。本文将提供一个 Python 脚本,一键解决数据清洗、划分和配置生成的问题。
第一步:从 Label Studio 导出
- 进入项目,点击右上角 Export。
- 格式选择 YOLO。
- 下载并解压 ZIP 包。
解压后的目录结构(假设文件夹名为 ls_export):
ls_export/
├── classes.txt # 类别表
├── notes.json
├── images/ # 图片(如果是本地挂载模式,这里可能为空)
└── labels/ # 标注文件
🔴 关键检查:图片都在吗?
如果你使用了 Docker 挂载本地存储(Local Storage),导出的压缩包里可能只有labels而没有图片。
解决方法:请将你原始的图片复制到这个ls_export/images文件夹中。确保文件名与 labels 里的 txt 文件名一一对应。
第二步:自动化清洗与划分(核心步骤)
为了替代繁琐的手工移动文件,我编写了一个脚本。它会帮你做三件事:
- 按 8:2 比例随机划分训练集和验证集。
- 自动补全负样本:如果某张图没有标注(背景图),自动生成空的 txt 文件(YOLO 训练必需,否则会报错)。
- 自动生成
data.yaml:读取classes.txt并生成配置。
1. 创建脚本文件
在 ls_export 同级目录下,新建文件 split_data.py,粘贴以下代码:
import os
import shutil
import random
import yaml
import argparse
from pathlib import Path
# 支持的图片格式
IMG_FORMATS = {'.bmp', '.jpg', '.jpeg', '.png', '.tif', '.dng', '.webp'}
def split_dataset(source_dir, output_dir, train_ratio=0.8):
source_path = Path(source_dir)
output_path = Path(output_dir)
# 检查源文件
src_images = source_path / 'images'
src_labels = source_path / 'labels'
classes_file = source_path / 'classes.txt'
if not src_images.exists():
print(f"❌ 错误: 找不到 images 文件夹: {src_images}")
return
# 创建目标目录
for split in ['train', 'val']:
(output_path / 'images' / split).mkdir(parents=True, exist_ok=True)
(output_path / 'labels' / split).mkdir(parents=True, exist_ok=True)
# 获取图片列表
images = [f for f in src_images.iterdir() if f.suffix.lower() in IMG_FORMATS]
random.shuffle(images)
# 计算划分数量
num_train = int(len(images) * train_ratio)
split_map = {'train': images[:num_train], 'val': images[num_train:]}
print(f"📊 数据集总数: {len(images)} | 训练集: {len(split_map['train'])} | 验证集: {len(split_map['val'])}")
# 开始处理
for split, imgs in split_map.items():
print(f"🚀 处理 {split} 数据中...")
for img in imgs:
# 1. 复制/移动图片
shutil.copy(str(img), str(output_path / 'images' / split / img.name))
# 2. 处理标签
label_name = img.stem + '.txt'
src_label = src_labels / label_name
dst_label = output_path / 'labels' / split / label_name
if src_label.exists():
shutil.copy(str(src_label), str(dst_label))
else:
# 关键:创建空标签文件(处理负样本)
with open(dst_label, 'w') as f: pass
# 生成 data.yaml
names = {i: n.strip() for i, n in enumerate(open(classes_file).readlines())} if classes_file.exists() else {0: "unknown"}
yaml_data = {
'path': str(output_path.absolute()), # 绝对路径,防止报错
'train': 'images/train',
'val': 'images/val',
'nc': len(names),
'names': names
}
with open(output_path / 'data.yaml', 'w') as f:
yaml.dump(yaml_data, f, sort_keys=False)
print(f"✅ 处理完成!配置文件路径: {output_path / 'data.yaml'}")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--source', type=str, required=True, help='Label Studio 导出目录')
parser.add_argument('--output', type=str, required=True, help='输出的 YOLO 数据集目录')
parser.add_argument('--ratio', type=float, default=0.8, help='训练集比例')
args = parser.parse_args()
split_dataset(args.source, args.output, args.ratio)
2. 运行脚本
打开终端,运行:
# 用法: python split_data.py --source <源目录> --output <新目录>
python split_data.py --source ./ls_export --output ./yolo_dataset
运行结束后,你会在 yolo_dataset 文件夹下看到完美的 YOLO 格式结构,且包含生成的 data.yaml。
第三步:开始训练 (YOLOv8)
数据准备好了,现在开始训练。我们将使用 Ultralytics 官方库。
1. 安装环境
pip install ultralytics
2. 启动训练
脚本已经帮你生成了绝对路径的配置文件,所以你只需要一行命令:
yolo detect train \
data=./yolo_dataset/data.yaml \
model=yolov8n.pt \
epochs=100 \
imgsz=640 \
batch=16
参数解释:
- model:
yolov8n.pt(Nano) 速度最快,适合 CPU 或入门显卡;yolov8m.pt精度更高。 - epochs: 训练轮数。100 轮通常能看到不错的效果。
- imgsz: 输入图片大小,必须是 32 的倍数,常用 640。
常见问题与排查
Q1: 训练报错 file not found 或 no labels found?
- 检查
data.yaml内容。脚本默认生成的是绝对路径 (path: /User/xxx/yolo_dataset),这是最稳妥的方式。如果你移动了数据集文件夹,需要手动修改 yaml 里的路径。
Q2: 为什么我的准确率 (mAP) 是 0?
- 检查 Label Studio 的导出。YOLO 格式的 txt 内容必须是归一化的(0-1之间)。
- 打开一个 txt 文件,如果看到类似
0 0.5 0.5 0.2 0.3的数据是正常的;如果看到0 500 300 100 200(像素值),说明导出格式选错了(选成了 CSV 或其他)。
Q3: 多边形标注 (Polygon) 怎么办?
- 上述流程仅适用于目标检测 (Detect)。如果你在 Label Studio 画的是多边形,想做实例分割 (Segment),YOLOv8 需要的格式不同。
- 你需要将 Label Studio 导出为
JSON格式,然后编写转换脚本将 JSON 转为 YOLO Segmentation TXT 格式。
总结
通过引入自动化脚本,我们消除了从 Label Studio 到 YOLO 之间的人工操作壁垒。现在,你只需要专注于最核心的工作——高质量的标注,剩下的数据清洗和训练配置,交给代码自动完成即可。