
前段时间我花了一个周末把yolov8从环境搭建、官方权重推理再到自定义数据集训练完整跑通了。整个过程没有想象中那么难但坑确实不少。这篇文章把复现过程和一份可以直接复制使用的测试脚本一起分享出来给正准备上手yolov8的朋友一个参考。yolov8是当前目标检测领域绕不开的一个框架无论是做算法学习、毕设项目还是工业视觉落地它都是一个很好的起点。官方把训练、验证、推理、导出都封装在同一个库里接口非常统一这也是我选择用它做基准测试的原因。下面从整体思路开始说把我实际跑过的命令、配置、踩过的坑全部摆出来。1. 复现前的整体思路先理清yolov8要解决什么问题1.1 为什么选yolov8而不是更老版本很多初学者会纠结一个问题既然有yolov5、yolov6为什么直接上手yolov8我的判断标准很简单看项目维护活跃度和接口统一度。yolov8背后的ultralytics团队把检测、分割、分类三大任务集成到了一个包里训练和推理API都是同一套写法这对做工程的人来说太重要了。yolov5虽然生态成熟社区资料多但它的代码结构偏独立很多模块要自己改和后续版本之间的迁移成本也高。yolov6在工程部署上做了很多优化但官方迭代节奏不稳定一些版本的接口变化比较大。yolov8则是把Anchor-Free、C2f模块、解耦头这些结构都整合进去了检测精度和速度平衡得不错而且训练起来不需要手动处理复杂的锚框配置对复现阶段来说非常省心。另外还有一个很实际的原因yolov8官方仓库自带的数据集自动下载、权重自动下载、训练可视化这些能力都做得比较完整新手不需要额外写一堆工具函数就能跑通全流程。我个人复现项目的经验是工具链越少踩坑越少越容易把精力放在理解模型本身。1.2 复现路线图推理、数据集、训练三条线复现yolov8不是只跑一次官方demo就完事完整的复现应该拆成三条线。第一条线是环境与推理。先确认Python、PyTorch、CUDA版本匹配安装ultralytics包跑通官方权重在图片、视频上的推理。这条线主要验证环境没问题。第二条线是数据集制作。拿自己的数据或者公开数据集整理成yolo格式的标注文件写数据配置yaml让模型能读进去。很多人在这个环节卡住因为标注格式的细节比较多。第三条线是训练与验证。启动训练、看loss和mAP指标、用训练好的权重做测试集推理。这个环节最容易出现显存不足、参数不收敛等问题。三条线依次走完才算真正复现。只跑到推理就收工遇到自定义数据还是会一头雾水。后面的内容就按这个路线来组织。2. 环境配置与测试脚本设计2.1 环境依赖与安装版本避坑指南先说环境这是所有问题的源头。我的建议是优先用Linux系统如果没有GPU机器Windows也能跑CPU推理但训练速度会非常慢。我自己复现时用的是一张中端显卡显存8GB后面训练都按这个条件来设置参数。先列一份依赖清单都是我在实际环境里验证过的依赖项推荐版本说明Python3.8 - 3.113.12部分依赖还没适配好建议避开PyTorch2.0.0 - 2.2.02.0以上对CUDA支持更稳定CUDA11.8 或 12.1装PyTorch前先确认本机CUDA版本ultralytics8.0.0及以上直接用pip安装最新版即可其它依赖opencv-python、pillow、numpy安装ultralytics时会自动带安装命令很简单# 创建独立环境避免污染系统Python conda create -n yolo python3.10 conda activate yolo # 安装PyTorch这里以CUDA 11.8为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装yolov8框架 pip install ultralytics这中间最大的坑是CUDA版本和PyTorch版本的匹配。我的建议是先跑nvidia-smi看显卡驱动支持的CUDA版本再参照PyTorch官方给出的安装命令选择对应版本不要凭感觉装。装完以后用下面这行代码确认CUDA是否可用import torch print(torch.__version__, torch.cuda.is_available())如果输出True说明GPU环境没问题。我之前在这块吃过亏装了cpu版本的torch结果训练时一直用CPU跑一个epoch要半小时换回CUDA版本后同样的epoch只要两分钟。注意pip install ultralytics会自动安装匹配的PyTorch版本但自动装的往往是CPU版。如果你有NVIDIA显卡务必按上面的命令先装好GPU版PyTorch再装ultralytics。2.2 权重选择与推理API解析yolov8官方提供了n、s、m、l、x五种规格的预训练权重体积和精度递增。复现阶段建议先用最小的n模型跑通流程再根据需要切到更大的模型。模型参数量MCOCO mAP50大概数值适用场景yolov8n3.20.806算力有限、实时性要求高的场景yolov8s11.20.844一般实验和大部分落地项目yolov8m25.90.854精度优先的服务器推理yolov8l43.70.873高精度场景yolov8x68.20.888极致精度显存要求高选择依据很简单先看你的显存和推理设备的算力。显存8GB左右跑s和m没问题跑l和x训练会比较吃力。推理API是所有功能里最常用的只需要三行代码from ultralytics import YOLO model YOLO(yolov8n.pt) # 加载权重没有会自动下载 results model.predict(sourcebus.jpg, saveTrue)predict方法的常用参数我整理了一下conf是置信度阈值默认0.25低于这个值的检测框会被过滤掉iou是NMS的IoU阈值默认0.7控制重叠框的合并程度imgsz是输入尺寸默认640显存不够时可以调到480或320device用来指定设备0表示第一块GPUcpu表示CPUsaveTrue会自动保存标注后的结果图。2.3 可直接复制使用的测试脚本送出的测试脚本我放在了文章里逻辑很简单但把常用参数都暴露出来了方便你直接用。脚本支持图片、视频、文件夹三种输入输出结果自动保存到指定目录。我按“推理一张图片”这个刚需场景来设计脚本同时兼顾了后续扩展到批量推理的可能性。完整的测试脚本如下import argparse from pathlib import Path from ultralytics import YOLO def parse_args(): parser argparse.ArgumentParser(descriptionyolov8推理测试脚本) parser.add_argument(--weights, typestr, defaultyolov8n.pt, help模型权重文件路径) parser.add_argument(--source, typestr, defaultimages/demo.jpg, help推理图片、视频或文件夹路径) parser.add_argument(--conf, typefloat, default0.25, help置信度阈值越小检测出的目标越多) parser.add_argument(--iou, typefloat, default0.7, helpNMS交并比阈值控制重叠框合并) parser.add_argument(--imgsz, typeint, default640, help输入图片尺寸显存不足时可减小) parser.add_argument(--device, typestr, default0, help推理设备cpu或gpu编号如0) parser.add_argument(--output, typestr, default./runs/detect, help结果保存目录) return parser.parse_args() def main(): args parse_args() # 创建输出目录 output_dir Path(args.output) output_dir.mkdir(parentsTrue, exist_okTrue) # 加载模型 model YOLO(args.weights) # 批量推理 results model.predict( sourceargs.source, confargs.conf, iouargs.iou, imgszargs.imgsz, deviceargs.device, saveTrue, projectargs.output, nametest, exist_okTrue, ) # 打印每张图片的检测结果 for i, r in enumerate(results): boxes r.boxes if boxes is not None: print(f[{i}] 检测到 {len(boxes)} 个目标) for box in boxes: cls int(box.cls[0]) conf float(box.conf[0]) xyxy box.xyxy[0].tolist() print(f 类别 {cls} 置信度 {conf:.3f} 坐标 {xyxy}) if __name__ __main__: main()用法我实际演示一下假设你有一张测试图片bus.jpg放在当前目录的images文件夹下python test_detect.py --weights yolov8n.pt --source images/demo.jpg --conf 0.3脚本会自动下载权重第一次运行需要联网推理完成后在runs/detect/test目录下找到标注好的结果图。如果想把检测框的坐标信息打印出来上面这段代码已经帮你写好了。提示脚本里的--source参数也可以直接传0表示调用摄像头实时检测。这是验证模型效果最快的方式。3. 完整实操从推理到自定义训练3.1 跑通官方权重推理环境搭好以后第一步就是跑官方权重推理。我把测试脚本运行了一遍输入是官方仓库里常见的一张示例图片。第一次运行时模型权重会自动下载到当前目录大约6MB左右速度很快。推理结果会输出一个包含目标坐标、类别、置信度的列表。比如检测到一个人的置信度是0.9一辆公交车置信度是0.85说明模型工作正常。这里有一个小细节官方示例图里的目标是固定的所以第一次跑通只能说明环境没问题真正检验模型效果还要拿自己的图片测。我用手机拍了几张办公室的照片丢进去测。实际效果挺稳的常见的显示器、键盘、人、椅子都能准确框出来。不过也暴露了一个问题默认的0.25置信度阈值会对一些小目标产生很多误检框比如把远处的杯子误认为人。这时调高conf到0.4或者0.5误检会明显减少。另外还要注意一个点推理时如果不指定device框架会自动检测是否有GPU有就优先用GPU。如果你的机器有显卡但提示检测不到多半是PyTorch版本装成了CPU版按照2.1节的方法重新安装。3.2 自定义数据集制作与配置跑通了官方推理下一步就是自定义数据训练。这里需要把数据集整理成yolo格式。先看目录结构正确的方式是datasets/custom/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── custom.yamlimages和labels必须一一对应同名图片对应同名txt文件。比如images/train/cat_001.jpg对应labels/train/cat_001.txt。每个 txt 文件的内容格式是class_id x_center y_center width height注意x_center、y_center、width、height都是归一化坐标取值在0到1之间。比如一张宽1000像素、高800像素的图片上一个目标框的左上角是(200, 150)右下角是(500, 400)那么x_center (200500)/2/1000 0.35y_center (150400)/2/800 0.34375width (500-200)/1000 0.3height (400-150)/800 0.3125。我第一次做数据集时就栽在这里拿像素坐标直接写进txt训练了十个epoch才发现loss不下降。记住这个归一化的规律后期能省很多麻烦。标注工具方面我实际用的是LabelImg操作简单选择yolo格式保存即可。数据量少的时候也可以自己动手算坐标但是超过两三百张图就必须用工具了。数据集配置yaml文件内容如下path: ./datasets/custom train: images/train val: images/val names: 0: cat 1: dogpath建议写成绝对路径避免运行命令的工作目录和配置文件不一致导致的找不到数据问题。names就是你的类别列表顺序和txt里的class_id对应。3.3 训练启动与参数参考数据集准备好以后训练命令非常简单yolo detect train datacustom.yaml modelyolov8n.pt epochs100 imgsz640 batch8 device0这里modelyolov8n.pt有两个作用一是作为预训练权重的初始化二是在没有yolov8n.pt时自动下载。epochs是训练轮数batch是批次大小device指定GPU编号。参数的确定过程我解释一下因为这部分很多人不知道怎么选。batch大小的决定因素是显存。8GB显存跑yolov8n模型batch可以开到16如果跑yolov8m可能只能开到8以下。建议先跑一次看显存占用率再调整不要一上来就开到最大。imgsz默认640可以固定不动。epochs多少要看数据量几百张图的小数据集100轮基本够用上万张的大数据集可以只跑50轮然后看验证集的mAP是否还在上升。训练到一半时我会直接用命令行观察loss值yolo detect train datacustom.yaml modelyolov8n.pt epochs100 batch8yolov8训练时会输出box_loss、cls_loss、dfl_loss等指标。正常情况下这些数值都会逐渐下降。如果你看到loss不降反升大概率是数据集的标注出了问题要先检查txt文件里的坐标是否归一化、类别id是否在yaml配置的范围内。训练完成后runs/detect/train目录下会有模型权重文件best.pt和last.pt。验证集上mAP最高的权重保存在best.pt里测试阶段优先用这个。加载方式和之前一样model YOLO(runs/detect/train/weights/best.pt)3.4 训练参数速查表我把常用训练参数整理成表格方便你直接对照设置参数推荐值说明epochs100起步数据量大时可以适当减少batch8-16根据显存调整先小后大imgsz640全流程统一训练推理保持一致optimizerauto让框架自动选择lr00.01学习率默认即可device0指定GPU编号workers4-8数据加载线程数pretrainedTrue使用COCO预训练权重可以加速收敛其中pretrainedTrue是个容易忽略但很重要的配置。用自己的小数据集从零开始训练收敛很慢且精度不高而加载COCO预训练权重后相当于模型已经具备通用特征的识别能力只需要在基础上微调效果会好很多。4. 坑都踩完了问题汇总与排查思路4.1 高频报错对照表复现过程中我遇到了不少报错把它们列出来供你对照报错信息出现原因解决方法torch.cuda.is_available()返回FalsePyTorch装成了CPU版本重新安装对应CUDA版本的PyTorchmodule PIL.Image has no attribute ANTIALIASPillow版本过高降低Pillow版本pip install pillow9.5.0AssertionError: Label class 5 exceeds nc...标注里有超出类别范围的id检查txt文件确保类别id小于names配置数量CUDA out of memory显存不足降低batch或imgsz也可换成更小模型Downloading ... 卡住不动网络问题导致权重下载失败手动下载权重文件放入当前目录AttributeError: NoneType object has no attribute shape图片路径错误或读图失败检查source路径改用绝对路径FileNotFoundError: ... labels/....txt图片缺少对应标注文件补齐labels目录下的txt文件matplotlib font not found可视化字体缺失跑一次import matplotlib; matplotlib.font_manager._rebuild()最典型的还是第一次跑训练时遇到“Label class 5 exceeds nc”这个错误。当时我在txt里写了类别id5但yaml里的names只配置了4个类别id范围0-3。模型发现类别id超过nc直接报错。这种错误很难靠肉眼检查发现建议写个小脚本扫描所有txt文件找出超出范围的行。4.2 几条独家实战心得实操下来有几个心得是官方文档里不会写的但非常实用。第一复现任何一种模型先跑通最小闭环再优化。不要一开始就追求精度只有跑通了才能确认你的环境、数据、代码链路都是通的。我第一次接触yolov8时直接用了l模型结果显存溢出、训练时间超长排查了半天才发现是环境问题。后来改成n模型跑通再切到s模型整个过程顺畅很多。第二数据集质量比模型参数重要得多。yolov8的自监督能力很依赖标注质量。我在一个测试数据集上做过对比同样训练50轮把标注误差较大的样本修正后mAP从0.72直接提升到0.84。如果你花了大量时间调参效果依然不好先回头检查数据标注。第三用best.pt而不是last.pt。训练结束时保存的last.pt是最后一轮的权重而best.pt是验证集上表现最好的权重。两者可能差别很大尤其在数据量小、训练后期过拟合的情况下。推理测试时我习惯用best.pt这一步价值非常高。第四命令行和Python API是等价的但脚本化更适合复现。训练时用命令行方便直接观察输出推理时用Python脚本方便批处理、结果写入所以测试脚本建议保持下来后续的项目大概率还能复用。我在实际项目中用这套流程完成了一个模拟项目的目标检测验证从环境配置到最终跑出结果前后不到两天。yolov8这个框架最大的优点就是接口统一、生态成熟只要环境搭好后面基本都能顺利跑通。希望这份复现笔记能帮你少走点弯路如果你在复现过程中遇到其它问题不妨回头看一下是不是环境版本或数据格式导致的这两个方向覆盖了大多数坑。