1. YOLOv5环境搭建与COCO数据集准备
任务目标
本案例完成YOLOv5训练环境搭建,下载COCO数据集的少量子集(person类别),转换为YOLO格式并验证数据加载流程。最终通过运行数据检查脚本,确认图像与标签文件正确配对、类别ID无误。
环境依赖
需要Python 3.8+、PyTorch 1.8+、Ultralytics YOLOv5仓库。建议使用GPU(CUDA 11.x),CPU也可运行但训练较慢。
# 创建虚拟环境并安装依赖
python -m venv yolov5_env
source yolov5_env/bin/activate # Windows: yolov5_env\Scripts\activate
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118
git clone https://github.com/ultralytics/yolov5.git
cd yolov5
pip install -r requirements.txt
COCO子集下载与转换
使用pycocotools从COCO验证集中筛选仅含person类别的图像(约100张),并转换为YOLO格式的标签文件。以下脚本完成下载、筛选、格式转换与数据集划分:
import os
import json
import shutil
import urllib.request
import zipfile
from pathlib import Path
from collections import defaultdict
# 配置路径
BASE_DIR = Path("./coco_person_subset")
IMG_DIR = BASE_DIR / "images"
LABEL_DIR = BASE_DIR / "labels"
ANNOTATION_URL = "http://images.cocodataset.org/annotations/annotations_trainval2017.zip"
IMAGE_BASE_URL = "http://images.cocodataset.org/val2017/"
# 创建目录
IMG_DIR.mkdir(parents=True, exist_ok=True)
LABEL_DIR.mkdir(parents=True, exist_ok=True)
# 1. 下载COCO标注文件(若未存在)
ann_zip = BASE_DIR / "annotations_trainval2017.zip"
if not ann_zip.exists():
print("下载COCO标注文件...")
urllib.request.urlretrieve(ANNOTATION_URL, ann_zip)
with zipfile.ZipFile(ann_zip, 'r') as z:
z.extractall(BASE_DIR)
# 2. 加载instances_val2017.json
with open(BASE_DIR / "annotations" / "instances_val2017.json", 'r') as f:
coco_data = json.load(f)
# 建立类别名到ID的映射
cat_id_to_name = {cat['id']: cat['name'] for cat in coco_data['categories']}
cat_name_to_id = {cat['name']: cat['id'] for cat in coco_data['categories']}
person_cat_id = cat_name_to_id['person']
# 3. 筛选包含person的图像
img_id_to_info = {img['id']: img for img in coco_data['images']}
img_ids_with_person = set()
annotations_by_img = defaultdict(list)
for ann in coco_data['annotations']:
if ann['category_id'] == person_cat_id:
img_ids_with_person.add(ann['image_id'])
annotations_by_img[ann['image_id']].append(ann)
# 取前100张包含person的图像
selected_img_ids = list(img_ids_with_person)[:100]
print(f"筛选到 {len(selected_img_ids)} 张包含person的图像")
# 4. 下载图像并生成YOLO格式标签
for idx, img_id in enumerate(selected_img_ids):
img_info = img_id_to_info[img_id]
file_name = img_info['file_name']
width, height = img_info['width'], img_info['height']
# 下载图像
img_path = IMG_DIR / file_name
if not img_path.exists():
urllib.request.urlretrieve(IMAGE_BASE_URL + file_name, img_path)
# 生成YOLO标签文件
label_path = LABEL_DIR / (Path(file_name).stem + ".txt")
with open(label_path, 'w') as f:
for ann in annotations_by_img[img_id]:
# COCO bbox: [x, y, w, h] → YOLO: [x_center, y_center, w, h] 归一化
x, y, w, h = ann['bbox']
x_center = (x + w / 2) / width
y_center = (y + h / 2) / height
w_norm = w / width
h_norm = h / height
# person类别ID在YOLO中为0(COCO person的cat_id=1,但YOLO从0开始)
f.write(f"0 {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}\n")
if (idx + 1) % 20 == 0:
print(f"已处理 {idx + 1}/{len(selected_img_ids)} 张图像")
# 5. 生成数据集配置文件
data_yaml = f"""
path: {BASE_DIR.resolve()}
train: images
val: images
nc: 1
names: ['person']
"""
with open(BASE_DIR / "dataset.yaml", 'w') as f:
f.write(data_yaml)
print("数据集准备完成!")
print(f"图像数量: {len(list(IMG_DIR.glob('*.jpg')))}")
print(f"标签数量: {len(list(LABEL_DIR.glob('*.txt')))}")
数据加载验证
运行以下脚本验证YOLOv5能否正确加载数据集并读取标签:
import torch
from pathlib import Path
# 加载YOLOv5数据加载器
from utils.datasets import LoadImagesAndLabels
data_yaml = Path("./coco_person_subset/dataset.yaml")
dataset = LoadImagesAndLabels(str(data_yaml), img_size=640, batch_size=8, augment=False)
# 验证第一个batch
dataloader = torch.utils.data.DataLoader(dataset, batch_size=8, shuffle=True)
batch = next(iter(dataloader))
imgs, labels, paths, shapes = batch
print(f"Batch图像张量形状: {imgs.shape}") # 预期: [8, 3, 640, 640]
print(f"Batch标签形状: {labels.shape}") # 预期: [N, 6] 每行: [image_idx, cls, x, y, w, h]
print(f"样本图像路径: {paths[:2]}")
# 检查标签是否在有效范围内
cls = labels[:, 1]
assert cls.max() == 0, "类别ID应为0(person)"
assert (labels[:, 2:] >= 0).all() and (labels[:, 2:] <= 1).all(), "归一化坐标应在[0,1]内"
print("数据加载验证通过!")
验证方法与判定标准
- 数据集准备验证:运行第一个脚本后,终端输出图像数量与标签数量均为100,且
dataset.yaml文件生成成功。 - 数据加载验证:运行第二个脚本,若输出
Batch图像张量形状: [8, 3, 640, 640]且无断言错误,说明数据加载流程正常。 - 标签正确性抽查:随机打开
coco_person_subset/labels/下任一txt文件,确认每行格式为0 x_center y_center width height,数值均在0~1之间。
满足以上条件即判定环境搭建与数据准备成功,可进入后续YOLOv5训练环节。