Yolov1原理详细解读及实战(一)理论篇

news2024/11/23 20:59:16

在这里插入图片描述

什么是Yolov1?

Yolo(You Only Look Once)是一种one-stage目标检测算法,即仅需要 “看” 一次就可以识别出图片中物体的class类别和位置。作为one-stage的开山鼻祖,YOLOv1以其简洁的网络结构和GPU上的实时检测速度而一鸣惊人,打破了R-CNN的“垄断”地位,为目标检测领域带来巨大的变革。

Yolov1将目标检测任务重新定义为单个回归问题,仅使用一个卷积神经网络直接预测图像的Bounding box及其class类别的概率。 并且检测速度较快,普通的Yolov1模型实时处理图像速度可达到45帧每秒。更轻小的Fast Yolo,每秒处理速度则可高达155帧。

尽管以现在的眼光看Yolov1是由很多弊端的,但是它是后续one-stage工作的基础,里程碑意义不可磨灭。

网络结构

Yolov1整体网络结构如下图。
在这里插入图片描述
Yolov1的Backbone网络仿照GoogLeNet网络搭建,但并没有采用Inception模块,而是使用1x1卷积层和3x3卷积层堆砌。

从整体来看,Yolov1网络接收一张输入图像大小为448x448的RGB图像,经由Backbone网络处理后输出一个空间大小被降采样了64倍(网络最终的stride为64(448/7=64))的特征图,该特征图是一个维度为7x7x1024的三维张量,其中7x7是特征图的宽和高,1024是将经过卷积网络处理后的通道数。特征图再经过全连接层处理、维度转换等操作,输出7x7x30的一维张量。

Yolov1的输入和输出如下图所示。
在这里插入图片描述
为什么是7x7x30的输出?

Yolov1将一个448x448的原图片分割为7x7=49个grid cell,每个grid cell预测B个Bounding box的坐标(x,y,w,h)和box内是否包含目标物体的置信度confidence(共5个参数,B=2),以及该grid cell包含的目标物体属于C个class类别中某一类的概率(训练数据集为voc2012,包含20个class类别,C=20),所以每一个grid cell对应 (5x2+20=) 30个预测参数。
在这里插入图片描述
综上,网络最终输出的预测参数总量就是SxSx(5B+C),其中(S=输入图像尺寸/网络最大的stride)。

算法流程

在这里插入图片描述

图像划分

将输入的图像划分为SxS的grid cell,如果某个目标物体的中心点落到其中一个grid cell中,则该grid cell会负责检测此目标物。其中,Yolov1中,S=7,即划分为49个grid cell。
如下图狗的中心落在了阴影的小grid cell中,则该grid cell负责预测狗。
在这里插入图片描述

Bounding box预测

每个grid cell会预测B个Bounding box边界框(Yolov1中B=2,当然无论B的数量是多少,一个grid cell只负责预测一个目标,因此7×7=49个grid cell最多只能预测49个物体。),每个Bounding box有自己对应的置信度,这些Bounding box大小尺寸可随意,但是生成的Bounding box的中心点必须在grid cell中。

位置参数及置信度详解

  • 每个Bounding box可以用(x,y,w,h,c)这五个参数表示,其中,

    • (x,y):表示Bounding box预测框的中心坐标相较于该Bounding box(中心点)归属的grid cell左上角的偏移量,取值在0-1之间。如下图,绿点是grid cell的左上角(0,0),红色和蓝色框是该grid cell包含的2个Bounding box,二者中心坐标分别为红点和蓝点。二者的(x,y)分别是(0.5,0.5)和(0.9,0.9)。
      在这里插入图片描述

      注意:Bounding box的中心坐标一定是在其对应grid cell里面,因此红点和蓝点的坐标可以归一化到0-1之间。

    • (w,h):表示Bounding box预测框的宽和高相对于原图片宽和高的比例。Yolov1输入图像是448*448,假设Bounding box预测框的宽和高是44.8个像素,则w=0.1,h=0.1。

    • c:置信度confidence,用于表征网格中是否有目标物中心点或包含目标物的概率以及预测的边框位置的准确度。对于边界框位置的准确度,通常(使用预测的Bounding box与物体真实的边界框的)交并比IoU(Interaction over Union)来衡量。IoU越接近于1,表明目标物边框与边界框重合度越高。置信度计算公式为: c o n f i d e n c e = P r ( O b j e c t ) ∗ I o U p r e d t r u t h confidence=Pr(Object)*IoU_{pred}^{truth} confidence=Pr(Object)IoUpredtruth ,Pr(Object)表示Box中包含目标物的概率。若Box中包含目标物,Pr(Object)=1,此时置信度等于IoU,反之置信度为0。

