如何训练一个 YOLOv1 模型(基于 DarkNet 预训练)

本文介绍如何从零开始训练一个 YOLOv1 模型,包括 DarkNet 网络构建、训练流程、参数加载、数据集准备、模型评估与检测推理等完整步骤。适合目标检测初学者。

代码仓库:https://github.com/Keep-Doing-guoguo/yolo/tree/master


1. 构建 DarkNet 网络结构

YOLOv1 的骨干网络是基于 DarkNet 构建的卷积神经网络。其主要结构如下:

  • 每个卷积层结构为:Conv2d → BatchNorm2d → LeakyReLU
  • 使用 MaxPool2d 实现下采样
  • 中间层包含大量 1x1 和 3x3 卷积交替堆叠,用于提取复杂特征

此外,代码还会构建一个 不含 BN 层的 DarkNet 网络,用于对比实验,验证 BN 层对训练效果的影响。


2. 训练 DarkNet 模型(鲜花五分类)

为了提升 YOLOv1 的特征提取能力,我们首先在 鲜花五分类数据集 上预训练 DarkNet 网络。

数据集结构如下:

/models/other_code/acvhhhhh/archive/
├── train/
│   ├── class1/
│   │   ├── img1.jpg
│   │   ├── img2.jpg
│   ├── class2/
│   └── ...
└── val/
    ├── class1/
    ├── class2/
    └── ...

训练配置:

  • 分类任务:5分类
  • 指标:Top-1 Accuracy、Top-5 Accuracy
  • 使用 torchvision.transforms 进行数据增强
  • 使用 torch.utils.tensorboard.SummaryWriter 记录训练日志
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('logs/darknet_train')

训练完成后,使用以下命令查看 TensorBoard 可视化结果:

tensorboard --logdir=logs/darknet_train
# 默认访问地址:http://localhost:6006

3. 加载 DarkNet 参数训练 YOLOv1

训练完 DarkNet 后,我们将其中的 卷积层参数 加载到 YOLOv1 模型中,作为其特征提取部分。分类层参数将被忽略,YOLOv1 使用自定义的检测头输出。

# 加载预训练的 DarkNet 权重(只加载卷积层)
model = YOLOv1()
pretrained_dict = torch.load('darknet.pth')
model_dict = model.state_dict()
# 只加载卷积层参数
pretrained_dict = {k: v for k, v in pretrained_dict.items() if 'conv' in k}
model_dict.update(pretrained_dict)
model.load_state_dict(model_dict)

4. 准备 VOC2012 数据集

YOLOv1 的训练数据来自 VOC2012 数据集。我们需要使用 voc2012.txt 文件来读取标注信息。

该文件每一行格式如下:

JPEGImages/2007_000027.jpg Annotations/2007_000027.xml

解析 XML 文件,提取 bounding box 和类别标签,构建训练数据集。


5. 配置训练流程

在 YOLOv1 的训练中,使用 VOC2012 数据集进行训练,并复用 DarkNet 的卷积层参数。

训练流程如下:

  1. 构建 Dataset 和 Dataloader
  2. 定义损失函数(包含定位损失、置信度损失、分类损失)
  3. 使用 Adam 或 SGD 优化器
  4. 使用 TensorBoard 记录 loss、等指标(acc 等指标,需在训练中补充)

6. 模型评估(evaluate.py)

由于训练过程中未输出准确率(acc),我们单独编写 evaluate.py 脚本进行模型评估。

评估内容包括:

  • 整体准确率(Top-1 / Top-5)
  • 各类别准确率
  • 混淆矩阵分析
def evaluate(model, dataloader):
    model.eval()
    correct_top1 = 0
    correct_top5 = 0
    total = 0
    with torch.no_grad():
        for images, labels in dataloader:
            outputs = model(images)
            _, predicted = outputs.topk(5, 1, True, True)
            total += labels.size(0)
            correct_top1 += (predicted[:, 0] == labels).sum().item()
            correct_top5 += (predicted == labels.view(-1, 1)).sum().item()
    print(f"Top-1 Accuracy: {100 * correct_top1 / total:.2f}%")
    print(f"Top-5 Accuracy: {100 * correct_top5 / total:.2f}%")

7. 单图检测(detect.py)

训练完成后,可以使用 detect.py 脚本对单张图像进行目标检测。

流程如下:

  1. 加载模型权重
  2. 图像预处理(resize、归一化)
  3. 模型推理
  4. 解码输出(bounding box、类别、置信度)
  5. 应用 NMS(非极大值抑制)
  6. 绘制检测框并保存结果图像

8. 后续优化方向

  • 在训练过程中加入 Top-1 / Top-5 准确率输出
  • 支持 视频检测,扩展检测场景
  • 使用 TensorRT / ONNX 加速推理
  • 增加 数据增强策略 提高泛化能力
  • 支持 多GPU训练
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