YOLOV8解读及推理代码

news2025/1/19 17:24:38

YOLOV8解读及推理代码

  • YOLOV8
    • 前言
    • 性能对比
    • 新的骨干网络
    • 新的 Ancher-Free 检测头
    • 新的损失函数
    • 环境配置
    • 训练
      • 基于python脚本
      • 基于命令行
    • 推理
      • pt模型推理
      • onnx模型推理

YOLOV8

前言

YOLOv8并非一个全新的目标检测网络,而是在YOLOv5的基础上进行了升级。其主要升级包括:

  • 新的骨干网络
  • 创新的Ancher-Free检测头
  • 新的损失函数

性能对比

下表展示了在COCO Val 2017数据集上官方进行测试的mAP、参数量和FLOPs的结果。

模型YOLOv5params(M)FLOPs@640 (B)YOLOv8params(M)FLOPs@640 (B)
n28.0(300e)1.94.537.3 (500e)3.28.7
s37.4 (300e)7.216.544.9 (500e)11.228.6
m45.4 (300e)21.249.050.2 (500e)25.978.9
l49.0 (300e)46.5109.152.9 (500e)43.7165.2
x50.7 (300e)86.7205.753.9 (500e)68.2257.8

可以看出,相较于YOLOv5,YOLOv8在精度上取得了显著提升。然而,N/S/M模型的参数量和FLOPs相应地也有相当的增加。此外,大多数模型相较于YOLOv5,在推理速度上都略有下降。

在这里插入图片描述

新的骨干网络

YOLOv8引入了一系列关键的改进,特别是在骨干网络方面:

  • 第一个卷积层的kernel由6x6缩减为3x3,以提高特征提取的精度和效率。
  • 所有的C3模块都被替换为C2f模块,结构更为复杂,引入了更多的跳层连接和额外的Split操作,以促进信息的更好传递。
  • 删除了Neck模块中的两个卷积连接层,以简化网络结构。
  • 在Backbone中,C2f的block数由3-6-9-3调整为3-6-6-3,以优化网络的深度和复杂度。
    在这里插入图片描述

新的 Ancher-Free 检测头

在YOLOv8中,Head部分经历了一系列重大变化,从原先的耦合头演变为解耦头,并且从YOLOv5的Anchor-Based设计转变为Anchor-Free设计。这一变化带来了以下关键特点:

  • 解耦设计: Head部分不再采用之前的紧密耦合结构,而是进行了解耦,使分类和回归分支更为独立。
  • Anchor-Free设计: 与YOLOv5的Anchor-Based设计不同,YOLOv8的Head部分摒弃了之前的objectness分支,转而实现了Anchor-Free设计,从而简化了模型结构。
  • 回归分支创新: Head部分的回归分支采用了Distribution Focal Loss中提出的积分形式表示法,这一创新提高了模型对目标定位和边界框回归的效果。

这些变化共同构成了YOLOv8 Head部分的新特征,使其在目标检测任务中更具灵活性和性能。

在这里插入图片描述

新的损失函数

YOLOv8的损失函数计算涉及两个主要分支:分类分支和回归分支,不再包含之前的objectness分支。这两个分支的损失通过一定的权重比例进行加权。

  • 分类分支: 仍然使用二元交叉熵(BCE Loss)来处理目标分类问题。
  • 回归分支: 引入Distribution Focal Loss的积分形式表示法,同时还采用了CIoU Loss。这种设计使得回归分支更加精细化,有助于提高目标的定位和边界框回归的准确性。

通过这样的损失函数设计,YOLOv8在训练过程中能够更好地优化模型参数,使其在目标检测任务中取得更好的性能。

环境配置

conda create -n yolov8_env python==3.9
pip install ultralytics
conda activate yolov8_env
git clone https://github.com/ultralytics/ultralytics

训练

基于python脚本

from ultralytics import YOLO

# 加载模型
# model = YOLO("yolov8n.yaml")  # 从头开始构建新模型
model = YOLO("yolov8n.pt")  # 加载预训练模型(建议用于训练)

# 使用模型
model.train(data="ultralytics/ultralytics/datasets/VOC_lw.yaml", epochs=100,batch=16,patience=0)  # 训练模型
metrics = model.val()  # 在验证集上评估模型性能

基于命令行

yolo task=detect mode=train model=yolov8n.yaml data=ultralytics/ultralytics/datasets/VOC.yaml

推理

pt模型推理

results = model("https://ultralytics.com/images/bus.jpg")  # 对图像进行预测

onnx模型推理

  1. pt模型转onnx
yolo export model=best.pt format=onnx opset=12
  1. 基于ultralytics进行onnx推理
from ultralytics import YOLO
import os
# Load a model 
model = YOLO('best.onnx')  # load an official model

# Predict with the model
# results = model('62.png')  # predict on an image
path = "climb/images"
img_list = [os.path.join(path,dir) for dir in os.listdir(path)]
for im in img_list:  
    model.predict(im, save=True, imgsz=640, conf=0.40)
  1. onnx推理
import numpy as np
import cv2

import logging