class类别概率详解

每个grid cell会预测出20个class类别概率(Yolov1中C=20,训练数据集是20类),可通过条件概率计算得到,记为 P r ( c l a s s i ∣ o b j e c t ) Pr(class_i|object) Pr(classiobject)

P r ( c l a s s i ∣ o b j e c t ) ∗ P r ( O b j e c t ) ∗ I o U p r e d t r u t h = P r ( c l a s s i ) ∗ I o U p r e d t r u t h Pr(class_i|object)*Pr(Object)*IoU_{pred}^{truth}=Pr(class_i)*IoU_{pred}^{truth} Pr(classiobject)Pr(Object)IoUpredtruth=Pr(classi)IoUpredtruth

无论一个grid cell中包含多少Bounding box,一个grid cell只能预测一个物体,这是Yolov1对小目标物体检测性能较差的原因。如果原图片比较密集,grid cell中可能存在多个物体,Yolo模型只能预测其中一个,那么自然会忽略grid cell内的其它物体。

训练

我们知道深度学习的训练即就是通过梯度下降和反向传播法的迭代去微调网络神经元的权重,以使得损失函数最小化的过程

目标检测是一个典型的监督学习问题,训练集上会给定输入图像及其标签(标记好ground truth),算法的实现思路就是尽可能的去拟合人工标记的框,使损失函数达到最小。训练阶段,每个grid cell预测两个Bounding box,与ground truth交并比(IoU)最大的那个Bounding box负责拟合ground truth。

训练相关设置

  1. 预训练: 首先在ImageNet(1000-class类别)数据集上预训练一个分类网络,该网络是Yolov1网络结构中所示的前20个卷积网络++1个平均池化层+1个全连接层,网络输入是224x224。

  2. 模型微调:
    (1):在预训练模型基础上添加4个卷积层和2个全连接层(这里直接会替换预训练模型中的一个全连接层),新添加的层采用随机初始化参数。
    (2):为了提取更细粒度的视觉信息,因此将网络输入图像的分辨率由224x224调整到448x448。

  3. 归一化:

    (1):分别除以图像的宽和高使输出中的w、h归一化到[0,1]区间。
    (2):通过将坐标(x,y)限制为特定网格中的相对位置,同样使其归一化至[0,1]区间。

  4. 激活函数:最终的全连接层采用线性激活函数,其它所有层均采用leaky ReLU激活函数。

  5. 损失函数:具体介绍见下文。

损失函数

Yolov1损失函数包括三部分:边界框损失(Bounding box loss)、置信度损失(confidence loss)和分类损失(classification loss),其中置信度损失又可以细分为包含目标的Bbox的置信度损失和未包含目标的Bbox的置信度损失两种。计算方法如下:
在这里插入图片描述

坐标损失

在这里插入图片描述
其中,

  • 前半部分表示负责检测目标物的Bounding box中心点定位误差。
  • 后半部分表示负责检测目标物的Bounding box宽高定位误差。

注意

这里对宽和高的损失处理分别取了根号,因为如若不取根号,损失函数往往更倾向于调整尺寸比较大的预测框。例如20个像素点的偏差,对于800x600的预测框几乎没有影响,此时IoU值还是很大,

但是对于30x40的预测框影响就很大。取根号就是为了尽可能消除大尺寸框和小尺寸框之间的差异。其本质也就是尺度归一化。

置信度损失

在这里插入图片描述

  • 前半部分表示负责检测目标物的Bounding box的置信度损失。
  • 后半部分表示不负责检测目标物的Bounding box的置信度损失。

分类损失

在这里插入图片描述

  • 表示负责检测目标物的grid cell的分类损失。

特殊符号解析
在这里插入图片描述

推理

推理原理

Yolov1网络输入是448x448的图像,输出是7x7x30的张量。每张图片分成49个grid cell,每个grid cell预测2个Bounding box,整个推理过程会产生98个检测框。多数情况下,模型能够清晰的判断目标中心位置位于哪个grid cell,然后仅用一个Bounding box预测目标位置。对于较大或者位于多个网格边界的目标物,可能会被多个网格同时较好地定位,此时则采用非极大值抑制NMS的方法,去除冗余,即对于同一目标物只保留置信度(这里等于IoU)最大的Bounding box。

注意:训练阶段不需要NMS处理。

