# YOLO 模型测试流程指南 本文档基于知乎文章整理,帮助你从零开始完成一个 YOLO 目标检测项目的完整流程。 *** ## 目录 1. [环境准备](#1-环境准备) 2. [数据收集与准备](#2-数据收集与准备) 3. [数据标注](#3-数据标注) 4. [数据格式转换](#4-数据格式转换) 5. [数据集划分](#5-数据集划分) 6. [模型训练](#6-模型训练) 7. [模型评估与测试](#7-模型评估与测试) *** ## 1. 环境准备 ### 1.1 安装 Python 环境 确保 Python 版本 >= 3.8 ```bash python --version ``` ### 1.2 创建虚拟环境 为了避免影响全局 Python 环境,建议为项目创建独立的虚拟环境。 **方式一:使用 conda** **首先安装 Anaconda 或 Miniconda:** 1. 下载 Miniconda(推荐,更轻量): 2. 运行安装程序,勾选 "Add Miniconda to PATH"(或安装后手动配置) 3. 验证安装: ```bash conda --version ``` **创建并激活虚拟环境:** ```bash # 首次使用需要接受服务条款 conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/msys2 //切换用清华的源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main # 创建虚拟环境 conda create -n yolo_demo python=3.10 -y # 激活虚拟环境 conda activate yolo_demo conda env list # 安装 pytorch(GPU 支持,需要 CUDA) # 首先卸载 CPU 版本(如果已安装) conda uninstall pytorch torchvision torchaudio -y # 安装 PyTorch CUDA 版本(推荐 CUDA 12.1) conda install -v pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia -y # pip 来安装 PyTorch 更稳定 conda activate yolo_demo ; pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 # 验证安装是否成功 python -c "import torch; print(f'PyTorch版本: {torch.__version__}'); print(f'CUDA可用: {torch.cuda.is_available()}')" ``` **查看已创建的环境:** ```bash conda env list ``` **常见问题:** 如果遇到 `CondaToSNonInteractiveError` 错误,需要先运行上面的 `conda tos accept` 命令接受服务条款。 **验证虚拟环境已激活:** 激活后,终端提示符前会显示虚拟环境名称: ```bash (yolo_demo) D:\Codes\AI\Yolo\YoloDemo> ``` **退出虚拟环境:** ```bash # conda: conda deactivate ``` ### 1.3 安装 YOLOv8(推荐) ```bash conda activate yolo_demo ;pip install ultralytics ``` ### 1.4 验证安装 ```bash python -c "from ultralytics import YOLO; print('YOLOv8 安装成功')" ``` ### 1.5 检查 GPU 支持(可选但推荐) ```bash python -c "import torch; print(f'CUDA 可用: {torch.cuda.is_available()}')" ``` *** ## 2. 数据收集与准备 ### 2.1 确定检测目标 首先明确你要检测的类别,例如: - car(汽车) - person(行人) - bicycle(自行车) ### 2.2 数据量建议 | 项目类型 | 每类最少图片 | 推荐图片数 | | ---- | --------- | ------ | | 快速原型 | 100-200 张 | 500 张 | | 生产应用 | 1000 张 | 3000 张 | ### 2.3 数据来源 **方式一:使用公开数据集** - COCO 数据集: -
- Open Images: **方式二:自己拍摄/收集图片** - 确保图片清晰,目标可见 - 覆盖不同场景、光照、角度 - 统一格式为 JPG 或 PNG ### 2.4 创建数据目录结构 ```bash mkdir -p dataset/images mkdir -p dataset/labels ``` 将收集的图片放入 `dataset/images` 目录。 *** ## 3. 数据标注 ### 3.1 选择标注工具 推荐使用以下工具之一: - **TjMakeBot**(在线工具,支持 AI 辅助标注): - **LabelImg**(本地工具) - **Roboflow**(在线工具) ### 3.2 使用 LabelImg 标注(本地方式) **安装 LabelImg:** ```bash pip install labelImg ``` **启动 LabelImg:** ```bash labelImg ``` **标注步骤:** 1. 打开 LabelImg 2. 点击 "Open Dir" 选择图片目录 3. 点击 "Change Save Dir" 设置标注保存目录 4. **重要**:点击 "PascalVOC" 切换为 "YOLO" 格式 5. 使用快捷键 `W` 绘制边界框 6. 选择类别名称 7. 点击 "Save" 保存标注 8. 使用 `D` 键切换到下一张图片 ### 3.3 YOLO 标注格式说明 每张图片对应一个 `.txt` 文件,格式如下: ``` class_id center_x center_y width height ``` 示例: ``` 0 0.5 0.5 0.3 0.4 1 0.2 0.3 0.1 0.2 ``` **说明:** - `class_id`:类别 ID(从 0 开始) - `center_x, center_y`:边界框中心点坐标(归一化 0-1) - `width, height`:边界框宽高(归一化 0-1) *** ## 4. 数据格式转换 ### 4.1 验证标注文件 创建验证脚本 `validate_dataset.py`: ```python import os from PIL import Image def validate_yolo_dataset(dataset_dir): images_dir = os.path.join(dataset_dir, 'images') labels_dir = os.path.join(dataset_dir, 'labels') errors = [] image_files = [f for f in os.listdir(images_dir) if f.endswith(('.jpg', '.png'))] for img_file in image_files: img_path = os.path.join(images_dir, img_file) label_file = os.path.splitext(img_file)[0] + '.txt' label_path = os.path.join(labels_dir, label_file) if not os.path.exists(label_path): errors.append(f"缺失标注文件: {label_file}") continue try: img = Image.open(img_path) img_width, img_height = img.size except Exception as e: errors.append(f"无法打开图片: {img_file}") continue with open(label_path, 'r') as f: for line_num, line in enumerate(f, 1): line = line.strip() if not line: continue parts = line.split() if len(parts) != 5: errors.append(f"{label_file}: 格式错误") continue try: class_id = int(parts[0]) center_x = float(parts[1]) center_y = float(parts[2]) width = float(parts[3]) height = float(parts[4]) if not (0 <= center_x <= 1 and 0 <= center_y <= 1): errors.append(f"{label_file}: 坐标超出范围") except ValueError: errors.append(f"{label_file}: 数字解析错误") if errors: print("发现错误:") for error in errors[:10]: print(f" - {error}") else: print("验证通过!") if __name__ == '__main__': validate_yolo_dataset('./dataset') ``` 运行验证: ```bash python validate_dataset.py ``` ### 4.2 创建数据集配置文件 创建 `dataset.yaml` 文件: ```yaml path: ./dataset train: images/train val: images/val test: images/test nc: 3 names: 0: car 1: person 2: bicycle ``` **注意:** 根据你的实际类别修改 `nc` 和 `names`。 *** ## 5. 数据集划分 ### 5.1 创建划分脚本 创建 `split_dataset.py`: ```python import os import shutil import random def split_dataset(source_dir, train_ratio=0.7, val_ratio=0.15, test_ratio=0.15, seed=42): random.seed(seed) images_dir = os.path.join(source_dir, 'images') labels_dir = os.path.join(source_dir, 'labels') images = [f for f in os.listdir(images_dir) if f.endswith(('.jpg', '.png'))] random.shuffle(images) total = len(images) train_end = int(total * train_ratio) val_end = train_end + int(total * val_ratio) train_images = images[:train_end] val_images = images[train_end:val_end] test_images = images[val_end:] print(f"总图片数: {total}") print(f"训练集: {len(train_images)}") print(f"验证集: {len(val_images)}") print(f"测试集: {len(test_images)}") for split, img_list in [('train', train_images), ('val', val_images), ('test', test_images)]: split_images_dir = os.path.join(source_dir, 'images', split) split_labels_dir = os.path.join(source_dir, 'labels', split) os.makedirs(split_images_dir, exist_ok=True) os.makedirs(split_labels_dir, exist_ok=True) for img in img_list: shutil.copy(os.path.join(images_dir, img), os.path.join(split_images_dir, img)) label_name = os.path.splitext(img)[0] + '.txt' src_label = os.path.join(labels_dir, label_name) dst_label = os.path.join(split_labels_dir, label_name) if os.path.exists(src_label): shutil.copy(src_label, dst_label) print("数据集划分完成!") if __name__ == '__main__': split_dataset('./dataset') ``` ### 5.2 执行划分 ```bash python split_dataset.py ``` ### 5.3 验证划分结果 ```bash ls dataset/images/train ls dataset/images/val ls dataset/images/test ``` *** ## 6. 模型训练 ### 6.1 创建训练脚本 创建 `train.py`: ```python from ultralytics import YOLO import torch device = 'cuda' if torch.cuda.is_available() else 'cpu' print(f"使用设备: {device}") model = YOLO('yolov8n.pt') results = model.train( data='dataset.yaml', epochs=100, imgsz=640, batch=16, device=device, lr0=0.01, patience=50, save=True, plots=True, project='runs/detect', name='my_model', exist_ok=True, ) print("训练完成!") print(f"最佳模型保存在: runs/detect/my_model/weights/best.pt") ``` ### 6.2 开始训练 ```bash python train.py ``` ### 6.3 训练参数说明 | 参数 | 说明 | 建议值 | | -------- | ------ | ----------- | | epochs | 训练轮数 | 100-300 | | imgsz | 输入图片尺寸 | 640 | | batch | 批次大小 | 根据 GPU 内存调整 | | lr0 | 初始学习率 | 0.01 | | patience | 早停耐心值 | 50 | ### 6.4 模型选择建议 | 模型 | 参数量 | 速度 | 精度 | 适用场景 | | ------- | ----- | -- | -- | ---- | | yolov8n | 3.2M | 最快 | 较低 | 实时检测 | | yolov8s | 11.2M | 快 | 中等 | 平衡 | | yolov8m | 25.9M | 中等 | 较高 | 生产环境 | | yolov8l | 43.7M | 较慢 | 高 | 高精度 | *** ## 7. 模型评估与测试 ### 7.1 评估模型 创建 `evaluate.py`: ```python from ultralytics import YOLO model = YOLO('runs/detect/my_model/weights/best.pt') metrics = model.val(data='dataset.yaml', split='val') print("=" * 50) print("模型评估结果") print("=" * 50) print(f"mAP50: {metrics.box.map50:.4f}") print(f"mAP50-95: {metrics.box.map:.4f}") print(f"Precision: {metrics.box.mp:.4f}") print(f"Recall: {metrics.box.mr:.4f}") print("=" * 50) ``` 运行评估: ```bash python evaluate.py ``` ### 7.2 测试单张图片 创建 `predict.py`: ```python from ultralytics import YOLO model = YOLO('runs/detect/my_model/weights/best.pt') results = model('dataset/images/test/test_image.jpg', save=True, conf=0.25) for result in results: boxes = result.boxes for i in range(len(boxes)): class_name = model.names[int(boxes.cls[i])] conf = boxes.conf[i] print(f"检测到: {class_name}, 置信度: {conf:.2f}") ``` 运行测试: ```bash python predict.py ``` ### 7.3 批量测试 ```python from ultralytics import YOLO model = YOLO('runs/detect/my_model/weights/best.pt') results = model('dataset/images/test', save=True, conf=0.25) ``` ### 7.4 性能基准 | 应用场景 | mAP50 目标 | mAP50-95 目标 | | ----- | -------- | ----------- | | 快速原型 | > 0.5 | > 0.3 | | 生产环境 | > 0.7 | > 0.5 | | 高精度应用 | > 0.9 | > 0.7 | *** ## 常见问题排查 ### 问题 1:Loss 不下降 **解决方案:** - 调整学习率(尝试 0.001-0.01) - 检查数据质量 - 尝试更大的模型 ### 问题 2:过拟合 **解决方案:** - 增加数据量 - 使用更小的模型 - 启用更多数据增强 ### 问题 3:训练很慢 **解决方案:** - 使用 GPU 训练 - 增大批次大小 - 减小图片尺寸 *** ## 目录结构总结 完成后的目录结构: ``` project/ ├── venv/ # 虚拟环境目录(不应提交到版本控制) ├── dataset/ │ ├── images/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ └── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── dataset.yaml ├── train.py ├── evaluate.py ├── predict.py ├── split_dataset.py └── validate_dataset.py ``` *** ## 快速开始命令汇总 ```bash # 创建并激活虚拟环境 python -m venv venv venv\Scripts\activate # 安装依赖 pip install ultralytics # 后续步骤 python validate_dataset.py python split_dataset.py python train.py python evaluate.py python predict.py ``` *** ## 一键运行环境准备 项目已提供 `run_demo.py` 脚本,可一键完成环境搭建: ```bash python run_demo.py ``` 该脚本会自动完成: 1. 检查 Python 版本 2. 创建虚拟环境 3. 安装 ultralytics 依赖 4. 验证安装 5. 检查 GPU 支持 ## 在 VS Code 中直接运行代码 ### 方法一:使用 Code Runner 插件 1. 打开 VS Code,搜索并安装 `Code Runner` 插件 2. 将光标放在代码块内,点击右上角的 ▶️ 按钮运行 ### 方法二:右键运行 在代码块内右键,选择 "Run Code" 或使用快捷键 `Ctrl+Alt+N` ### 方法三:终端运行 ```bash # 进入项目目录 cd . # 激活虚拟环境 venv\Scripts\activate # 运行脚本 python run_demo.py python validate_dataset.py python split_dataset.py python train.py ``` *** 祝训练顺利!