CLASSES = ['dog']
colors = np.random.uniform(0, 255, size=(len(CLASSES), 3))

def draw_bounding_box(img, class_id, confidence, x, y, x_plus_w, y_plus_h):
    label = f'{CLASSES[class_id]} ({confidence:.2f})'
    color = colors[class_id]
    cv2.rectangle(img, (x, y), (x_plus_w, y_plus_h), color, 2)
    cv2.putText(img, label, (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)

class DogDetector:
    def __init__(self, model_path = None):
        # logging.info(f"start init model")
        self.model: cv2.dnn.Net = cv2.dnn.readNetFromONNX(model_path)
        self.img_det_size = 640


    
    def __call__(self , image, score_threshold = 0.9):
        blob = self.img_process(image)
        self.model.setInput(blob)
        outputs = self.model.forward()
        
        outputs = np.array([cv2.transpose(outputs[0])])
        rows = outputs.shape[1]

        boxes = []
        scores = []
        class_ids = []

        for i in range(rows):
            classes_scores = outputs[0][i][4:]
            (minScore, maxScore, minClassLoc, (x, maxClassIndex)) = cv2.minMaxLoc(classes_scores)
            if maxScore >= 0.25:
                box = [
                    outputs[0][i][0] - (0.5 * outputs[0][i][2]), outputs[0][i][1] - (0.5 * outputs[0][i][3]),
                    outputs[0][i][2], outputs[0][i][3]]
                boxes.append(box)
                scores.append(maxScore)
                class_ids.append(maxClassIndex)

        result_boxes = cv2.dnn.NMSBoxes(boxes, scores, score_threshold, 0.45, 0.5)
        detections = []
        # logging.info(f"result_boxes is : {result_boxes}")
        for i in range(len(result_boxes)):
            index = result_boxes[i]
            box = boxes[index]
            x1,y1,x2,y2 = round(box[0] * self.scale), round(box[1] * self.scale),round((box[0] + box[2]) * self.scale), round((box[1] + box[3]) * self.scale)   
            box = [x1,y1,x2,y2]
            detection = {
                'class_id': class_ids[index],
                'class_name': CLASSES[class_ids[index]],
                'confidence': scores[index],
                'box': box,
                'scale': self.scale}
            detections.append(detection)
            draw_bounding_box(image, class_ids[index], scores[index], round(box[0] * self.scale), round(box[1] * self.scale),
                            round((box[0] + box[2]) * self.scale), round((box[1] + box[3]) * self.scale))
 
        return detections


    
    def img_process(self, img):     
        img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
        original_image: np.ndarray = img
        [height, width, _] = original_image.shape
        length = max((height, width))
        logging.info(f"img shape:{height,width}")
        image = np.zeros((length, length, 3), np.uint8)
        image[0:height, 0:width] = original_image
        self.scale = length / self.img_det_size

        blob = cv2.dnn.blobFromImage(image, scalefactor=1 / 255, size=(640, 640), swapRB=True)
        return blob
if __name__ == '__main__':
	image = cv2.imread("dog.png")
	model = DogDetector(model_path="best.onnx")
	detections = model(image, score_threshold=0.5)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1269300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

enote笔记法之附录2——5w1h2k关联词(ver0.22)

enote笔记法之附录2——5w1h2k关联词(ver0.22) 最上面的是截屏的完整版,分割线下面的是纯文字版本: 作者姓名(本人的真实姓名):胡佳吉 居住地:上海 作者网名:EverSt…

裁员降薪如果影响到你,可能还是你的问题

1.摘要 今年以来,看到的裁员风波一茬接一茬,普遍的论调都是IT行业不行了, 总之就是一片哀嚎、惨不忍睹。最近身边的一些朋友也接连传出部门被优化、被裁员的消息, 说实话我自己也被这种寒意给触碰到, 每天也加强了自己的学习频率,甚至把回家路上的碎片时间也利用起来, 目的不在…

高效管理团队表现:构建可视化的贡献度面板组件

说在前面 贡献度面板(Contribution Graph)是指在代码仓库中按时间展示每位开发者的提交情况的可视化图表。它会显示不同日期的提交次数,并用颜色的深浅表示提交的数量。 贡献度面板展现的好处有以下几点: 可视化展示&#xff1…

『Nginx安全访问控制』利用Nginx实现账号密码认证登录的最佳实践

📣读完这篇文章里你能收获到 如何创建用户账号和密码文件,并生成加密密码配置Nginx的认证模块,实现基于账号密码的登录验证 文章目录 一、创建账号密码文件1. 安装htpasswd工具1.1 CentOS1.2 Ubuntu 二、配置Nginx三、重启Nginx 在Web应用程…

redis的数据类型的操作增删改查

redis的数据类型的操作增删改查 redis的高可用: 在集群当中有一个非常重要的指标,提供正常服务的时间的百分比(365天)99.9% redis的高可用的含义要更加宽泛,正常服务是指标之一数据容量扩展,数据的安全性…

ubuntu下训练自己的yolov5数据集

参考文档 yolov5-github yolov5-github-训练文档 csdn训练博客 一、配置环境 1.1 安装依赖包 前往清华源官方地址 选择适合自己的版本替换自己的源 # 备份源文件 sudo cp /etc/apt/sources.list /etc/apt/sources.list_bak # 修改源文件 # 更新 sudo apt update &&a…

三季度同道猎聘遇“瓶颈”,破局重点是中高端人才?

古往今来,人才一直是企业“争夺”的对象。随着新兴产业的快速冒头以及AI技术的崛起,新型人才以及中高端人才成为市场上的香饽饽,而这类人才的稀缺性让企业和招聘平台双方都很“头疼”。再加上外部环境的不确定性增加,职场人普遍求…

打造独特封面:封面设计的关键要素与技巧解析!

书籍作品的封面设计非常精致。就像商品的包装一样,有助于提高书籍的销量。书封的设计表现主要从图像、文字、材质等方面进行设计。基本上所有的书都需要有文字,所以特别考验设计师的文字排版能力。今天就和大家分享一些书籍封面设计的小知识,…

轻松整合Knife4j:快速搭建Swagger文档界面与接口调试

Knife4j 是一个为 Java 开发者提供的 Swagger 文档聚合工具,它是 Swagger-Bootstrap-UI 的升级版。它的主要功能是生成和展示 API 文档,让开发者能够更轻松地查看和测试接口。 整合 Knife4j(Swagger-Bootstrap-UI 的升级版)到 Spr…

VT驱动开发

VT技术(编写一个VT框架) 1.VT技术介绍 1.技术介绍 1.VT技术 VT技术是Intel提供的虚拟化技术,全称为Intel Virtualization Technology。它是一套硬件和软件的解决方案,旨在增强虚拟化环境的性能、可靠性和安全性。VT技术允许在一台物理计算机上同时运…

WebSocket 接口测试:打通前端与后端的通信之路!

什么是 WebSocket? WebSocket 是一种基于在单个 TCP 连接上进行全双工通信的协议,解决了HTTP协议不适用于实时通信的缺点,相较于 HTTP 协议,WebSocket 协议实现了持久化网络通信,可以实现客户端和服务端的长连接,能够…

微信小程序——给按钮添加点击音效

今天来讲解一下如何给微信小程序的按钮添加点击音效 注意&#xff1a;这里的按钮不一定只是 <button>&#xff0c;也可以是一张图片&#xff0c;其实只是添加一个监听点击事件的函数而已 首先来看下按钮的定义 <button bind:tap"onInput" >点我有音效&…

xxl-job适配postgresql数据库

xxl-job支持了mysql数据库&#xff0c;其他的数据库适配得自己弄一下&#xff0c;下面以目前最新的2.4.1为例进行说明适配postgresql数据库的过程。 获取源代码 从github或gitee获取源代码&#xff0c;目前最新版本2.4.1 xxl官网&#xff1a;分布式任务调度平台XXL-JOB 建立…

OpenCvSharpSlim画中文

github地址&#xff1a;https://github.com/AvenSun/OpenCvSharpSlim Slim Build of OpenCvSharp OpenCvSharpSlim This project provides the slim build of OpenCvSharp native library . Currently therere binary packages for OpenCvSharp 2.4.10, 3.4.20 ,4.8.0 and 4…

关键词挖掘软件-免费批量挖掘关键词的工具

在当今数字化时代&#xff0c;网站的曝光和排名对于吸引流量至关重要。而在这个大数据的背后&#xff0c;SEO&#xff08;Search Engine Optimization&#xff0c;搜索引擎优化&#xff09;成为许多网站主和创作者们追逐的关键。在SEO的世界里&#xff0c;关键词的选择和优化是…

数据结构与算法之美学习笔记:28 | 堆和堆排序:为什么说堆排序没有快速排序快?

目录 前言如何理解“堆”&#xff1f;如何实现一个堆&#xff1f;1. 往堆中插入一个元素2. 删除堆顶元素 如何基于堆实现排序&#xff1f;1. 建堆2. 排序 解答开篇内容小结 前言 本节课程思维导图&#xff1a; 我们今天讲另外一种特殊的树&#xff0c;“堆”&#xff08;Heap&…

电脑IP地址怎么修改?http代理ip设置方法有哪些?

在互联网时代&#xff0c;我们的网络已经成为我们生活、工作和学习中不可或缺的一部分。有时候&#xff0c;为了保护我们的隐私或者突破网络限制&#xff0c;我们需要修改电脑的IP地址。那么&#xff0c;电脑IP地址怎么修改呢&#xff1f;http代理ip设置方法有哪些呢&#xff1…

在JS中,手动添加标签

纯个人笔记 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, …

前端:实现二级菜单(二级菜单悬浮在一级菜单左侧)

效果 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, i…

正向和反向代理区别

文章目录 正向代理反向代理二者区别参考 正向代理 正向代理就是一个位于客户端和目标服务器之间的服务器&#xff0c;之间的这个服务器就是代理服务器 客户端为了从目标服务器获取内容&#xff0c;但是客户端由于限制无法直接访问到目标服务器&#xff0c;那么客户端就可以向…