1. 从YOLOv5到YOLOv8:一次“稳中求进”的架构演进
如果你在过去两年里接触过计算机视觉,尤其是目标检测,那么“YOLO”这个名字你一定不陌生。从Joseph Redmon大神开创的初代YOLO,到Alexey Bochkovskiy接棒后推出的YOLOv4、YOLOv5,这个系列以其“You Only Look Once”的极速推理特性,在工业界和学术界都占据了重要地位。而今天我们要聊的YOLOv8,由Ultralytics公司发布,它没有选择激进的、颠覆性的变革,而是在YOLOv5这个已经被市场充分验证的“地基”上,进行了一系列精密的“外科手术式”改进。这种“稳中求进”的策略,让YOLOv8在发布之初就获得了极高的接受度,因为它既继承了YOLOv5易用、高效、生态成熟的优点,又在精度、速度和灵活性上带来了实实在在的提升。对于开发者、研究员和工程师来说,理解YOLOv8的架构,不仅仅是学习一个新模型,更是理解现代目标检测模型在工程化道路上如何平衡创新与稳定性的绝佳案例。
YOLOv8的定位非常清晰:它是一个生产就绪的框架。这意味着,从数据准备、模型训练、验证到部署,Ultralytics提供了一套完整的、高度封装的工具链。你不再需要像早期那样,花费大量时间在数据加载、损失函数调试、后处理代码上“拧螺丝”,而是可以更专注于业务逻辑和模型调优本身。这种“开箱即用”的特性,极大地降低了目标检测技术的应用门槛。无论是想用1000张行人图片训练一个安防模型,还是在RK3588这类边缘计算芯片上部署一个轻量化版本,YOLOv8都提供了清晰的路径和丰富的文档支持。接下来,我们就抛开那些泛泛而谈的“精度提升X%”的宣传,深入到YOLOv8的架构内部,看看它到底做了哪些关键的改动,以及这些改动背后的设计逻辑是什么。
2. 核心架构拆解:Backbone、Neck与Head的协同升级
YOLOv8的整体架构依然遵循了目标检测领域经典的“Backbone(主干网络)- Neck(颈部)- Head(检测头)”范式。这种结构分工明确:Backbone负责从输入图像中提取多层次的特征;Neck负责融合和增强这些不同尺度的特征,为检测头提供更丰富的上下文信息;Head则最终负责输出目标的类别和位置。YOLOv8的改进渗透在这三个部分的每一个环节。
2.1 Backbone:CSPDarknet的深度优化与C2f模块的引入
YOLOv8的Backbone基于YOLOv5的CSPDarknet架构,但进行了关键模块的替换。最显著的变化是将原始的C3模块(Cross Stage Partial Network with 3 convolutions)替换为了C2f模块。要理解这个变化,我们得先回顾一下CSP结构的设计初衷。CSPNet(Cross Stage Partial Network)的核心思想是通过将特征图分割为两部分,一部分经过复杂的残差块处理,另一部分直接进行恒等映射(shortcut),最后再将两部分融合。这样做的好处是能在几乎不增加计算量的情况下,极大地增强梯度的流动,缓解深层网络的梯度消失问题,从而让网络可以做得更深、更强大。
YOLOv5的C3模块是CSP结构的一个具体实现。而YOLOv8的C2f模块可以看作是C3模块的一个更灵活、更高效的变体。这里的“f”代表“faster”或更广义的“flexible”。从结构上看,C2f模块同样采用了跨阶段部分连接的思想,但它通常包含了更多的分支和更丰富的短路连接。具体来说,C2f模块可能采用了更高效的瓶颈(Bottleneck)设计,或者在特征融合阶段引入了类似注意力机制的轻量化操作,以提升特征提取的效率。这种改动带来的直接收益是,在相似的参数量和计算量下,模型能够捕捉到更细微的特征差异,这对于检测小目标或者区分相似类别的物体(比如不同品种的狗)尤为重要。在实际训练中,你会发现使用C2f模块的模型,其损失函数曲线(尤其是定位损失)往往下降得更平滑、更稳定。
2.2 Neck:SPPF的极致优化与特征金字塔的增强
Neck部分,YOLOv8继承了并强化了YOLOv5的路径聚合网络(Path Aggregation Network, PANet)结构。PANet的核心是在特征金字塔网络(FPN)自顶向下传递语义信息的基础上,增加了一个自底向上的路径,将底层的细节信息(如边缘、纹理)也传递到高层。这种双向的信息流确保了无论是大目标(需要强语义)还是小目标(需要细粒度细节),检测头都能获得充足的信息。
YOLOv8在Neck中的一个重要细节优化是广泛使用了SPPF(Spatial Pyramid Pooling Fast)模块,替代了原先的SPP模块。SPP模块的提出是为了解决卷积神经网络对输入尺寸敏感的问题,它通过不同尺度的池化核(如5x5, 9x9, 13x13)对特征图进行池化,然后将结果拼接起来,从而让网络能够适应不同尺度的输入,并提取多尺度的上下文信息。然而,原始SPP模块是串行执行这些不同尺寸的池化操作,计算上并非最优。
SPPF模块则巧妙地将其改为串行重复使用多个小尺寸池化核(通常是5x5)来实现与大尺寸池化核相同的感受野。例如,两个5x5的MaxPool层串联,其等效感受野是9x9;三个串联,等效感受野就是13x13。这样做有什么好处?首先,计算效率更高。多个小卷积/池化核的串联通常比单个大核的参数更少、计算更快。其次,引入了更多的非线性激活函数。每个池化层后通常跟有激活函数,更多的串联意味着更复杂的非线性变换能力,可能有助于模型学习更复杂的模式。在实际的代码中,你会看到类似这样的结构:一个特征图先后通过三个kernel_size=5的MaxPool2d层,然后将输入和三个池化后的输出在通道维度上进行拼接。这个改动非常典型地体现了YOLO系列“工程优化”的哲学:用更聪明、更高效的方式实现相同甚至更好的效果。
2.3 Head:Anchor-Free与解耦头的最终统一
Head部分的变革是YOLOv8最具标志性的改动之一:它彻底抛弃了Anchor Box(锚框)机制,转向了Anchor-Free(无锚框)的范式,并且采用了目前主流的解耦头(Decoupled Head)设计。
为什么放弃Anchor?Anchor机制曾是YOLOv2-v5系列成功的基石。它通过预设一系列不同尺度和长宽比的先验框,让网络去学习基于这些先验框的偏移量,从而预测目标框。它的优势是训练稳定,尤其对于密集场景。但缺点也很明显:1)超参数敏感:Anchor的尺寸、数量和长宽比需要根据数据集精心设计,用COCO数据集上设定的Anchor去检测行人或牛奶纸盒,效果可能大打折扣。2)计算冗余:会生成大量负样本(背景锚框),加剧正负样本不平衡问题。3)灵活性差:对于极端长宽比的目标(如旗杆、火车)难以匹配。
YOLOv8转向了类似于YOLOX和FCOS的Anchor-Free方式。它直接让每个网格点(或特征点)预测目标中心点距离该点的偏移量,以及目标框的宽高。具体来说,对于特征图上的每一个位置,Head直接输出4个值(tx, ty, tw, th)来表示预测框。这种方式简化了设计,减少了对数据集的依赖,使得模型更容易迁移到新的领域(比如从通用物体检测迁移到工业缺陷检测)。
解耦头又是什么?在YOLOv5及以前,分类和回归任务是共享同一个卷积头的,我们称之为“耦合头”。而解耦头则为分类(判断是什么类别)和回归(预测框的位置和大小)分别使用独立的小型分支网络。这样做最直观的好处是,分类和回归任务不再相互干扰。想象一下,一个负责判断“这是不是狗”的神经元,和另一个负责判断“狗的边界框有多精确”的神经元,它们关注的特征可能是不同的。解耦头让这两个任务可以各自优化自己的参数,在实践中通常能带来精度上的提升,尤其是对于分类和定位难度不一致的场景。YOLOv8的解耦头设计通常包含几个共享的底层卷积,然后分叉成两个独立的卷积分支,分别输出类别置信度和边界框坐标。
将Anchor-Free和解耦头结合,YOLOv8的Head输出维度也发生了变化。假设有80个类别,对于输入图像,经过Neck后得到三个不同尺度的特征图(例如80x80, 40x40, 20x20)。对于每一个尺度的特征图上的每一个点,Head会输出:4个回归值(框的坐标)+ 80个分类值(类别概率)。这种设计清晰、简洁,且与现代检测框架的主流设计接轨。
3. 损失函数与训练策略的精细化调整
架构的改进需要匹配相应的训练策略才能发挥最大效力。YOLOv8在损失函数和训练技巧上也做了不少文章,这也是为什么网上会有“yolov8 改进损失函数”这样的搜索热词。
3.1 损失函数的组成:CIoU、BCE与DFL
YOLOv8的损失函数主要由三部分组成:边界框回归损失(Box Loss)、分类损失(Cls Loss)和分布焦点损失(DFL Loss)。
边界框回归损失:YOLOv8默认使用CIoU Loss。IoU(交并比)是衡量两个框重叠程度的直接指标,但IoU本身作为损失函数存在梯度消失的问题(当两个框不重叠时,IoU=0,梯度也为0)。CIoU(Complete IoU)在IoU的基础上,增加了对中心点距离和长宽比一致性的惩罚项。它同时考虑了三要素:重叠面积、中心点距离和纵横比,使得边界框的回归更加精准。相比于YOLOv5使用的GIoU,CIoU通常能带来更快的收敛速度和更优的定位精度,尤其是在目标框与锚框(或Anchor-Free下的网格点)初始位置偏差较大时。
分类损失:YOLOv8使用标准的二元交叉熵损失(Binary Cross-Entropy Loss, BCE),而不是YOLOv5中使用的Focal Loss。这似乎是一个“倒退”,但其实有其考量。Focal Loss是为了解决单阶段检测器中极端的前景-背景类别不平衡问题而设计的,它通过降低大量简单负样本的权重,让模型更关注难分的样本。然而,在YOLOv8转向Anchor-Free并配合更优的正负样本分配策略(如TaskAlignedAssigner)后,类别不平衡问题得到了有效缓解。此时,简单稳定的BCE Loss可能比需要调整两个超参数(α和γ)的Focal Loss更具鲁棒性,也更容易调优。在实际训练中,使用BCE Loss的模型,其分类损失曲线往往更平滑。
分布焦点损失(Distribution Focal Loss, DFL):这是YOLOv8损失函数中一个比较新颖的组成部分。在传统的边界框回归中,我们直接回归一个连续的坐标值(如中心点x坐标)。而DFL的思想是将回归问题转化为分类问题。具体来说,它不再直接预测一个值,而是预测这个值的一个离散概率分布。例如,对于框的宽度w,网络会输出n个值,表示w落在n个预定义区间(bins)的概率。最终的预测值是通过对概率分布求期望得到的。DFL的好处在于,它让网络学习到了边界框位置的不确定性。对于难以确定精确边界的模糊目标(比如毛茸茸的猫的边缘),网络预测的概率分布可能会更平缓;对于边界清晰的目标,分布则会非常尖锐。这种表示方式提供了更丰富的监督信息,有助于提升回归精度,尤其是对于小目标。
3.2 训练技巧:Mosaic增强、余弦退火与EMA
除了损失函数,YOLOv8继承并优化了一系列成熟的训练技巧:
Mosaic数据增强:这是YOLO系列的一大“杀器”。它将四张训练图像随机拼接成一张,极大地丰富了单张图片内的场景和目标上下文,同时引入了不同的尺度变化。这相当于在一个批次(batch)内实现了“小批量”的尺度不变性训练,对提升模型鲁棒性,特别是检测不同尺度目标的能力至关重要。YOLOv8在训练初期(如前150个epoch)会使用Mosaic,后期则关闭,以让模型更好地拟合真实的单图分布。
余弦退火学习率调度:学习率是训练神经网络最重要的超参数之一。YOLOv8使用余弦退火策略,让学习率随着训练进程,像余弦曲线一样从初始值平滑地下降到接近0。这种策略有助于模型在训练后期更精细地收敛到最优解附近,避免震荡。相比于阶梯式下降,余弦退火通常能获得更好的最终精度。
指数移动平均(EMA):EMA是一种模型参数更新策略。它并不直接使用每次梯度下降得到的新参数,而是维护一个“影子参数”,这个影子参数是历史参数和当前参数的加权平均。在训练过程中,EMA模型往往比最终训练得到的模型具有更好的鲁棒性和泛化能力。在YOLOv8中,验证和保存的最佳模型通常就是EMA模型。
注意:很多用户在尝试“yolov8画损失函数曲线图”时,会发现Ultralytics框架内置的日志和可视化工具(如TensorBoard或ClearML集成)已经非常完善。训练过程中的Box Loss、Cls Loss、DFL Loss以及各自的组成部分都会被详细记录。分析这些曲线是调参的关键:如果Box Loss居高不下,可能是定位任务太难,需要检查标注质量或调整回归损失权重;如果Cls Loss震荡剧烈,可能需要调整分类损失函数或数据增强策略。
4. 模型家族与轻量化设计:从Nano到X的全场景覆盖
和YOLOv5一样,YOLOv8也提供了一个完整的模型缩放家族,以满足从嵌入式设备到云端服务器的不同算力需求。这个家族通常包括:YOLOv8n (Nano), YOLOv8s (Small), YOLOv8m (Medium), YOLOv8l (Large), YOLOv8x (Extra Large)。
它们的区别主要在于网络的深度(模块堆叠层数)和宽度(通道数)。例如,YOLOv8n的Backbone和Neck中的通道数最少,C2f模块中Bottleneck的重复次数也最少;而YOLOv8x则拥有最深的层数和最宽的通道。这种设计使得用户可以根据自己的硬件条件和精度要求进行灵活选择。在RK3588或Jetson Orin这类边缘计算设备上部署时,YOLOv8n或YOLOv8s是首选;而在服务器端追求极致精度时,则可以选择YOLOv8x。
轻量化不仅仅是缩放模型尺寸。YOLOv8的轻量化思路还体现在架构层面。例如,其使用的C2f和SPPF模块本身就比一些传统模块更高效。此外,社区和研究者们也在YOLOv8的基础上进行了大量的轻量化改进尝试,这也就是“yolov8轻量化”成为热词的原因。常见的轻量化手段包括:
- 通道剪枝(Channel Pruning):通过评估神经元或通道的重要性,剪掉那些对输出贡献小的冗余通道,从而减少模型参数量和计算量。
- 知识蒸馏(Knowledge Distillation):用一个庞大的、精度高的教师模型(如YOLOv8x)去指导一个小型的学生模型(如YOLOv8n)进行训练,让学生模型模仿教师模型的输出和行为,从而获得接近大模型的精度。
- 神经网络架构搜索(NAS):自动搜索更高效的模块或连接方式。例如,将部分标准卷积替换为深度可分离卷积(Depthwise Separable Convolution),可以大幅减少计算量。
- 注意力机制的精简集成:虽然“yolov8分割模型加注意力机制”是改进方向,但注意力模块(如SE、CBAM、CA)本身会增加计算开销。轻量化设计中,需要选择或设计更轻量的注意力变体,或者将其只添加到关键层中。
对于希望在资源受限环境(如STM32单片机或K230开发板)部署YOLOv8的开发者来说,选择预定义的轻量模型(如nano版)是第一步,后续往往还需要结合模型压缩工具(如TensorRT、OpenVINO、NCNN、TNN等)进行进一步的量化(INT8/FP16)和优化,才能达到实时性的要求。
5. 实战:从环境配置到自定义数据集训练
理解了架构,最终还是要落地到应用。我们以在Ubuntu系统上训练一个自定义数据集(比如“牛奶纸盒检测”)为例,串联起YOLOv8的核心使用流程。
5.1 环境配置与源码安装
虽然可以通过pip直接安装ultralytics包,但对于想深入研究或进行定制化开发的用户,从源码安装是更好的选择。这对应了热搜词“ubuntu 源码安装ultralytics yolov8”。
# 1. 克隆仓库 git clone https://github.com/ultralytics/ultralytics.git cd ultralytics # 2. 创建并激活Python虚拟环境(强烈推荐) python3 -m venv yolov8_env source yolov8_env/bin/activate # 3. 安装PyTorch(请根据你的CUDA版本到PyTorch官网选择对应命令) # 例如,对于CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 4. 安装Ultralytics包及其依赖 pip install -e . # ‘-e’代表可编辑模式,方便修改源码 # 5. 验证安装 python -c “from ultralytics import YOLO; print(YOLO(‘yolov8n.pt’))”提示:使用虚拟环境可以避免包依赖冲突。如果遇到权限问题,不要在命令前加
sudo,而是确保你在虚拟环境中操作。安装后,ultralytics这个包就关联到了你本地的源码目录,任何对源码的修改都会立即生效。
5.2 准备自定义数据集
YOLOv8要求数据集遵循特定的格式。假设我们的项目是检测牛奶纸盒,我们需要准备约1000张图片(“yolov8 1000张 数据集”)。
目录结构:创建一个
milk_carton_dataset文件夹,内部结构如下:milk_carton_dataset/ ├── images/ │ ├── train/ │ │ ├── 001.jpg │ │ └── ... │ └── val/ │ ├── 101.jpg │ └── ... └── labels/ ├── train/ │ ├── 001.txt │ └── ... └── val/ ├── 101.txt └── ...标注格式:每个
.txt文件对应一张图片,每行代表一个标注对象,格式为:<class_id> <x_center> <y_center> <width> <height>。这里的坐标是归一化后的,即相对于图片宽高的比例值(范围0-1)。例如,如果图片宽640像素,高480像素,一个目标框的中心点在(320, 240),宽100像素,高80像素,那么对应的标注行应为:0 0.5 0.5 0.15625 0.166667(假设类别ID0代表牛奶纸盒)。可以使用LabelImg、CVAT或Roboflow等工具进行标注。数据集配置文件:创建一个YAML文件(如
milk_carton.yaml),用于告诉YOLOv8数据集的位置和类别信息。# milk_carton.yaml path: /home/user/datasets/milk_carton_dataset # 数据集根目录 train: images/train # 训练集图片路径(相对于path) val: images/val # 验证集图片路径(相对于path) # test: images/test # 可选,测试集 # 类别列表 names: 0: milk_carton # 如果有多个类别,继续往下写 # 1: water_bottle # 2: can
5.3 模型训练与关键参数解析
准备好数据和配置文件后,训练就变得非常简单。你可以使用命令行接口(CLI)或Python API。
使用Python API(更灵活):
from ultralytics import YOLO # 加载一个预训练模型 model = YOLO(‘yolov8s.pt’) # 使用小模型作为起点 # 开始训练 results = model.train( data=‘/path/to/milk_carton.yaml’, epochs=100, # 训练轮数 imgsz=640, # 输入图像尺寸 batch=16, # 批次大小,根据GPU内存调整 workers=8, # 数据加载线程数 device=‘0’, # 使用GPU 0,如果是CPU则设为‘cpu’ project=‘milk_carton_det’, # 项目名称 name=‘exp1’, # 实验名称 pretrained=True, # 使用预训练权重(强烈推荐) optimizer=‘AdamW’, # 优化器,可选SGD, Adam, AdamW等 lr0=0.01, # 初始学习率 cos_lr=True, # 使用余弦退火学习率调度 label_smoothing=0.1, # 标签平滑,防止过拟合 dropout=0.2, # 分类头中的Dropout率(仅部分模型支持) amp=True, # 自动混合精度训练,节省显存并加速 )关键参数解析:
imgsz: 网络输入尺寸。更大的尺寸通常能带来更好的精度,尤其是对小目标,但会显著增加显存消耗和计算时间。640是一个在精度和速度间取得良好平衡的常用值。batch: 批次大小。在GPU内存允许的情况下,较大的批次通常能使训练更稳定,但可能会影响泛化能力。如果出现内存不足(OOM)错误,首先尝试减小batch或imgsz。pretrained=True: 这是迁移学习的关键。从在COCO等大型数据集上预训练的模型开始,能让你的模型快速收敛,并大幅提升在小数据集(如你的1000张牛奶纸盒图)上的性能。amp=True: 自动混合精度训练。它让模型的部分计算使用半精度浮点数(FP16),在几乎不影响精度的情况下,可以节省约50%的显存,并提升训练速度。这是现代GPU训练的标配。
训练开始后,所有日志、损失曲线、模型权重都会保存在runs/detect/exp1(根据你的project和name参数)目录下。你可以使用TensorBoard实时监控训练过程。
5.4 模型验证、预测与导出
训练完成后,你需要评估模型在验证集上的表现。
# 在验证集上评估最佳模型 metrics = model.val() # 默认会使用训练时保存的最佳模型(best.pt) print(metrics.box.map) # 打印mAP50-95 # 使用模型进行预测 results = model(‘path/to/test_image.jpg’, save=True) # 预测并保存结果图片 # 遍历结果 for result in results: boxes = result.boxes # 边界框信息 masks = result.masks # 分割掩码(如果使用分割模型) keypoints = result.keypoints # 关键点(如果使用姿态模型) probs = result.probs # 分类概率 # 可以访问具体的属性,如 boxes.xyxy, boxes.conf, boxes.cls对于部署,你需要将PyTorch模型导出为其他格式。YOLOv8支持一键导出到多种格式:
# 导出模型 model.export(format=‘onnx’) # 导出为ONNX格式 # 还可以导出为 TensorRT, OpenVINO, CoreML, TFLite 等 # model.export(format=‘engine’, imgsz=640, device=0) # 导出为TensorRT引擎导出的ONNX或TensorRT模型就可以用于在RK3588、Jetson、Android手机等各种边缘设备上进行高效推理了。例如,在RK3588上,你可以使用RKNN Toolkit将ONNX模型转换并部署。
6. 常见问题排查与调优经验
在实际使用YOLOv8的过程中,你肯定会遇到各种各样的问题。下面分享几个我踩过的坑和对应的解决思路。
6.1 训练损失不下降或出现NaN
这是最常见的问题之一。
- 检查数据标注:这是首要怀疑对象。使用
YOLO框架提供的model.train(data=‘coco128.yaml’)**先在一个标准小数据集(如COCO128)上跑一个epoch,看损失是否正常下降。如果正常,那问题大概率出在你的自定义数据集上。仔细检查标注文件(.txt)格式是否正确,坐标值是否在0-1之间,是否有空标签文件,图片和标签是否一一对应。 - 学习率过高:过高的初始学习率(
lr0)可能导致优化过程在最优解附近震荡甚至发散,损失出现NaN。尝试将lr0降低一个数量级(例如从0.01降到0.001)再试。 - 梯度爆炸:如果使用了AMP混合精度训练,在极少数情况下可能导致梯度爆炸。可以尝试在训练命令中加入
--amp False关闭AMP,看问题是否消失。如果消失,可能是模型某部分对FP16数值不稳定,可以尝试使用更稳定的AMP模式(如O2)。 - 数据异常:检查训练集中是否有损坏的图片(无法解码),或者像素值范围异常的图片(如全黑、全白)。
6.2 模型过拟合:在训练集上表现好,验证集上差
过拟合意味着模型只是记住了训练数据,而没有学到泛化规律。
- 增加数据增强:YOLOv8默认已经开启了较强的数据增强(Mosaic, MixUp, 色彩抖动等)。如果仍过拟合,可以尝试在
model.train()中调整增强参数,例如增加hsv_h,hsv_s,hsv_v(色调、饱和度、明度抖动)的幅度,或者增加translate(平移)和scale(缩放)的范围。 - 使用更小的模型:对于小数据集(如几千张图片),使用YOLOv8x这样的大模型很容易过拟合。尝试换用YOLOv8n或YOLOv8s。
- 正则化:增加权重衰减(
weight_decay)参数,或者在支持Dropout的模型版本中增加dropout率。 - 早停(Early Stopping):监控验证集损失(val_loss),当其在连续多个epoch不再下降时,就停止训练。Ultralytics框架在训练时会自动保存验证集性能最好的模型(
best.pt),这本身也是一种早停策略。
6.3 小目标检测效果差
如果你的数据集中有很多小尺寸的牛奶纸盒(在图像中占比很小),那么默认设置可能效果不佳。
- 增大输入尺寸:将
imgsz从640提高到1280甚至更高。这会显著增加计算开销,但能为小目标提供更多的像素信息。 - 调整Anchor-Free参数:虽然YOLOv8是Anchor-Free,但其在特征金字塔不同层级上分配正样本的策略(TaskAlignedAssigner)有相关阈值参数。不过,Ultralytics API没有直接暴露这些参数。更实用的方法是修改模型结构,增加对小目标的检测层。这需要修改模型配置文件(
.yaml),增加一个更浅、分辨率更高的检测头(P2层)。这是一个进阶操作,需要你对网络结构有较深理解。 - 检查数据标注质量:小目标的边界框标注难度大,容易出现标注不一致或错误的情况,这会严重影响模型学习。务必确保小目标的标注尽可能精确。
6.4 部署到边缘设备速度慢
在RK3588或树莓派上部署时,即使使用了YOLOv8n,可能也无法达到实时(如30 FPS)。
- 模型量化:将FP32模型量化为INT8是加速推理最有效的手段之一。可以使用TensorRT、OpenVINO或RKNN Toolkit等工具进行后训练量化(PTQ)或量化感知训练(QAT)。INT8推理通常能带来2-4倍的速度提升,且精度损失可控。
- 降低输入分辨率:将推理时的
imgsz从训练时的640降到320或416。这会牺牲一些精度,尤其是小目标检测精度,但能大幅提升速度。 - 利用硬件加速:确保你的推理引擎充分利用了目标硬件的所有计算单元。例如,在RK3588上使用RKNN,在Jetson上使用TensorRT,在Intel CPU上使用OpenVINO,在苹果芯片上使用CoreML。
- 批处理(Batch Inference):如果应用场景允许(如处理视频流),一次处理多帧图片(一个batch)的吞吐量远高于逐帧处理。