推理过程

推理过程如下图所示。每个grid cell包含2个Bounding box和20个class类别class类别的条件概率,每个Bounding box又会包含4个box位置坐标和1个box置信度,每个box置信度与20个class类别class类别的条件概率分别相乘,得到一个权概率(20*1),因此每个grid cell有2个权概率,整个推理过程有7x7x2=98个权概率。
在这里插入图片描述

然后将98个权概率分别以颜色(class类别)和粗细(box置信度)加持,可视化即可得到如下图②的98个框。经过NMS非极大值抑制之后,进而得到图③的检测结果。
在这里插入图片描述

非极大值抑制NMS(Non-Max Suppression)

NMS核心思想:

选择权概率最高的作为输出,与该输出重叠的去掉,不断重复这一过程直到所有候选对象处理完成。

NMS计算方法:

网络输出7x7x30的张量,计算NMS即是求每一个grid cell中, c l a s s i class_i classi位于第j个Bounding box的得分。该得分表示 c l a s s i class_i classi位于第j个Bounding box的可能性/概率。
在这里插入图片描述
每个网格包括:20个class类别对象的概率*2个Bounding box的置信度=40个得分(候选对象)。49个网格共1960个得分。每种class类别对象分别进行NMS,那么每种对象有1960/20=98个得分。

NMS处理过程:

  1. 设置Score阈值,低于该阈值的候选对象对应的Score置零。

  2. 遍历每一个对象class类别(20个class类别):

    • 遍历每个对象class类别的98个得分:

      • 找到Score最大的对象class类别及其Bounding box,添加到输出列表。
      • 对每个Score不为0的候选对象,计算其与Score最大的对象class类别对应Bounding box的IoU。
      • 根据预先设置的IoU阈值筛选,高于阈值(重叠度较高)的候选对象的Score置零。
      • 直到所有Bounding box处理完成,表示该对象class类别的NMS计算完成。
  3. 输出列表即为预测的对象。

至此,关于Yolov1网络结构、算法流程、训练及推理原理的讲解基本完成。关于Yolov1是如何工作的,相信读者也有了基本的认识。然而,“纸上得来终觉浅,绝知此事要躬行”,只有亲自动手才能够真正地掌握所学到的知识。为此,我们将在下一章进入实战环节。

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

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

相关文章

Linux centos7 bash编程(break和continue)

在学习shell知识时,简单编程要从格式入手。 首先学习好单行注释和多行注释。 先学习简单整数的打印输出,主要学习echo命令,学习选项-e -n的使用。 下面的练习是常用的两个分支程序:break和continue。 #!/bin/bash # 这是单行注…

极氪汽车的云资源治理细探

作者:极氪汽车吴超 前言 2021 年,极氪 001 迅速崭露头角,仅用 110 天便创下了首款车型交付量“最快破万”的纪录。2022 年 11 月,极氪 009 在短短 76 天内便率先完成了首批交付,刷新了中国豪华纯电品牌交付速度的纪录…

算法通过村第四关-栈白银笔记|括号问题

文章目录 前言1. 括号匹配问题2. 最小栈问题3. 最大栈 总结 前言 提示:如果让我送给年轻人四个字,就是:量力而行。 量力而行不会失眠,不会啃老,不会为各种考试焦虑。顺其自然活得轻松。其实,量力而行最易大…

数据库集群的简单了解

Update 关于操作的日志 1.0 redo log 读一次写一次 一共2次, 不安全 注意redo log是顺写 而file是随机 所以Mysql做出类似HDFS的操作 行为日志和数据分离,但是不同的是,Mysql在内存中操作修改,如果不出事故,由内存中的行为来直接…

Yolov1原理详细解读及实战(二)实战篇

在Yolov1原理详细解读及实战(一)理论篇 中,我们对Yolov1网络结构、算法流程、训练及推理原理进行了详细剖析,本章进入实战环节,话不多说,马上开始! 环境 vscodeWSL:Ubuntu 18.04python 3.9.7 …

wireshark过滤器的使用

目录 wiresharkwireshark的基本使用wireshark过滤器的区别 抓包案例 wireshark wireshark的基本使用 抓包采用 wireshark,提取特征时,要对 session 进行过滤,找到关键的stream,这里总结了 wireshark 过滤的基本语法,…

外卖订餐系统源码:数字化时代餐饮服务的创新之道

