简介
YOLO(you only look once)是一阶段目标检测模型的开山之作,在图像目标检测领域一向以响应速度快著称,它同是兼顾了模型的准确性,在两者之间做到很好的平衡。经过多版本迭代,到YOLOv8,是一个功能强大,受到广大开发者欢迎与喜爱的目标检测模型,另外,在同一套代码中,它可以分别实现图像分类、姿势识别、图像分割,并且在目标检测、姿势识别、图像分割模型基础上实现视频跟踪功能。通过在超参数指定如下参数:
task: segment 可选项:detect, segment, classify, pose,指定任务目标类型
mode: train 可选项:train, val, predict, export, track, benchmark 指定模式
model: # (str, optional) path to model file, i.e. yolov8n.pt, yolov8n.yaml 模型文件路径或模型配置文件路径
data: # (str, optional) path to data file, i.e. coco128.yaml 数据文件路径或数据配置文件路径
YOLOv8网络结构
上图为架构图,图最上面从左到右,包含Backbone(主干), Neck(颈部), Head(头部)三大部分.
Backbone由5个卷积模块,4个C2f模块, 1个SPPF模块组成,激活函数为SiLU。
整个卷积模块的作用为:
1 降采样:每个卷积模块中的卷积层都采用步长为2的卷积核进行降采样操作,以减少特征图的尺寸并增加通道数
2 非线性表示:每个卷积层之后都添加了batch normalization(批标准化)层和激活函数,以增强模型的非线性表示能力
SiLU(Sigmoid-weighted Linear Unit)函数的定义为f(x) = x * sigmoid(x),其中sigmoid(x)表示对x进行sigmoid运算。它是一个将输入值映射到0到1之间的非线性函数,且具有平滑和连续性质。
与ReLU相比,SiLU在保持非线性特性的同时,具有类似于Sigmoid函数的非饱和性、平滑性、梯度饱和性较低等优点。这些特性使得SiLU函数能够更好地处理梯度问题,并且在某些深度学习任务中可以取得更好的性能。在一些实验中,SiLU被证明可以提供更高的模型准确性和更快的收敛速度。
batch normalization的基本思想是:对每个小批量数据进行标准化,使得每个特征的均值为0,方差为1,然后再通过一个可学习的缩放因子和平移因子来调整数据的分布,从而使得神经网络更容易训练。
在YOLOv8的网络结构中C2f模块算是YOLOv8的一个较大改变,与YOLOv5的C3模块相比,C2f模块具有更少的参数量和更优秀的特征提取能力。下图为C2f结构图:
在C2f模块中我们可以看到,输入首先经过一个k=1,s=1, p=0, c=c_out的卷积模块进行了处理,然后经过一个split处理(在这里split和后面的concat的组成其实就是所谓的残差模块处理)经过数量为n的DarknetBottleneck模块处理以后将残差模块和主干模块的结果进行Concat拼接在经过一个卷积模块处理进行输出。
在其中提到的残差连接(residual connections)是一种用于构建深层神经网络的技术,它的核心思想是通过跳过层级连接来传递残差或误差。
在传统的神经网络中,信息流通过一层层的网络层,每一层都通过非线性激活函数进行转换和提取特征,然而,随着神经网络的加深,可能会出现“梯度消失”或“梯度爆炸”的问题,导致网络收敛困难或性能下降
残差连接通过引入跨层级的连接,将输入的原始信息直接传递到后续层级,以解决梯度消失和爆炸问题。具体而言,它将网络的输入与中间层的输出相加,形成了一个“捷径”或“跳跃连接”,从而允许梯度更容易地传播。
数学上,假设我们有一个输入x,通过多个网络层进行处理后得到预测值H(x),那么残差连接的表达式为:
F(x)=H(x)+x
其中,F(x)为残差块的输出, H(x)为经过一系列网络层处理后得到的特征表示,x为输入直接连接到残差块中的跳跃连接。
通过残差连接,网络可以更容易地学习残差或误差,从而使网络更深层次的特征表达更准确,这对于训练深层神经网络非常有用,可以提高网络的性能和收敛速度。
在C2f模块中用到的DarknetBottleneck模块其中使用多个3x3卷积核进行卷积操作,提取特征信息,同时其具有add是否进行残差链接的选项
其实整个C2f模块就是一个改良版本的Darknet
1首先,使用1x1卷积核将输入通道减少到原来的1/2,以减少计算量和内存消耗
2 然后,使用多个3x3卷积核进行卷积操作,提取特征信息
3 接着,使用残差链接,将输入直接加到输出中,从而形成了一条跨层连接
4 接着,再次使用1x1卷积核恢复特征图的通道数。
Neck部分的整体功能的详细分析如下:
1Neck的作用:
Neck部分在YOLOv8模型中负责对来自Backbone的特征进行进一步处理和融合,以提高目标检测的准确性和鲁棒性,它通过引入不同的结构和技术,将多尺度的特征图进行融合,以便更好地捕捉不同尺度目标的信息。
2 特征金字塔网络(Feature Pyramid Network, FPN):
3 特征融合(Feature Fusion):
4 上采样和下采样
YOLOv8的Neck部分通过特征金字塔网络和特征融合等操作,有效地提取和融合多尺度的特征,从而提高了目标检测的性能和鲁棒性,这使得模型能够更好地适应不同尺度和大小的目标,并在复杂场景下取得更准确的检测结果
PAN-FPN(具有特征金字塔网络的路径聚合网络)是一种用于计算机视觉中对象检测的神经网络架构。它将特征金字塔网络(FPN)与路径聚合网络(PAN)相结合,以提高目标检测的准确性和效率。
FPN用于从不同比例的图像中提取特征,而PAN用于跨网络的不同层聚合这些特征,这允许网络检测不同大小和分辨率的对象,并处理具有多个对象的复杂场景。
Head
如果Backone和Neck部分可以理解为准备工作,那么Head部分就是收获的部分,经过前面的准备工作我们得到了Neck部分的输出T1、T2、T3分别代表不同层级的特征图,Head部分就是对这三个特征图进行处理以产生模型的输出结果的一个过程。
在YOLOv8的Head部分,体现了最核心的改动-解耦头(Decoupled-Head),顾名思义就是将原先的一个检测头分解成两个部分。
在Head部分的三个解耦头分别对应着Neck部分的特征图输出T1、T2、T3.
解耦头的工作流程是
将网络得到的特征图T1、T2、T3分别输入解耦头进行,检测头的结构其中包含4个3x3卷积与2个1x1卷积,同时在检测头的回归分支中添加WIOU损失函数,回归头部需要计算预测框与真实框之间的位置偏移量,然后将偏移量送入回归头部进行损失计算,然后输出一个四维向量,分别表示目标框左上角坐标x y和右下角坐标x y.
分类头部针对每个anchor free提取的候选框对其进行Rol Pooling和卷积操作得到一个分类器输出张量每个位置上的值表示该候选框属于每个类别的概率,在最后通过非极大值抑制方式筛选出最终的检测结果。
本机训练、预测
1 训练:
代码如下:
from ultralytics import YOLO
# Load a model
model = YOLO("yolov8n.yaml") # build a new model from YAML
model = YOLO("yolov8n.pt") # load a pretrained model (recommended for training)
model = YOLO("yolov8n.yaml").load("yolov8n.pt") # build from YAML and transfer weights
# Train the model
results = model.train(data="coco8.yaml", epochs=100, imgsz=640)
在上述训练代码中,构建模型方式有三种:用模型配置文件、用模型文件或用模型配置文件加模型文件。在训练的时候指定数据配置文件。
在多GPU情况下,上面训练行代码可改用下面代码指定GPU:
# Train the model with 2 GPUs
results = model.train(data="coco8.yaml", epochs=100, imgsz=640, device=[0, 1])
如果训练任务是检测姿势关键点位置,在这里的results中会返回关键点坐标,当需要模型自动确认关键点坐标指明的是什么动作,在提示标注训练数据的时候,图像不仅要标注关键点坐标,还要标注同一个目标的关键点对应的动作名称,在获得results 返回后,需要用一个图像分类模型,以关键点坐标及标注的动作名称作为训练集进行动作分类训练,就是要训练姿势识别与动作分类两个模型。
- 推理:
代码如下:
from ultralytics import YOLO
# Load a model
model = YOLO("yolov8n.pt") # pretrained YOLOv8n model
# Run batched inference on a list of images
results = model(["im1.jpg", "im2.jpg"], stream=True) # return a generator of Results objects
# Process results generator
for result in results:
boxes = result.boxes # Boxes object for bounding box outputs
masks = result.masks # Masks object for segmentation masks outputs
keypoints = result.keypoints # Keypoints object for pose outputs
probs = result.probs # Probs object for classification outputs
obb = result.obb # Oriented boxes object for OBB outputs
result.show() # display to screen
result.save(filename="result.jpg") # save to disk
在这里,预测结果在results中返回,包含:检测框点的坐标、图像分割掩码、姿势识别关键点坐标、目标所属分类置信度等。如果要在图片上标注预测结果信息,可以用如下代码:
from ultralytics import YOLO
# Load a pretrained YOLOv8n model
model = YOLO("yolov8n.pt")
# Run inference on 'bus.jpg' with arguments
model.predict("bus.jpg", save=True, imgsz=320, conf=0.5)
如果训练任务是检测姿势关键点位置,在上面获取到目标的关键点坐标数据后,还要以这些数据作为测试集,调用前面提到的动作分类模型,以识别姿势分类。
- 导出指定格式
YOLO模型训练默认保存为.pt格式,可以通过导出成指定格式文件。常用的导出文件格式有:ONNX:全称为Open Neural Network Exchange,主要目的是促进不同深度学习框架之间的互操作性,使得AI模型能够在不同的环境和平台之间无缝迁移和部署。格式参数:onnx, 其他参数:imgsz, half, dynamic, simplify, opset, batch
TensorRT:用于在推理时候用TensorRT引擎加速,格式参数:engine, 其他参数:imgsz, half, dynamic, simplify, workspace, int8, batch
CoreML:用于IOS移动端应用,格式参数:coreml, 其他参数:imgsz, half, int8, nms, batch
TF Lite:用于安卓移动端应用,格式参数:tflite, 其他参数:imgsz, half, int8, batch
导出代码如下(ONNX):
from ultralytics import YOLO
# Load a model
model = YOLO("yolov8n.pt") # load an official model
model = YOLO("path/to/best.pt") # load a custom trained model
# Export the model
model.export(format="onnx", int8=True)
- 视频跟踪
代码如下:
from ultralytics import YOLO
# Load an official or custom model
model = YOLO("yolov8n.pt") # Load an official Detect model
model = YOLO("yolov8n-seg.pt") # Load an official Segment model
model = YOLO("yolov8n-pose.pt") # Load an official Pose model
model = YOLO("path/to/best.pt") # Load a custom trained model
# Perform tracking with the model
results = model.track("https://youtu.be/LNwODJXcvt4", show=True) # Tracking with default tracker
results = model.track("https://youtu.be/LNwODJXcvt4", show=True, tracker="bytetrack.yaml") # with ByteTrack
在上面,需要选择自己的模型文件构建模型。在跟踪时候,需要指定视频文件地址,还可以指定跟踪配置文件,有两种目标跟踪算法:botsort, bytetrack,默认是botsort。
botsort:一种基于Boosting的目标跟踪算法。它首先对每个帧进行目标检测,然后通过一个基于Boosting的目标跟踪器来跟踪目标。BoT-SORT的目标跟踪器采用了一个新的目标级联框架,可以有效地解决目标丢失问题。同时,BoT-SORT还提出了一种新的目标级联分配策略,可以在目标丢失的情况下快速重新分配目标。此外,BoT-SORT还采用了一个新的目标级联更新策略,可以实时地更新目标级联,从而提高跟踪精度。
bytetrack:一种基于tracking-by-detection范式的目标跟踪算法。它首先在视频中检测出目标对象,然后通过关联和重定位技术来跟踪目标对象。ByteTrack通过引入一个新的目标级联框架,将目标检测和跟踪问题转化为一个目标级联问题,从而有效地解决了目标跟踪中的目标丢失问题。同时,ByteTrack还提出了一种新的目标级联分配策略,可以在目标丢失的情况下快速重新分配目标。
ByteTrack和BoT-SORT都采用了目标级联框架来解决目标丢失问题,但ByteTrack采用的是目标级联分配策略,而BoT-SORT采用的是目标级联更新策略。两者都取得了很好的效果,并在许多实际应用中得到了验证。
model.track()函数可以指定检测框最大置信度(conf)、过滤重复检测框交并比(iou),如下:
results = model.track(source="https://youtu.be/LNwODJXcvt4", conf=0.3, iou=0.5, show=True,racker="bytetrack.yaml")
model.track()函数返回一个列表,列表中每个元素中包含boxs列表属性,boxs元素中有id,是目标跟踪id,用于在不同帧之间确定是否相同的目标。
详情可参考YOLOv8官方操作文档:https://docs.ultralytics.com/usage/python/
标签:视频,卷积,模型,YOLO,目标,实现目标,模块,model,YOLOv8 From: https://blog.csdn.net/heyiqiunet/article/details/141965033