YOLO系列基础(六)YOLOv1原理详解,清晰明了!

系列文章地址

YOLO系列基础(一)卷积神经网络原理详解与基础层级结构说明-CSDN博客

YOLO系列基础(二)Bottleneck瓶颈层原理详解-CSDN博客

YOLO系列基础(三)从ResNet残差网络到C3层-CSDN博客

YOLO系列基础(四)归一化层(BN层)的前世今生!-CSDN博客

YOLO系列基础(五)从神经元共适应性到模型Dropout层-CSDN博客

YOLO系列基础(六)YOLOv1原理详解原理如此清晰-CSDN博客

目录

系列文章地址

背景

YOLOv1的网络结构

YOLOv1原理的高层级理解

YOLO算法流程

YOLOv1原理详解

YOLOv1网格详解

针对每一个grid_cell

输出结构内容详解

YOLOv1损失函数详解

第一行损失函数详解

第二行损失函数详解

第三、四行损失函数详解

第五行损失函数详解


背景

        随着YOLOv11版本的发布,YOLO算法在视觉检测领域独领风骚,本系列旨在从小白出发,给大家讲解清楚视觉检测算法的前世今生,并讲清楚YOLOv11版本算法的所有模块功能!

        经过前面几个栏目的学习与掌握,我们已经具备理解和掌握YOLOv1的基本能力。今天,我们来精讲YOLOv1的原理!

YOLOv1的网络结构

YOLOv1网络结构图

YOLOv1的网络结构图很简单,主要的需要注意的点如下:

  • 输入图像大小为448*448。
  • 经过若干个卷积层与池化(具体是24个卷积层和4个最大池化层),变为7*7*1024张量(图一中倒数第三个立方体)。
  • 最后经过两层全连接层,输出张量维度为7*7*30。
  • 在第一个连接层之后,还有一层dropout层,其丢弃率设置为0.5。
  • 除了最后一层使用了线性激活函数外,其余层的激活函数为 Leaky ReLU

        这就是Yolo v1的整个神经网络结构。没有BN层等后续复杂的层级结构,在那个年代,神经网络还很清晰单纯……

        下图为整个结构图的说明解释,官方给的图有点容易让人混淆了,特别是上面的立方体和下面的层不对应……也是有点无语了……

YOLOv1原理的高层级理解

        如果一上来就把原理揉碎了开始长篇大论,个人感觉效果会很不好,听者也会云里雾里。所以我们先从YOLOv1的高层级理解开始,先给自己一个大致的感觉~

        YOLOv1网络将输入的图片resize成480*480之后,再把这个图片分割为7*7的格网(也称grid_cell),如下图所示。想必大家都已经看腻下面的图片了吧(笑)。在代码中,下图的 S = 7。

        在该图片中,假设我们需要检测狗、自行车、和白车。我人工标注了一下三个检测框和中心点。白色框框选狗,白色小圆圈标记框的中心点,以此类推……

YOLO算法流程

  • 首先获取每一个检测框的中心点,也就是上图中的白色、红色、蓝色圆圈坐标。
  • 获取到坐标之后,该坐标点对应的grid_cell(也就是对应的格子)就需要负责该类别的检测,一共需要获取三个内容(中心点坐标、检测框坐标、类别ID)
  • YOLO的训练策略为:非中心点所在的cell需要极力让自己格子内检测框的置信度C降低,中心点所在的cell则需要让自己的检测框的置信度上升、中心点的坐标和检测框的IoU要极力去拟合,当然还有类别的概率。

也就是说,无论是检测中心点还是检测框,都是由中心点所在的cell来预测的,和其他的cell没有任何关系。但是每个cell都需要进行中心点、检测框、类别的预测,然后在训练过程中,将预测置信度不断提高(有物体) or 降低(无物体)!

显然,以cell为检测单位,导致每一个cell仅能针对一个类别进行预测,若两个类别的中心点位同一个cell,那么YOLOv1就会直接开摆~

有了上诉的一些概念,我们进行原理详解与论文精读

YOLOv1原理详解

传统的视觉识别算法分两步走:

  1. 检测中心和检测框的回归问题
  2. 目标对象的分类问题

        在YOLO中,我们把对象的分类问题也看成回归问题去解决,使得整个网络大为精简(端到端直接全部输出类别、检测框……)

