深度学习项目实战:基于PyTorch的图像分类与目标检测(YOLOv8)

深度学习项目实战:基于PyTorch的图像分类与目标检测(YOLOv8)

一、项目概述

1.1 项目背景

目标检测是计算机视觉领域的核心技术之一,广泛应用于自动驾驶、安防监控、工业检测、医疗诊断等领域。YOLO(You Only Look Once)系列算法因其高效性和准确性成为目标检测的主流方案。

1.2 YOLOv8简介

|--------|------------------------------------------|
| 特性 | 说明 |
| 单阶段检测 | 将目标检测作为回归问题处理,实现端到端训练 |
| 实时性能 | 在保持高精度的同时实现实时检测 |
| 模块化设计 | 支持多种模型尺寸(nano、small、medium、large、xlarge) |
| 灵活部署 | 支持多种推理框架和硬件平台 |
| 易用性强 | 提供简洁的API和丰富的预训练模型 |

1.3 项目目标

• 掌握YOLOv8的核心原理和实现方法

• 完成从数据准备到模型部署的完整流程

• 实现图像分类和目标检测两个任务

• 学习模型优化和性能调优技巧

• 掌握深度学习项目的工程化实践

二、技术栈与环境配置

2.1 技术栈

|--------|---------------------------|
| 组件 | 技术 |
| 深度学习框架 | PyTorch 2.0+ |
| 计算机视觉库 | OpenCV, Pillow |
| 数据处理 | NumPy, Pandas |
| 可视化 | Matplotlib, Seaborn |
| 目标检测框架 | Ultralytics YOLOv8 |
| 模型部署 | ONNX, TensorRT |
| 开发工具 | Jupyter Notebook, VS Code |

2.2 环境配置

创建虚拟环境并安装依赖:

创建虚拟环境

conda create -n yolo python=3.10 -y
conda activate yolo

安装PyTorch(根据CUDA版本选择)

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

安装YOLOv8

pip install ultralytics

安装其他依赖

pip install opencv-python pillow numpy pandas matplotlib seaborn

验证安装

python -c "import torch; import ultralytics; print(torch.version)"

2.3 硬件要求

|--------|------------------------------|
| 组件 | 要求 |
| GPU | NVIDIA GPU(建议RTX 3060及以上) |
| 内存 | 16GB RAM(推荐32GB) |
| 存储 | 50GB可用空间(用于数据集和模型) |
| 操作系统 | Windows 10/11, Ubuntu 20.04+ |

三、YOLOv8架构详解

3.1 网络结构

YOLOv8采用CSPDarknet作为骨干网络,结合PANet和FPN进行特征融合,实现多尺度目标检测。

3.2 核心组件

|-------------|-------------------|
| 组件 | 功能 |
| C2f模块 | 改进的CSP模块,增强特征提取能力 |
| SPPF模块 | 空间金字塔池化,提取多尺度特征 |
| PANet | 路径聚合网络,融合不同层级特征 |
| 解耦头 | 分离分类和回归任务,提高检测精度 |
| Anchor-free | 无锚框设计,简化模型结构 |

3.3 损失函数

YOLOv8采用多种损失函数的组合:

|----------|------------------|
| 损失类型 | 函数 |
| 分类损失 | BCE Loss(二元交叉熵) |
| 回归损失 | CIoU Loss(完整交并比) |
| DFL损失 | 分布焦点损失,提高边界框定位精度 |

四、项目结构设计

4.1 目录结构

yolov8_project/
├── data/ # 数据目录

│ ├── images/ # 图像数据

│ │ ├── train/ # 训练集

│ │ ├── val/ # 验证集

│ │ └── test/ # 测试集

│ └── labels/ # 标注文件

│ ├── train/
│ ├── val/
│ └── test/
├── models/ # 模型目录

│ ├── yolov8n.pt # 预训练模型

│ ├── yolov8s.pt
│ ├── yolov8m.pt
│ └── yolov8l.pt
├── configs/ # 配置文件

│ ├── data.yaml # 数据集配置

│ └── train.yaml # 训练配置

├── src/ # 源代码

│ ├── train.py # 训练脚本

│ ├── inference.py # 推理脚本

│ ├── visualize.py # 可视化脚本

│ └── utils.py # 工具函数

├── outputs/ # 输出目录

│ ├── runs/ # 训练结果

