From 41e3bb113a2ddebdf96c36006996e7cc7b777f9d Mon Sep 17 00:00:00 2001 From: ShaoHua <345265198@qqcom> Date: Tue, 5 May 2026 01:07:49 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=AE=89=E8=A3=85=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/1.YOLO模型测试流程指南.md | 643 +++++++++++++++++++++++++++++++++ 1 file changed, 643 insertions(+) create mode 100644 docs/1.YOLO模型测试流程指南.md diff --git a/docs/1.YOLO模型测试流程指南.md b/docs/1.YOLO模型测试流程指南.md new file mode 100644 index 0000000..3ed720e --- /dev/null +++ b/docs/1.YOLO模型测试流程指南.md @@ -0,0 +1,643 @@ +# 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 +``` + +*** + +祝训练顺利!