YOLOv1网格详解

        我们已知YOLO会将输入图像分成S×S(其中S=7)的网格,如果一个物体的中心点落入到一个cell中,那么该cell就要负责预测该物体,一个格子只能预测一个物体,并生成B个检测框(其中B=2,意味着每次检测都会尝试两次)。

针对每一个grid_cell

  • 我们会输出B个(B=2)检测框,大小、高度都无所谓,但是检测框的中心点坐标一定是落于该cell内的
  • 我们针对每一个检测框,都会输出检测框的置信度,代表该处存在物体的可能性以及IoU

注意,每一个检测框的置信度是由该处存在物体的可能性和检测框的IoU决定的,公式如下:

confidence=P(Object)×IOU_{truth}^{pred}

P(Object) :表示预测框内存在物体的概率

IOU_{truth}^{pred}    :表示预测框与真实框之间的交并比。

  • 所以每个检测框包含5个元素(x,y,w,h,c)分别代表中心点坐标(x,y),检测框大小(w,h)以及置信度。每个格子一共两个检测框,所以一共有10个值输出。

 图例如下

   

 注意,上面的x,y,w,h均是归一化到(0,1)的值,和整个图像大小之间进行归一化。有的博主认为中心点坐标xy是和网格cell之间的偏移量进行归一化,但是私以为,应该还是和原图像进行的归一化。