│ │ ├── detect/ # 检测结果

│ │ └── train/ # 训练日志

│ └── models/ # 导出模型

├── notebooks/ # Jupyter笔记本

│ ├── data_exploration.ipynb
│ └── model_analysis.ipynb
├── requirements.txt # 依赖列表

└── README.md # 项目说明

五、数据集准备

5.1 数据集选择

|---------|-----------------------------|
| 数据集 | 说明 |
| COCO | 通用目标检测数据集,80个类别,11万张图像 |
| VOC | PASCAL VOC数据集,20个类别,1.6万张图像 |
| 自定义数据集 | 根据具体应用场景收集和标注数据 |

5.2 数据标注

使用LabelImg或LabelStudio进行数据标注:

安装标注工具

pip install labelimg

启动标注工具

labelimg data/images/train data/labels/train

标注格式:YOLO格式

每行格式: class_id x_center y_center width height

坐标归一化到0,1

5.3 数据增强

|----------|---------------|
| 增强类型 | 方法 |
| 几何变换 | 随机翻转、旋转、缩放、平移 |
| 颜色变换 | 亮度、对比度、饱和度调整 |
| Mosaic增强 | 将4张图像拼接成一张 |
| MixUp增强 | 两张图像混合 |
| HSV增强 | 色调、饱和度、明度调整 |

5.4 数据集配置

创建data.yaml配置文件:

数据集配置

path: ../data # 数据集根目录

train: images/train # 训练集路径

val: images/val # 验证集路径

test: images/test # 测试集路径

类别定义

names:
0: person
1: car
2: bicycle
3: dog
4: cat

数据集信息

nc: 5 # 类别数量

六、模型训练

6.1 训练脚本

from ultralytics import YOLO

加载预训练模型

model = YOLO('yolov8n.pt') # 或 yolov8s.pt, yolov8m.pt, yolov8l.pt

训练模型

results = model.train(
data='configs/data.yaml', # 数据集配置

epochs=100, # 训练轮数

imgsz=640, # 输入图像大小

batch=16, # 批次大小

device='0', # GPU设备

workers=8, # 数据加载线程数

name='yolov8n_custom', # 实验名称

patience=50, # 早停耐心值

save=True, # 保存检查点

plots=True, # 生成训练曲线

verbose=True # 详细输出

)

验证模型

metrics = model.val()

导出模型

model.export(format='onnx')

6.2 训练参数说明

|---------------|------------------|
| 参数 | 说明 |
| epochs | 训练轮数,默认100 |
| imgsz | 输入图像大小,默认640 |
| batch | 批次大小,根据显存调整 |
| lr0 | 初始学习率,默认0.01 |
| weight_decay | 权重衰减,默认0.0005 |
| momentum | 动量,默认0.937 |
| warmup_epochs | 预热轮数,默认3 |
| mosaic | Mosaic增强概率,默认1.0 |
| mixup | MixUp增强概率,默认0.0 |

6.3 训练监控

使用TensorBoard监控训练过程:

启动TensorBoard

tensorboard --logdir outputs/runs/train

或在代码中使用

from ultralytics import YOLO

model = YOLO('yolov8n.pt')
model.train(data='configs/data.yaml', tensorboard=True)

七、模型推理与部署

7.1 图像推理

from ultralytics import YOLO
import cv2

加载训练好的模型

model = YOLO('outputs/runs/train/yolov8n_custom/weights/best.pt')

单张图像推理

results = model('test_image.jpg')

批量推理

results = model('image1.jpg', 'image2.jpg', 'image3.jpg')

处理结果

for result in results:

获取检测框

boxes = result.boxes
for box in boxes:

获取类别

cls_id = int(box.cls0)
cls_name = model.namescls_id

获取置信度

conf = float(box.conf0)

获取边界框坐标

x1, y1, x2, y2 = box.xyxy0

绘制结果

