005-建立 YOLO11n 基线:固定数据、参数、随机种子和结果目录

本文基于 Ultralytics 8.3.253 和 YOLO11n 进行整理,目的是在正式做注意力、Neck、Backbone、Loss 等改进前,先建立一套可重复对比的训练基线。后续所有改进实验都应该和这套基线在同一数据集、同一训练参数和同一评价方式下比较。

摘要

很多 YOLO 改进实验最容易忽略的一步,不是模块代码,而是 baseline。没有固定数据划分、随机种子、训练轮数、输入尺寸和结果目录,后面即使某个模块跑出了更高的 mAP,也很难判断是结构真的有效,还是训练条件发生了变化。

本文从工程复现实验的角度,使用 Ultralytics 8.3.253 中的 YOLO11n 作为基础模型,整理一套适合 Windows 环境的 baseline 建立流程。内容包括代码版本确认、数据集固定、训练参数固定、CLI 与 Python 两种训练方式、结果目录说明、实验记录表和常见问题排查。本文不填写任何虚构指标,所有 mAP、Precision、Recall 都以读者自己训练后的 results.csv 为准。

关键词: YOLO11、Ultralytics 8.3.253、YOLO11n、baseline、目标检测、results.csv、随机种子


一、为什么改进前必须先建立 baseline

后面做 YOLO11 改进时,经常会遇到下面几种情况:

  1. 加了注意力机制后 mAP50 变高,但 mAP50-95 没变;
  2. 换了 Neck 后参数量增加,训练显存也增加;
  3. 某个模块第一轮实验看起来有效,第二次复现又不明显;
  4. 只换了数据增强参数,却误以为是模型结构带来的提升。

这些问题本质上都和基线不稳定有关。一个合格的 baseline 至少要固定下面这些内容:

固定项为什么要固定
数据集划分train、val、test 一旦变化,指标不能直接比较
模型版本YOLO11n、YOLO11s 等模型规模不同,不能混着对比
代码版本Ultralytics 不同版本的训练参数和解析逻辑可能变化
训练轮数epoch 不一致会影响收敛程度
输入尺寸imgsz 会影响小目标、显存和速度
batchbatch 变化会影响训练稳定性和显存占用
随机种子减少随机初始化、数据加载顺序带来的波动
结果目录方便追踪每次实验的权重、曲线和日志

baseline 不是为了追求最高指标,而是为了让后面的每一次改动都有一个清楚的参照物。


二、本文使用的版本说明

本文统一使用以下工程环境:

项目说明
操作系统Windows 10 / Windows 11
YOLO 框架Ultralytics 8.3.253
基础模型YOLO11n
训练任务目标检测 detect
推荐安装方式源码可编辑安装 pip install -e .
主要结果文件args.yamlresults.csvresults.pngweights/best.ptweights/last.pt

如果后续你要改源码,例如注册新模块、修改 YAML 或改检测头,建议使用源码可编辑安装:

cd C:\Users\你的用户名\Downloads\ultralytics-8.3.253
pip install -e .

这条命令的作用是让当前 Python 环境直接使用本地源码目录。后续你修改 ultralytics/nn/tasks.pyultralytics/nn/modules/ 或模型 YAML 时,不需要每次重新打包安装。

安装完成后可以检查版本:

yolo checks

也可以用 Python 检查当前导入的是哪个路径:

import ultralytics

print(ultralytics.__version__)
print(ultralytics.__file__)

这里重点看两件事:版本是否为 8.3.253,以及 ultralytics.__file__ 是否指向你正在编辑的源码目录。


三、先固定数据集目录和 data.yaml

为了让后面的实验可以公平比较,数据集划分不要在每次实验前重新随机划分。建议第一次划分好以后,就固定目录结构:

datasets/
  my_dataset/
    images/
      train/
      val/
      test/
    labels/
      train/
      val/
      test/
    data.yaml

YOLO 标签文件需要和图片文件一一对应,例如:

images/train/000001.jpg
labels/train/000001.txt

data.yaml 可以按下面方式组织:

path: G:/datasets/my_dataset
train: images/train
val: images/val
test: images/test

names:
  0: class_a
  1: class_b

这几个字段要特别注意:

字段说明
path数据集根目录
train训练集图片路径
val验证集图片路径
test测试集图片路径,可按实际情况保留
names类别编号和类别名

后续做改进时,尽量不要临时替换 val。模型好不好,主要看它在同一个验证集上的表现。验证集变了,指标就不再是同一个参照系。


四、固定 YOLO11n baseline 训练参数