在如今快节奏的生活中,外卖订餐系统源码正成为餐饮业界的一股创新浪潮。它为餐厅和创业者提供了一个数字化的平台,使订餐与配送更加便捷、高效。本文将为您展示如何使用外卖订餐系统源码创建一个简单但功能强大的订餐平台。 # 导入必要的模块 import d…

离线竞价功能说明及设置

为了更加方便广大用户不再熬夜竞价,西部数码推出了离线竞价功能,现已正式上线,欢迎大家使用反馈。 1、离线竟价功能说明 当您拥有域名的出价权限时,您可在 【我参与的竞价】或【我出价的域名】列表选中域名开启离线竟价。 设置…

固定资产管理系统都需要考虑哪些问题?

企业管理中固定资产的追踪和管理是非常重要的一环。固定资产不仅包括房屋、土地、机器设备等大量的资产,也包括低值易耗品。因为这些资产往往是企业生产或者管理过程中不可或缺的。在使用和管理过程中,往往涉及到转移、借调、维护等方面。如何进行有效的…

健康安全的新定义,照明舒适达到巅峰,SUKER书客护眼台灯L1震撼发售

深耕照明领域多年的SUKER书客,这一次给大家带来一份大惊喜。在最近正式发布新品——SUKER书客护眼台灯L1,这款护眼台灯承载着在照明领域的前沿技术,能保证照明安全健康和舒适度并带来非常优秀的护眼效果。作为书客在护眼台灯领域的颠覆式新品…

【FaceChain风格DIY手把手教程】无限场景风格LoRA与固定人物LoRA的融合(4Kstar!)

先看效果 以上风格LoRA分别为:户外花园婚纱、冬季雪景汉服、火焰女神、仙侠风 环境准备 在魔搭平台ModelScope 魔搭社区中选择PAI-DSW-GPU环境 进入后打开terminal环境,先检查显存需要20G左右(nvidia-smi),然后下载核…

面试题-React(七):React组件通信

在React开发中,组件通信是一个核心概念,它使得不同组件能够协同工作,实现更复杂的交互和数据传递。常见的组件通信方式:父传子和子传父 一、父传子通信方式 父组件向子组件传递数据是React中最常见的一种通信方式。这种方式适用…

什么是可观测性

可观测性是指使用从其组件收集的累积信息来了解系统或应用程序的当前状态,可观测性通常侧重于监视整个系统或应用程序,而不是单独管理元素,完全可观察的环境将深入了解网络堆栈,并始终保持网络基础设施处于最佳工作状态。 什么是…

整数拆分乘积最大

将一个整数拆分为若干个自然数的和,如果要使这些数的乘积最大,应该尽可能的拆分出3。 任意一个数字可以由多个3的n次方的和(差)表示。 import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class M…

k8s的学习篇1

一 k8s的概念 1.1 k8s k8s是一个轻量级的,用于管理容器化应用和服务的平台。通过k8s能够进行应用的自动化部署和扩容缩容。 1.2 k8s核心部分 1.prod: 最小的部署单元;一组容器的集合;共享网络;生命周期是短暂的; …

<C++> 继承

1.继承的概念和定义 继承是面向对象其中的一个核心概念之一,继承允许一个类(称为子类或派生类)从另一个类(称为父类或基类)继承属性和行为,以便在子类中重用已有的代码并添加新的功能。通过继承&#xff0…

yo!这里是Linux基础开发工具介绍

目录 前言 基础开发工具 yum vim 1.基本介绍 2.基本操作 3.正常模式常用命令 4.底行模式常用命令 gcc/g gdb 1.基本介绍 2.常用操作 make/Makefile 1.背景 2.介绍 3.使用 git 1.介绍 2.操作 进度条程序简单实现 后记 前言 在学完初步的基础指令及权限控…

Spring Boot进阶(60):5种判断线程池任务是否全部完成的方案 | 实用技巧分享!

1. 前言🔥 多线程编程在现代软件开发中非常常见且重要,而线程池是多线程编程的常用技术。在使用线程池时,通常需要判断线程池中的任务是否全部完成,以便决定程序继续执行的下一步操作。本文将介绍5种判断线程池任务是否全部完成的…

MySQL项目迁移华为GaussDB PG模式指南

文章目录 0. 前言1. 数据库模式选择(B/PG)2.驱动选择2.1. 使用postgresql驱动2.1. 使用opengaussjdbc驱动 3. 其他考虑因素4. PG模式4.1 MySQL和OpenGauss不兼容的语法处理建议4.2 语法差异 6. 高斯数据库 PG模式JDBC 使用示例验证6. 参考资料 本章节主要…