(若有错漏请指正

输出结构内容详解

        我们已知YOLOv1的输出结构为7*7*30,这里的7*7指的是输出特征的大小,是由原图像(480*480)通过4层最大池化层和一层卷积层(步长均为2)来进行缩减的,也就是说每一个格子,对应64*64的原像素区域。

        在YOLOv1的官方示例中,官方采用了20种标签来进行训练。由于YOLOv1采用回归的方式解决分类问题,所以输出的结果还有该网格中所有类别的分类置信度(一共20个)。

        所以输出结构就很清晰了:

  • 7*7代表7*7的格子
  • 30代表两个检测框的(x,y,w,h,c)和20个类别的分类置信度

举个例子,以下就是30的含义:

第一个检测框第二个检测框所有类别的置信度
x1y1w1h1c1x2y2w2h2c2cls1cls2……cls19cls20

  

至此,YOLOv1的输出结构已经说明完毕。

到此为止,YOLOv1的网络结构都已经解构完成,我们只缺损失值的计算。

YOLOv1损失函数详解

直接先给出YOLOv1损失函数!

  

看着头晕晕?没关系,其实很简单!我们一行行来:

第一行损失函数详解

\lambda _{coord}\sum_{i=0}^{s^{2}}\sum_{j=0}^{B}\mathbb{I}_{ij}^{obj}[(x_{i}-\hat{x}_{i})^{2}-(y_{i}-\hat{y}_{i})^{2}] 

这一行主要是针对中心点进行差距损失的计算。

  • 其中\lambda _{coord}(等于5)是一个参数,暂时没啥特别的(后面详解)
  • \sum_{i=0}^{s^{2}}用以遍历所有的格子
  • \sum_{j=0}^{B}用以遍历每一个格子中的检测框

以我们普遍的理念看来,假设我们需要针对中心点进行拟合,我们能想出来的损失函数应当如下所示:

\lambda _{coord}\sum_{i=0}^{s^{2}}\sum_{j=0}^{B}[(x_{i}-\hat{x}_{i})^{2}-(y_{i}-\hat{y}_{i})^{2}]

这是我们好理解的,可是剩下的 \mathbb{I}_{ij}^{obj} 是个什么东西??

  1. 这表明在第 i 个格子存在待测物体的中心点。
  2. 且单元i中的第j个边界框预测器“负责”该预测。

这个部分最重要的就是确保该检测框正确召回了物体!也就是说确保该检测框检测出了待测物体,尽管可能IOU不高、类别不精准。

大家可以想象,若没有这个条件约束,后面的计算就毫无意义。 

第二行损失函数详解

\lambda _{coord}\sum_{i=0}^{s^{2}}\sum_{j=0}^{B}\mathbb{I}_{ij}^{obj}[(w_{i}-\hat{w}_{i})^{2}-(h_{i}-\hat{h}_{i})^{2}]

简单,和第一行一样,这次计算的是检测框宽和高的损失。

第三、四行损失函数详解

\sum_{i=0}^{s^{2}}\sum_{j=0}^{B}\mathbb{I}_{ij}^{obj}[(c_{i}-\hat{c}_{i})^{2}] + \lambda _{noobj}\sum_{i=0}^{s^{2}}\sum_{j=0}^{B}\mathbb{I}_{ij}^{noobj}[(c_{i}-\hat{c}_{i})^{2}]

此为检测框置信度的损失值计算,但是这里出现了\lambda _{noobj} 和 \mathbb{I}_{ij}^{noobj} 这是为什么呢?实际上,\mathbb{I}_{ij}^{noobj}和上面的\mathbb{I}_{ij}^{obj}含义刚好相反,\mathbb{I}_{ij}^{obj}表示该检测框成功召回了物体,\mathbb{I}_{ij}^{noobj}则表示该检测框没有召回物体。显然这里的损失函数的两面的:

  • 针对成功召回的检测框,我们需要计算检测框和目标检测框的IOU之间的差距来表示损失值。
  • 针对没有召回的检测框,此时的目标置信度为0,我们需要将这些失败的检测框的置信度下降。

第五行损失函数详解

\sum_{i=0}^{s^{2}}\mathbb{I}_{i}^{obj}\sum_{c \in classes}(p_{i}(c)-\hat{p_{i}}(c))^{2}

显然,这里的意思就是:

遍历所有的检测框,如果检测框内存在目标物体的中心点,则针对该检测框内的分类结果对所有的类别的目标进行损失的计算并求和。

至此YOLOv1的全部内容详解完毕!

总结

YOLOv1虽然已经是将近10年前的算法了,但是作为目标检测之王的初代版本,依旧有很多可以学习和借鉴的内容,实际上,博主光是准备此篇博客就花费了整整两天的时间。恳请广大读者不要吝啬手中的点赞哦!

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

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

相关文章

硬石电机学习2024116

F4 概况 共模抑制线圈作用是滤波 LD3.3是将5v转为芯片用的3.3V CH340用于板子和电脑通讯 光耦隔离保护主控 16M的外部flash 1M的芯片内部的flash 10kHZ高速的光耦隔离,1M的低俗光耦隔离 F4 stm32概况 stm8和51都是一次可以运算处理8位的 32表示一次处理32位…

[Qt] Qt删除文本文件中的某一行

需求 我们经常读一个文件或者直接往一个空白文件中写文本&#xff0c;那么该如何使用Qt在一个文本文件中删除某一行 代码 #include <QCoreApplication> #include <QIODevice> #include <QFile> #include <QTextStream> #include <QString> #i…

【OceanBase 诊断调优】—— ocp上针对OB租户CPU消耗计算逻辑

指标介绍 租户 CPU 使用量 * 100 / 租户 CPU 分配量。 指标参数说明 指标项指标名称单位租户 CPU 消耗ob_tenant_cpu_percent% 计算表达式 sum(rate(ob_sysstat{stat_id"140013",LABELS}[INTERVAL])) by (GBLABELS) / sum(ob_sysstat{stat_id"140005"…

Vue开发风格

风格指南 如果在工程中使用 Vue&#xff0c;为了回避错误、小纠结和反模式&#xff0c;该指南是份不错的参考。不过我们也不确信风格指南的所有内容对于所有的团队或工程都是理想的。所以根据过去的经验、周围的技术栈、个人价值观做出有意义的偏差是可取的。 对于其绝大部分…

基于Python爬虫大屏可视化的热门旅游景点数据分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

OpenCV、YOLO、VOC、COCO之间的关系和区别

OpenCV、YOLO、COCO 和 VOC 是计算机视觉和深度学习领域常见的几个名词&#xff0c;它们分别代表不同的工具、算法和数据集&#xff0c;之间有一些联系和区别。下面分别说明它们的定义、用途以及相互关系。 1. OpenCV&#xff08;Open Source Computer Vision Library&#xf…

RAG经验论文《FACTS About Building Retrieval Augmented Generation-based Chatbots》笔记

《FACTS About Building Retrieval Augmented Generation-based Chatbots》是2024年7月英伟达的团队发表的基于RAG的聊天机器人构建的文章。 这篇论文在待读列表很长时间了&#xff0c;一直没有读&#xff0c;看题目以为FACTS是总结的一些事实经验&#xff0c;阅读过才发现FAC…

解析传统及深度学习目标检测方法的原理与具体应用之道

深度学习目标检测算法 常用的深度学习的目标检测算法及其原理和具体应用方法&#xff1a; R-CNN&#xff08;Region-based Convolutional Neural Networks&#xff09;系列1&#xff1a; 原理&#xff1a; 候选区域生成&#xff1a;R-CNN 首先使用传统的方法&#xff08;如 Se…

lambda 与函数指针

C 的函数类型包括了以下几种&#xff1a; 函数指针&#xff1b;成员函数指针&#xff1b;上述两种函数类型的引用、c-v- 和 noexcept 修饰符的排列组合。 在 C11 后&#xff0c;语言标准引入了更灵活的 lambda 函数&#xff1b;因此在函数类型中又新增了 lambda 类型和一堆修…

boost之property

简介 property在boost.graph中有使用&#xff0c;用于表示点属性或者边属性 结构 #mermaid-svg-56YI0wFLPH0wixrJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-56YI0wFLPH0wixrJ .error-icon{fill:#552222;}#me…

Oracle 19c PDB克隆后出现Warning: PDB altered with errors受限模式处理

在进行一次19c PDB克隆过程中&#xff0c;发现克隆结束&#xff0c;在打开后出现了报错&#xff0c;PDB变成受限模式&#xff0c;以下是分析处理过程 09:25:48 SQL> alter pluggable database test1113 open instancesall; Warning: PDB altered with errors. Elapsed: 0…

AndroidStudio-Activity的生命周期

一、Avtivity的启动和结束 从当前页面跳到新页面&#xff0c;跳转代码如下&#xff1a; startActivity(new Intent(源页面.this&#xff0c;目标页面.class))&#xff1b; 从当前页面回到上一个页面&#xff0c;相当于关闭当前页面&#xff0c;返回代码如下&#xff1a; finis…

ubuntu20.04 解决Pycharm没有写入权限,无法通过检查更新更新的问题

ubuntu20.04 解决Pycharm没有写入权限&#xff0c;无法通过检查更新更新的问题 您提供的截图显示了一个关于PyCharm更新的问题&#xff0c;其中提到了&#xff1a;“PyCharm 没有 /opt/pycharm-community-2024.1.2 的写入权限&#xff0c;请通过特权用户运行以更新。” 这表明…

云原生之运维监控实践-使用Telegraf、Prometheus与Grafana实现对InfluxDB服务的监测

背景 如果你要为应用程序构建规范或用户故事&#xff0c;那么务必先把应用程序每个组件的监控指标考虑进来&#xff0c;千万不要等到项目结束或部署之前再做这件事情。——《Prometheus监控实战》 去年写了一篇在Docker环境下部署若依微服务ruoyi-cloud项目的文章&#xff0c;当…

WinDefender Weaker

PPL Windows Vista / Server 2008引入 了受保护进程的概念&#xff0c;其目的不是保护您的数据或凭据。其最初目标是保护媒体内容并符合DRM &#xff08;数字版权管理&#xff09;要求。Microsoft开发了此机制&#xff0c;以便您的媒体播放器可以读取例如蓝光&#xff0c;同时…

Python 编程入门指南(二)

1. 条件语句 条件语句用于根据条件的真假来控制代码的执行流。在Python中,可以使用if、elif和else关键字来实现条件判断。 例如: x = 10 y = 20 if y > x:print("y 大于 x") elif y == x:

计算机视觉 1-8章 (硕士)

文章目录 零、前言1.先行课程&#xff1a;python、深度学习、数字图像处理2.查文献3.环境安装 第一章&#xff1a;概论1.计算机视觉的概念2.机器学习 第二章&#xff1a;图像处理相关基础1.图像的概念2.图像处理3.滤波器4.卷积神经网络CNN5.图像的多层表示&#xff1a;图像金字…

实习冲刺练习 第二十三天

每日一题 回文链表. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:bool isPalindrome(ListNode* head) {if(headnullptr) return false;vector<int> v;while(head!nullptr){//将链表的值存入数组中v.push_back(head->val);headhead->next;}in…

《C++ 实现生成多个弹窗程序》

《C 实现生成多个弹窗程序》 在 C 编程中&#xff0c;我们可以利用特定的系统函数来创建弹窗&#xff0c;实现向用户展示信息等功能。当需要生成多个弹窗时&#xff0c;我们可以通过循环结构等方式来达成这一目的。 一、所需头文件及函数介绍 在 Windows 操作系统环境下&#…