Ultralytics 8.3.253 默认训练参数中,seed=0deterministic=Trueepochs=100imgsz=640batch=16workers=8。这些默认值可以作为第一套基线的起点。

我建议把 baseline 明确写成下面这组参数:

参数baseline 建议值说明
modelyolo11n.pt使用官方 YOLO11n 预训练权重
data自己的 data.yaml固定同一份数据集配置
epochs100后续单模块实验保持一致
imgsz640常用输入尺寸,兼顾速度和效果
batch16显存不足时可以降低,但要记录
device0使用第 0 张显卡
workers8Windows 卡住时可改为 0 或 2
seed0固定随机种子
deterministicTrue尽量保持可复现
projectruns/yolo11_baseline单独存放基线结果
nameyolo11n_s0_e100_i640从目录名就能看出关键信息
exist_okFalse避免覆盖旧实验
ampTrue默认开启混合精度训练
plotsTrue保存曲线图和验证可视化结果

如果你的显卡显存较小,可以优先调整 batch,但不要同时改很多变量。比如从 batch=16 降到 batch=8,实验记录表中就要写清楚。


五、使用 CLI 启动 baseline 训练

在 Windows 终端中,可以使用下面命令启动训练:

yolo detect train model=yolo11n.pt data=G:/datasets/my_dataset/data.yaml epochs=100 imgsz=640 batch=16 device=0 workers=8 seed=0 deterministic=True project=runs/yolo11_baseline name=yolo11n_s0_e100_i640 exist_ok=False cache=False close_mosaic=10 amp=True plots=True

这条命令的重点不在于参数多,而是把会影响实验对比的参数全部显式写出来。

几个容易忽略的参数说明如下:

参数说明
seed=0固定随机种子,减少不同训练之间的随机波动
deterministic=True开启确定性相关设置,速度可能略慢,但更适合做对比实验
projectname控制结果保存位置,避免所有实验都堆在 runs/detect/train
exist_ok=False同名目录存在时不直接覆盖,防止旧结果被冲掉
cache=False第一套 baseline 先不缓存,避免不同机器内存条件影响复现
close_mosaic=10最后 10 个 epoch 关闭 mosaic,沿用当前默认思路

如果 Windows 下数据加载卡住,可以把 workers=8 改成:

workers=0

这会降低数据加载并行度,但能规避一部分 Windows 多进程问题。修改后要在实验表中记录,不要和 workers=8 的结果混在一起比较。


六、使用 Python 脚本启动 baseline 训练

如果你后续计划批量跑多个模型,建议把 baseline 写成一个固定脚本,例如 train_yolo11n_baseline.py

from ultralytics import YOLO


def main():
    model = YOLO("yolo11n.pt")

    model.train(
        data=r"G:\datasets\my_dataset\data.yaml",
        epochs=100,
        imgsz=640,
        batch=16,
        device=0,
        workers=8,
        seed=0,
        deterministic=True,
        project=r"runs\yolo11_baseline",
        name="yolo11n_s0_e100_i640",
        exist_ok=False,
        cache=False,
        close_mosaic=10,
        amp=True,
        plots=True,
    )


if __name__ == "__main__":
    main()

运行方式:

python train_yolo11n_baseline.py

这段脚本和 CLI 命令做的是同一件事。Python 写法的好处是后续可以复制一份脚本,把 modelname 改成改进模型的配置,其他参数保持不变。

例如后面写某个注意力模块时,只改:

model = YOLO("yolo11n_attention.yaml")
name = "yolo11n_attention_s0_e100_i640"

其他训练条件不动,这样对比才有意义。


七、训练完成后应该保存哪些文件

Ultralytics 8.3.253 训练完成后,结果目录大致如下:

runs/
  yolo11_baseline/
    yolo11n_s0_e100_i640/
      args.yaml
      results.csv
      results.png
      labels.jpg
      train_batch0.jpg
      val_batch0_labels.jpg
      val_batch0_pred.jpg
      confusion_matrix.png
      confusion_matrix_normalized.png
      weights/
        best.pt
        last.pt

几个关键文件的作用如下:

文件作用
args.yaml记录本次训练的全部参数,是复现实验的重要依据
results.csv每个 epoch 的 loss、Precision、Recall、mAP50、mAP50-95 等指标
results.png根据 results.csv 绘制的训练曲线
weights/best.pt根据验证指标保存的最佳权重
weights/last.pt最后一个 epoch 的权重,可用于断点续训
confusion_matrix.png混淆矩阵,用来观察类别混淆情况
val_batch*_pred.jpg验证集预测可视化图片

