自从yolov系列模型发布以来,平均按照每年更新一次的版本来更新yolov系列模型,但是yolo的作者已经参与其系列模型的更新了,而后期的模型更新都是不同的团队在yolo系列模型上来更新,只是大家按照一个约定俗成的做法,在前任的基础上,更新YOLO系列的版本号。
YOLOv9模型简介
YOLOv9 是Chien-Yao Wang 等人提出的 YOLO 系列的最新版本。 于 2024 年 2 月 21 日发布。它是 YOLOv7 的改进,两者均由 Chien-Yao Wang 及其同事开发。 YOLOv7 通过所谓的可训练bag-of-freebies在优化训练过程方面取得了重大进展,有效提高了训练效率,从而在不增加推理成本的情况下提高了对象检测的准确性。然而,YOLOv7 并没有专门解决输入数据前馈过程中的信息丢失问题,这一挑战被称为信息瓶颈。这个问题是由网络中的缩减操作引起的,这可能会稀释重要的输入数据。
现有的解决方案如可逆架构、掩模建模和深度监督有助于减少信息瓶颈,但上述方法在训练和推理过程中存在不同的缺点。它对于较小的模型架构也不太有效,而这对于 YOLO 系列中的实时目标检测器至关重要。为了克服这些挑战,YOLOv9引入了可编程梯度信息(PGI)和通用高效层聚合网络(GELAN)两种创新技术,直接解决信息瓶颈问题,提高目标检测的准确性和效率。
YOLOv9框架引入了一种创新方法,通过深度学习解决目标检测的核心挑战,主要关注网络架构中的信息丢失和效率问题。该方法有四个关键组成部分:信息瓶颈原理、可逆函数、可编程梯度信息(PGI)和广义高效层聚合网络(GELAN)。基于以上分析,需要一种新的深度神经网络训练方法,既能生成可靠的梯度来更新模型,又能适用于浅层和轻量级神经网络。可编程梯度信息(PGI)是一种解决方案,包括用于推理的主分支、用于可靠梯度计算的辅助可逆分支以及多级辅助信息,可有效解决深度监督问题,而无需增加额外的推理成本。
在 YOLOv9 中引入可编程梯度信息 (PGI) 后,对更精细架构的需求变得显而易见。这就是通用高效层聚合网络(GELAN)发挥作用的地方。 GELAN代表了一种适合PGI框架的独特设计,增强了模型更有效地处理和学习数据的能力。由于 PGI 解决了在深度神经网络中保留关键信息的挑战,GELAN 在此基础上提供了支持各种计算模块的灵活高效的结构。
YOLOv9 中的广义高效层聚合网络 (GELAN)结合了CSPNet梯度路径规划的最佳功能与ELAN 的推理速度优化。 GELAN 代表了一种多功能架构,它融合了这些属性并增强了 YOLO 系列标志性的实时推理能力。 GELAN 是一个轻量级框架,在不牺牲准确性的情况下优先考虑快速推理时间,从而扩展了计算块的应用。
SPPELAN 模块:该模块介绍了一种通过在 ELAN 结构中合并空间金字塔池(SPP) 来进行层聚合的方法。它从调整通道维度的卷积层开始,然后是一系列空间池化操作以捕获多尺度上下文信息。输出被连接并通过另一个卷积层以巩固特征,优化网络从各种空间层次结构中提取详细特征的能力。
RepNCSPELAN4 模块:该组件代表了 CSP-ELAN 的高级版本,旨在进一步简化特征提取过程。它将来自初始卷积层的输入分成两条路径,通过一系列RepNCSP和卷积层处理每条路径,然后将它们合并回来。这种双路径策略有利于高效的梯度流和特征重用,通过确保深度而显著提高模型的学习效率和推理速度,而不会产生通常与复杂性增加相关的计算损失。
GELAN架构将CSPNet的梯度效率和ELAN的速度导向架构融合成一个统一的框架,支持更广泛的计算块。这种灵活性使 YOLOv9 能够适应不同的计算环境和任务,保持高精度和速度。基于以上的各个功能模型,大大提高了YOLOv9系列模型的精度,在各个数据集上实现了很好的效果。
YOLOv9模型发布了5个不同尺寸大小的模型,分别是YOLOv9-T轻量型,YOLOv9-s小型,YOLOv9-M中型模型,YOLOv9-C紧凑型,以及YOLOv9-E扩展型。
YOLOv9模型代码推理
使用YOLOv9模型进行推理,首先安装相关的库,代码实现如下:
!git clone --recursive https://github.com/WongKinYiu/yolov9.git%cd yolov9/!pip install -r requirements.txt -q!pip install supervision -q!pip install -q roboflow!wget -P /weights -q https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-c.pt!wget -P /weights -q https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-e.pt
安装需要的第三方库后,还需要下载预训练模型,需要放在项目文件下的weights文件夹下,当然此预训练模型可以放置在任何地方,后期使用时,指定正确的项目路径即可。
!python detect.py --weights /weights/gelan-c.pt --conf 0.1 --source /data/dog.jpeg --device 0
然后直接执行cmd终端命令,使用detect.py代码自动执行对象检测功能,执行完成后,模型识别的结果保存在runs文件夹中,可以打开图片查看结果。
yolov9/runs/detect/exp/dog.jpeg
当然除了使用终端界面执行对象检测外,自己可以搭建一下对象检测的代码,方便进行多图片,或者多视频的对象检测。
import torchimport cv2import numpy as npfrom models.common import DetectMultiBackendfrom utils.general import non_max_supPRession, scale_boxesfrom utils.torch_utils import select_device, smart_inference_modefrom utils.augmentations import letterboximport PIL.Imageimport supervision as sv@smart_inference_mode()def predict(image_path, weights='yolov9-c.pt', imgsz=640, conf_thres=0.1, iou_thres=0.45, device='0', data='data/coco.yaml'): device = select_device(device) model = DetectMultiBackend(weights, device=device, fp16=False, data=data) stride, names, pt = model.stride, model.names, model.pt image = PIL.Image.open(image_path) img0 = np.array(image) assert img0 is not None, f'Image Not Found {image_path}' img = letterbox(img0, imgsz, stride=stride, auto=True)[0] img = img[:, :, ::-1].transpose(2, 0, 1) img = np.ascontiguousarray(img) img = torch.from_numpy(img).to(device).float() img /= 255.0 if img.ndimension() == 3: img = img.unsqueeze(0) bounding_box_annotator = sv.BoxAnnotator() label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER) pred = model(img, augment=False, visualize=False) pred = non_max_suppression(pred[0][0], conf_thres, iou_thres, classes=None, max_det=1000) for i, det in enumerate(pred): if len(det): det[:, :4] = scale_boxes(img.shape[2:], det[:, :4], img0.shape).round() for *xyxy, conf, cls in reversed(det): label = f'{names[int(cls)]} {conf:.2f}' detections = sv.Detections( xyxy=torch.stack(xyxy).cpu().numpy().reshape(1, -1),class_id=np.array([int(cls)]),confidence=np.array([float(conf)])) labels = [ f"{class_id} {confidence:0.2f}"for class_id, confidencein zip(detections.class_id, detections.confidence)] img0 = bounding_box_annotator.annotate(img0, detections) img0 = label_annotator.annotate(img0, detections, labels) return img0[:, :, ::-1]
这里把对象检测的函数单独拿出来,若我们需要进行多图片检测,可以直接使用loop循环来设计代码。搭建完成对象检测函数后,就可以使用此函数进行对象检测了。
img = predict(image_path=f'test.jpeg',weights=f'weights/yolov9-e.pt')sv.plot_image(img)
使用此函数,加载一张图片,并进入yolov9模型进行对象检测任务,模型执行完成后,可以使用opencv或者其他可视化库进行代码的可视化操作。
从速度与精度上,其yolov9模型都得到了很好的提高,若模型传递的是一个视频文件,则模型会自动执行视频对象检测。
!python detect.py --weights /weights/gelan-c.pt --conf 0.1 --source /data/video.mp4 --device 0
yolov9模型,在黑暗条件下与模糊的弱光条件下,都有很好的效果。
https://github.com/WongKinYiu/yolov9?tab=readme-ov-filehttps://arxiv.org/pdf/2402.13616https://learnopencv.com/yolov9-advancing-the-yolo-legacy/https://huggingface.co/merve/yolov9
发表评论