cv2.rectangle(result.orig_img, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)
cv2.putText(result.orig_img, f'{cls_name} {conf:.2f}',
(int(x1), int(y1)-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

保存结果

cv2.imwrite('result.jpg', result.orig_img)

7.2 视频推理

from ultralytics import YOLO
import cv2

加载模型

model = YOLO('best.pt')

打开视频

cap = cv2.VideoCapture('input_video.mp4')

获取视频信息

fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

创建视频写入器

fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('output_video.mp4', fourcc, fps, (width, height))

逐帧处理

while cap.isOpened():
ret, frame = cap.read()
if not ret:
break

推理

results = model(frame)

绘制结果

annotated_frame = results0.plot()

写入视频

out.write(annotated_frame)

显示

cv2.imshow('YOLOv8 Detection', annotated_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break

cap.release()
out.release()
cv2.destroyAllWindows()

7.3 模型部署

将模型导出为ONNX格式进行部署:

from ultralytics import YOLO

加载模型

model = YOLO('best.pt')

导出为ONNX

model.export(format='onnx', dynamic=True, simplify=True)

导出为TensorRT

model.export(format='engine', half=True)

导出为CoreML

model.export(format='coreml')

八、可视化与评估

8.1 训练曲线可视化

import matplotlib.pyplot as plt
import pandas as pd
from pathlib import Path

读取训练日志

results_csv = 'outputs/runs/train/yolov8n_custom/results.csv'
df = pd.read_csv(results_csv)

绘制损失曲线

fig, axes = plt.subplots(2, 2, figsize=(12, 10))

训练损失

axes0, 0.plot(df'epoch', df'train/box_loss', label='Box Loss')
axes0, 0.plot(df'epoch', df'train/cls_loss', label='Cls Loss')
axes0, 0.plot(df'epoch', df'train/dfl_loss', label='DFL Loss')
axes0, 0.set_xlabel('Epoch')
axes0, 0.set_ylabel('Loss')
axes0, 0.set_title('Training Loss')
axes0, 0.legend()

验证损失

axes0, 1.plot(df'epoch', df'val/box_loss', label='Box Loss')
axes0, 1.plot(df'epoch', df'val/cls_loss', label='Cls Loss')
axes0, 1.plot(df'epoch', df'val/dfl_loss', label='DFL Loss')
axes0, 1.set_xlabel('Epoch')
axes0, 1.set_ylabel('Loss')
axes0, 1.set_title('Validation Loss')
axes0, 1.legend()

mAP指标

axes1, 0.plot(df'epoch', df'metrics/mAP50(B)', label='mAP@50')
axes1, 0.plot(df'epoch', df'metrics/mAP50-95(B)', label='mAP@50-95')
axes1, 0.set_xlabel('Epoch')
axes1, 0.set_ylabel('mAP')
axes1, 0.set_title('Mean Average Precision')
axes1, 0.legend()

精确率和召回率

axes1, 1.plot(df'epoch', df'metrics/precision(B)', label='Precision')
axes1, 1.plot(df'epoch', df'metrics/recall(B)', label='Recall')
axes1, 1.set_xlabel('Epoch')
axes1, 1.set_ylabel('Score')
axes1, 1.set_title('Precision and Recall')
axes1, 1.legend()

plt.tight_layout()
plt.savefig('training_curves.png', dpi=300)

8.2 混淆矩阵

from ultralytics import YOLO
import matplotlib.pyplot as plt

加载模型

model = YOLO('best.pt')

验证并生成混淆矩阵

results = model.val(conf=0.25, iou=0.6, plots=True)

混淆矩阵会自动保存到 outputs/runs/val/confusion_matrix.png

8.3 PR曲线

验证模型并生成PR曲线

results = model.val(plots=True)

PR曲线会自动保存到 outputs/runs/val/PR_curve.png

九、项目实战案例

9.1 案例1:交通标志检测

实现交通标志的实时检测,用于自动驾驶辅助系统。

|--------|----------------------|
| 参数 | 配置 |
| 数据集 | GTSDB(德国交通标志检测基准数据集) |
| 类别数 | 43个交通标志类别 |
| 模型 | YOLOv8n(轻量级,适合实时应用) |
| 输入尺寸 | 640x640 |
| 训练轮数 | 100 epochs |
| mAP@50 | 0.92 |
| 推理速度 | 2ms/帧(RTX 3090) |

9.2 案例2:工业缺陷检测

实现产品表面缺陷的自动检测,用于质量控制。

|--------|----------------------|
| 参数 | 配置 |
| 数据集 | 自定义工业缺陷数据集 |
| 类别数 | 5类缺陷(划痕、凹陷、污渍、裂纹、气泡) |
| 模型 | YOLOv8s(平衡精度和速度) |
| 输入尺寸 | 1024x1024 |
| 训练轮数 | 150 epochs |
| mAP@50 | 0.88 |
| 推理速度 | 8ms/帧(RTX 3090) |

9.3 案例3:行人检测

实现行人的实时检测,用于安防监控。

|--------|------------------|
| 参数 | 配置 |
| 数据集 | COCO行人数据 + 自定义数据 |
| 类别数 | 1类(行人) |
| 模型 | YOLOv8m(高精度) |
| 输入尺寸 | 640x640 |
| 训练轮数 | 200 epochs |
| mAP@50 | 0.95 |
| 推理速度 | 5ms/帧(RTX 3090) |

十、优化与扩展

10.1 模型优化

|----------|-----------------------|
| 优化方法 | 说明 |
| 模型量化 | 将FP32模型量化为INT8,减少模型大小 |
| 模型剪枝 | 移除不重要的权重,减少计算量 |
| 知识蒸馏 | 用大模型指导小模型训练 |
| 神经架构搜索 | 自动搜索最优网络结构 |

10.2 性能优化

|----------|-------------------|
| 优化方法 | 说明 |
| 混合精度训练 | 使用FP16加速训练,减少显存占用 |
| 梯度累积 | 模拟大批次训练 |
| 分布式训练 | 多GPU并行训练 |
| 数据加载优化 | 使用多线程预加载数据 |

10.3 部署优化

|--------------|------------------|
| 部署平台 | 优化方案 |
| TensorRT加速 | NVIDIA GPU专用推理引擎 |
| ONNX Runtime | 跨平台推理框架 |
| OpenVINO | Intel CPU优化推理 |
| CoreML | Apple设备部署 |

附录:完整代码示例

A.1 完整训练脚本

#!/usr/bin/env python3

-*- coding: utf-8 -*-

"""
YOLOv8完整训练脚本

"""

from ultralytics import YOLO
import torch
from pathlib import Path

def train_model():
"""训练YOLOv8模型"""

检查GPU

device = '0' if torch.cuda.is_available() else 'cpu'
print(f'Using device: {device}')

加载预训练模型

model = YOLO('yolov8n.pt')

训练配置

config = {
'data': 'configs/data.yaml',
'epochs': 100,
'imgsz': 640,
'batch': 16,
'device': device,
'workers': 8,
'name': 'yolov8n_custom',
'patience': 50,
'save': True,
'plots': True,
'verbose': True,
'lr0': 0.01,
'weight_decay': 0.0005,
'warmup_epochs': 3,
'mosaic': 1.0,
'mixup': 0.0,
'hsv_h': 0.015,
'hsv_s': 0.7,
'hsv_v': 0.4
}

训练模型

results = model.train(**config)

验证模型

metrics = model.val()

打印结果

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}')

导出模型

model.export(format='onnx')

return model, results

if name == 'main':
model, results = train_model()

A.2 完整推理脚本

#!/usr/bin/env python3

-*- coding: utf-8 -*-

"""
YOLOv8完整推理脚本

"""

from ultralytics import YOLO
import cv2
import argparse
from pathlib import Path

class YOLODetector:
"""YOLOv8检测器"""

def init(self, model_path, conf_threshold=0.5, iou_threshold=0.45):
"""
初始化检测器

Args:
model_path: 模型路径

conf_threshold: 置信度阈值

iou_threshold: IOU阈值

"""
self.model = YOLO(model_path)
self.conf_threshold = conf_threshold
self.iou_threshold = iou_threshold
self.class_names = self.model.names

def detect_image(self, image_path, output_path=None):
"""
检测单张图像

Args:
image_path: 输入图像路径

output_path: 输出图像路径

"""

读取图像

image = cv2.imread(str(image_path))
if image is None:
raise ValueError(f'无法读取图像: {image_path}')

推理

results = self.model(
image,
conf=self.conf_threshold,
iou=self.iou_threshold,
verbose=False
)

绘制结果

annotated_image = results0.plot()

保存结果

if output_path:
cv2.imwrite(str(output_path), annotated_image)
print(f'结果已保存到: {output_path}')

return results0

def detect_video(self, video_path, output_path=None):
"""
检测视频

Args:
video_path: 输入视频路径

output_path: 输出视频路径

"""

打开视频

cap = cv2.VideoCapture(str(video_path))
if not cap.isOpened():
raise ValueError(f'无法打开视频: {video_path}')

获取视频信息

fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

创建视频写入器

if output_path:
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(str(output_path), fourcc, fps, (width, height))

逐帧处理

frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break

推理

results = self.model(
frame,
conf=self.conf_threshold,
iou=self.iou_threshold,
verbose=False
)

绘制结果

annotated_frame = results0.plot()

写入视频

if output_path:
out.write(annotated_frame)

显示进度

frame_count += 1
if frame_count % 30 == 0:
print(f'处理进度: {frame_count}/{total_frames} ({frame_count/total_frames*100:.1f}%)')

显示

cv2.imshow('YOLOv8 Detection', annotated_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break

释放资源

cap.release()
if output_path:
out.release()
cv2.destroyAllWindows()

print(f'视频处理完成: {frame_count} 帧')

def detect_webcam(self):
"""检测摄像头实时画面"""

打开摄像头

cap = cv2.VideoCapture(0)
if not cap.isOpened():
raise ValueError('无法打开摄像头')

while True:
ret, frame = cap.read()
if not ret:
break

推理

results = self.model(
frame,
conf=self.conf_threshold,
iou=self.iou_threshold,
verbose=False
)

绘制结果

annotated_frame = results0.plot()

显示

cv2.imshow('YOLOv8 Webcam Detection', annotated_frame)

按q退出

if cv2.waitKey(1) & 0xFF == ord('q'):
break

cap.release()
cv2.destroyAllWindows()

def main():
"""主函数"""
parser = argparse.ArgumentParser(description='YOLOv8目标检测')
parser.add_argument('--model', type=str, default='best.pt', help='模型路径')
parser.add_argument('--source', type=str, help='输入源(图像/视频/摄像头)')
parser.add_argument('--output', type=str, help='输出路径')
parser.add_argument('--conf', type=float, default=0.5, help='置信度阈值')
parser.add_argument('--iou', type=float, default=0.45, help='IOU阈值')
parser.add_argument('--webcam', action='store_true', help='使用摄像头')

args = parser.parse_args()

创建检测器

detector = YOLODetector(
model_path=args.model,
conf_threshold=args.conf,
iou_threshold=args.iou
)

检测

if args.webcam:
detector.detect_webcam()
elif args.source:
source_path = Path(args.source)
if source_path.is_file():
if source_path.suffix.lower() in '.jpg', '.jpeg', '.png', '.bmp':
detector.detect_image(source_path, args.output)
elif source_path.suffix.lower() in '.mp4', '.avi', '.mov':
detector.detect_video(source_path, args.output)
else:
raise ValueError(f'不支持的输入源: {args.source}')
else:
print('请指定输入源(--source)或使用摄像头(--webcam)')

if name == 'main':
main()

十一、项目数据已上传,下载地址:

https://download.csdn.net/download/m0_67097444/92942078

相关推荐
imDwAaY1 小时前
从感知机到 Attention:我用 PyTorch 打穿 CS188 机器学习终章 CS188 Proj5 学习笔记
人工智能·pytorch·笔记·python·学习·机器学习
天天进步201513 小时前
Python全栈项目--基于深度学习的视频目标跟踪系统
python·深度学习·音视频
AI人工智能+14 小时前
融合图像处理与模式识别算法的智能银行卡识别系统,为金融行业带来了革命性的效率提升
人工智能·深度学习·ocr·银行卡识别
zhangfeng113316 小时前
Mamba transformer的颠覆者 论文技术解读与应用实践深度报告,
人工智能·深度学习·transformer
hans汉斯17 小时前
【计算机科学与应用】YOLO-Apple:一种用于苹果幼果检测的改进型目标检测方法
人工智能·yolo·目标检测·计算机视觉·目标跟踪·数据·病虫害检测
动物园猫18 小时前
外墙裂缝目标检测数据集分享(适用于YOLO系列深度学习分类检测任务)
深度学习·yolo·目标检测
郑洁文18 小时前
基于卷积神经网络的智能车牌识别系统
人工智能·深度学习·神经网络·车牌识别
红宝村村长19 小时前
loss.backward() 和 梯度累积
深度学习
zlkingdom19 小时前
Jetson Orin开发板,在conda环境中直接实现Pytorch的GPU加速
人工智能·pytorch·conda·随笔·jetson orin