后续写改进文章时,建议至少保留 args.yamlresults.csvweights/best.pt。这三个文件能够说明实验是怎么跑的、指标是多少、权重在哪里。


八、建立一张自己的 baseline 记录表

建议为整个 YOLO11 改进系列单独建立一张表。第一行就是 baseline,后面每个模块依次追加。

实验编号模型配置改动位置seedepochsimgszbatchmAP50mAP50-95参数量GFLOPs备注
B001yolo11n.pt原始 YOLO11n010064016按真实结果填写按真实结果填写按模型输出填写按模型输出填写第一套 baseline

这里不要提前写提升百分比。baseline 训练完成后,再从 results.csv 中读取真实指标。

后续改进实验可以这样追加:

实验编号模型配置改动位置seedepochsimgszbatchmAP50mAP50-95参数量GFLOPs备注
A001yolo11n_xxx.yamlC3k2 后加入某模块010064016按真实结果填写按真实结果填写按模型输出填写按模型输出填写与 B001 对比

这样整理的好处是非常明显的:文章中可以清楚说明“我只改了模型结构,其他训练条件不变”。读者也能判断实验是否公平。


九、如何重新验证 baseline 权重

训练完成后,可以单独运行验证命令:

yolo detect val model=runs/yolo11_baseline/yolo11n_s0_e100_i640/weights/best.pt data=G:/datasets/my_dataset/data.yaml imgsz=640 batch=16 device=0 plots=True

这一步会重新在验证集上计算 Precision、Recall、mAP50 和 mAP50-95,并生成验证相关图像。

如果你想看预测效果,可以运行:

yolo detect predict model=runs/yolo11_baseline/yolo11n_s0_e100_i640/weights/best.pt source=G:/datasets/my_dataset/images/val imgsz=640 conf=0.25 device=0 save=True

注意,predictconf=0.25 主要用于推理展示,不能代替正式验证指标。正式写实验对比时,优先看 val 或训练过程中的 results.csv


十、断点续训和重新训练要分开

如果训练中断,可以使用:

yolo detect train resume model=runs/yolo11_baseline/yolo11n_s0_e100_i640/weights/last.pt

resume 是继续原来的训练,不是开启新实验。它会尽量沿用上一次训练保存的参数和优化器状态。

如果你要重新跑一套 baseline,建议换一个 name,例如:

name=yolo11n_s0_e100_i640_run2

不要直接覆盖原目录。baseline 一旦被覆盖,后面所有改进实验的参照物就不清楚了。


十一、常见问题

1. 为什么同样参数训练两次,结果还是有小幅波动

深度学习训练中仍然可能受到 CUDA 算子、数据加载、硬件环境等影响。seed=0deterministic=True 可以减少波动,但不代表所有机器上每个小数点都完全一致。

做改进实验时,重点看稳定趋势,不要只根据一次训练中的极小差异下结论。

2. batch 改了以后还能和 baseline 比吗

可以记录,但不建议直接作为公平对比。batch 会影响显存、梯度更新和训练稳定性。显存不足必须改 batch 时,建议 baseline 和改进模型都使用同一个 batch。

3. mAP50 提高但 mAP50-95 没提高,算不算有效

不能只看 mAP50。mAP50 的 IoU 阈值较宽松,mAP50-95 更严格,能更好反映定位质量。后面做结构改进时,建议同时记录 mAP50 和 mAP50-95。

4. 训练结果目录自动变成 train2、train3 怎么办

说明同名目录已经存在。为了避免覆盖旧结果,Ultralytics 会生成新的目录。建议自己显式设置 projectname,让每次实验的命名可读。

5. Windows 下训练卡在数据加载阶段

可以先把 workers 改成 02 试一下。如果这样能正常训练,说明大概率是多进程数据加载相关问题。改动后要记录在实验表中,后续对比实验也保持一致。


十二、总结

本文完成了 YOLO11n baseline 的建立流程:固定 Ultralytics 8.3.253 版本、固定数据集划分、固定训练参数、固定随机种子和结果目录,并整理了训练完成后需要保存的关键文件。

后续做 YOLO11 改进时,先不要急着比较“提升了多少”。正确顺序应该是:baseline 能稳定复现,改进模型能正常构建,训练参数完全一致,最后再用 results.csv 中的 Precision、Recall、mAP50 和 mAP50-95 做对比。

有了这套基线,后面的注意力机制、轻量卷积、Neck 融合、检测头和损失函数实验才会有统一参照。否则文章写得再热闹,也很难说明改进到底来自哪里。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