YOLO 目标框回归(三)

2023-05-16

边框预测公式分析 

Cx,Cy 是 feature map 中 grid cell 的左上角坐标;Pw,Ph 是预设的 anchor box 映射到 feature map 中的宽和高。

最终得到的边框坐标值是 bx,by,bw,bh,即边界框 bbox 相对于 feature map 的位置和大小,是我们需要的预测输出坐标。但网络实际上的学习目标是 tx,ty,tw,th 偏移量(offsets),其中 tx,ty 是预测的坐标偏移值,tw,th 是尺度缩放,有了这4个offsets,可以根据公式去求得 bx,by,bw,bh。

问题1:为何不直接学习bx,by,bw,bh 呢?

解答:YOLO 的输出是卷积特征图,包含沿特征图深度的边界框属性(边界框属性由彼此堆叠的单元格预测得出)。如果需要在 (5,6) 处访问该单元格的第二个边框bbox,需要通过 map[5,6,(5+C):2*(5+C)] 将其编入索引。这种格式对于输出处理过程(例如通过目标置信度进行阈值处理、添加对中心的网格偏移、应用锚点等)很不方便,因此求偏移量即可。另外,通过学习偏移量,就可以通过网络原始给定的 anchor box 坐标经过线性回归(平移加尺度缩放)去逐渐靠近 groundtruth。

问题2:anchor box 的作用。

解答:YOLOv3 为每种 FPN 预测特征图(13x13,26x26,52x52)设定 3 种 anchor box,总共聚类出 9 种尺寸的 anchor box。在 COCO 数据集这 9 个 anchor box 是:(10x13),(16x30),(33x23),(30x61),(62x45),(59x119),(116x90),(156x198),(373x326)。

分配上,最小的 13x13 特征图上由于其感受野最大故应用最大的 anchor box (116x90、156x198、373x326),适合检测较大的目标。中等的 26x26 特征图上由于其具有中等感受野,故应用中等的 anchor box (30x61、62x45、59x119),适合检测中等大小的目标。较大的 52x52 特征图上由于其具有较小的感受野,故应用最小的 anchor box(10x13、16x30、33x23),适合检测较小的目标。特征图的每个像素(即每个grid)都会有对应的三个 anchor box,如 13x13 特征图的每个 grid 都有三个 anchor box (116x90、156x198、373x326,这几个坐标需除以32缩放尺寸),即会使用 13×13×3=507 个 anchor box。

偏移量的求解

4 个坐标(tx,ty,tw,th)对于训练样本,在大多数文章里需要用到 ground truth 的真实框来求这4个坐标:

\LARGE \begin{aligned} t_{x} &=\left(G_{x}-P_{x}\right) / P_{w} \\ t_{y} &=\left(G_{y}-P_{y}\right) / P_{h} \\ t_{w} &=\log \left(G_{w} / P_{w}\right) \\ t_{h} &=\log \left(G_{h} / P_{h}\right) \end{aligned}

上述公式是 faster-rcnn 系列文章用到的公式,Pw,Ph 是预设的 anchor box 的在 feature map 上的宽和高。Gx,Gy,Gw,Gh 是 ground truth 在这个 feature map 的4个坐标。Gx、Gy、Gw、Gh 要先根据原图纵横比不变映射为416*416坐标下的一个子区域如416*312,取 min(w/img_w, h/img_h)这个比例来缩放成416*312,再填充为416*416,并把 x1,x2,y1,y2 的坐标系的换算从针对实际框的坐标系 416*312 变为 416*416 下,保证 bbox 不会扭曲,然后除以 stride 得到相对于 feature map 的坐标。

问题3:用 x,y 坐标减去 anchor box 的 x,y 坐标得到偏移量好理解,为何要除以 feature map 上 anchor box 的宽和高呢

解答:可能是为了把绝对尺度变为相对尺度。不同尺度的 anchor box 如果都用 Gx-Px 来衡量显然不对,有的 anchor box 大,有的却很小。都用 Gx-Px 会导致不同尺度的 anchor box 权重相同,而大的 anchor box 能容忍大点的偏移量,小的 anchor box 对小偏移都很敏感,故除以宽和高可以权衡不同尺度下的预测坐标偏移量。

但是 yolov3 与 faster-rcnn 文章用到的公式在前两行不同,yolov3 里 Px,Py 换为了 feature map 上的 grid cell 左上角坐标 Cx,Cy了,即 yolov3 中是 Gx,Gy 减去 grid cell 左上角坐标 Cx,Cy。x,y 坐标并没有针对 anchon box 求偏移量,所以并不需要除以 Pw,Ph。这样可以直接求 bbox 中心距离 grid cell 左上角的坐标的偏移量。tw 和 th的公式 yolov3 和 faster-rcnn 系列是一样的,是物体所在边框的长宽和 anchor box 长宽之间的比率,不管 Faster-RCNN 还是 YOLO,都不是直接回归 bounding box 的长宽而是尺度缩放到对数空间。

\LARGE \begin{aligned} t_{x} &=\left(G_{x}-C_{x}\right) \\ t_{y} &=\left(G_{y}-C_{y}\right) \\ t_{w} &=\log \left(G_{w} / P_{w}\right) \\ t_{h} &=\log \left(G_{h} / P_{h}\right) \end{aligned}

问题4:为何不是直接回归 bounding box 的长宽,而是尺度缩放到对数空间?

解答:怕训练带来不稳定的梯度。如果不做变换,直接预测相对形变 tw 和 th,那么要tw,th>0。因为框的宽高不可能是负数。这样,是在做一个有不等式条件约束的优化问题,没法直接用 SGD 来做。所以先取一个对数变换,将其不等式约束去掉。

anchors 与 gt 的匹配

这里就有个重要的疑问了,一个尺度的feature map有三个anchors,那么对于某个ground truth框,究竟是哪个anchor负责匹配它呢?和YOLOv1一样,对于训练图片中的ground truth,若其中心点落在某个cell内,那么该cell内的3个anchor box负责预测它,具体是哪个anchor box预测它,需要在训练中确定,即由那个与ground truth的IOU最大的anchor box预测它,而剩余的2个anchor box不与该ground truth匹配。

YOLOv3 需要假定每个 cell 至多含有一个 grounth truth,而在实际上基本不会出现多于 1 个的情况。与 ground truth 匹配的 anchor box 计算坐标误差、置信度误差(此时target为1)以及分类误差,而其它的 anchor box 只计算置信度误差(此时target为0)。在训练过程中划分正负样本是非常重要的,因为 anchor 很多,只有对一大堆 anchor box 划分了正负样本,才能有效地用正样本参与损失函数训练。但问题是三个检测层,那么多 anchor box,如果只把 gt 匹配一个 anchor,那么正样本数量会极其稀少,对训练极为不利。

问题5:如何划分正负样本

解答:假设 IOU 阈值为0.7,所有锚点框与真实标签进行匹配,需要构造 IOU 矩阵,每一行代表一个锚点框,行数代表 anchor box 数量,每一列代表一个真值框,列数代表gt的个数。然后执行 3 个标准:

  • 对于任何一个锚点框,与所有标签的最大 IOU 小于 0.3,则视为负样本
  • 对于任何一个真值,与其有最大 IOU 的瞄点框视为正样本
  • 对于任何一个瞄点框,与所有真值框的最大 IOU 大于 0.7 则视为正样本。

这样的三个标准顺序不能变动,保证了多个瞄点框对应一个真值,而一个真值框不能对应多个瞄点框。

根据偏移量求得真正的检测框

有了平移(tx,ty)和尺度缩放(tw,th),就能让 anchor box 经过微调与 grand truth 重合。如下图,红色框为 anchor box,绿色框为 Ground Truth,平移+尺度缩放可实线红色框先平移到虚线红色框,然后再缩放到绿色框。边框回归最简单的想法就是通过平移加尺度缩放进行微调嘛。

问题6:边框回归为何只能微调?

当输入的 Proposal 与 Ground Truth 相差较小时,即IOU很大时,可以认为这种变换是线性变换可以用线性回归(线性回归即给定输入的特征向量 X,学习一组参数 W,经过线性回归后的值跟真实值 Y(Ground Truth)非常接近)来建模对窗口进行微调,否则会导致训练的回归模型不 work(当 Proposal 与 GT 离得较远,就是复杂的非线性问题,此时用线性回归建模不合理) 

那么训练时用的 ground truth 的4个坐标去做差值和比值得到 tx,ty,tw,th,测试时就用预测的bbox 就好了,公式修改就简单了,把 Gx 和 Gy 改为预测的x,y;Gw、Gh改为预测的w,h即可。

网络可以不断学习 tx,ty,tw,th 偏移量和尺度缩放,预测时使用这4个offsets求得bx,by,bw,bh即可。

\LARGE \begin{gathered} b_{x}=\sigma\left(t_{x}\right)+c_{x} \\ b_{y}=\sigma\left(t_{y}\right)+c_{y} \\ b_{w}=p_{w}e^{t_w} \\ b_{h}=p_{h}e^{t_h} \end{gathered}

问题7:tx,ty为何要sigmoid一下啊?

解答:前面讲了在 yolov3 中没有让 Gx - Cx 后除以 Pw 得到 tx,而是直接 Gx - Cx 得到 tx,这样会有问题是导致 tx 比较大且很可能 >1(因为没有除以 Pw 归一化尺度)。用 sigmoid 将 tx,ty 压缩到 [0,1] 区间內,可以有效的确保目标中心处于执行预测的网格单元中,防止偏移过多。举个例子,网络不会预测边界框中心的确切坐标而是预测与预测目标的 grid cell 左上角相关的偏移 tx,ty。如 13*13 的 feature map 中,某个目标的中心点预测为(0.4,0.7),它的 Cx,Cy 即中心落入的 grid cell 坐标是(6,6),则该物体在 feature map 中的中心实际坐标显然是(6.4,6.7),这种情况没毛病。但若 tx,ty 大于1,比如(1.2,0.7)则该物体在 feature map 的的中心实际坐标是(7.2,6.7),这时候该物体中心在这个物体所属 grid cell 外面了,但(6,6)这个 grid cell 却检测出我们这个单元格内含有目标的中心(yolo 是采取物体中心归哪个 grid cell 整个物体就归哪个 grid celll了),这样就矛盾了,因为左上角为(6,6)的 grid cell 负责预测这个物体,这个物体中心必须出现在这个grid cell中而不能出现在它旁边网格中,一旦 tx,ty 算出来大于 1 就会引起矛盾,因而必须归一化。
扩展:当然 yolov5 里就不再是这样了,其为了使得有更多目标归属于每个格子,就不再限定偏移量为 [0-1],而是能够使得隔壁的目标也属于当前格子。

问题8:最后两行公式,tw 为何要指数呀?

解答:因为 tw,th 是 log 尺度缩放到对数空间了,当然要指数回来,而且这样可以保证大于0。至于左边乘以 Pw,Ph 是因为 tw=log(Gw/Pw) 当然应该乘回来得到真正的宽高。  

记 feature map 大小为 W*H(如13*13),可将 bbox 相对于整张图片的位置和大小计算出来(使4个值均处于[0,1]区间内)约束了bbox的位置预测值到[0,1]会使得模型更容易稳定训练(如果不是[0,1]区间,yolo的每个bbox的维度都是85,前5个属性是(Cx,Cy,w,h,confidence),后80个是类别概率,如果坐标不归一化,和这些概率值一起训练肯定不收敛)。

只需要把之前计算的bx,bw都除以W,把by,bh都除以H。即

\LARGE \begin{aligned} &b x=(\sigma(t x)+C x) / W \\ &b y=(\sigma(t y)+C y) / H \\ &b w=\left(P w e^{t w}\right) / W \\ &b h=\left(P h e^{t h}\right) / H \end{aligned}

YOLOv5采用跨邻域网格的匹配策略,从而得到更多的正样本anchor,可加速收敛。

从当前网络的上、下、左、右的四个网格中找到离目标中心点最近的两个网格,再加上当前网格共三个网格进行匹配。

\LARGE \begin{gathered} b_{x}=2 \sigma\left(t_{x}\right)-0.5+c_{x} \\ b_{y}=2 \sigma\left(t_{y}\right)-0.5+c_{y} \\ b_{w}=p_{w}\left(2 \sigma\left(t_{w}\right)\right)^{2} \\ b_{h}=p_{h}\left(2 \sigma\left(t_{h}\right)\right)^{2} \end{gathered}

参考文章:超详细的Yolo检测框预测分析 - 知乎 (zhihu.com)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

YOLO 目标框回归(三) 的相关文章

  • 嵌入式Linux调试器GDB的使用

    调试一直是程序开发的重中之重 xff0c 使用GDB调试可以帮助我们快速找到程序中的错误 注意 xff1a 在进行GDB调试之前 xff0c 程序在gcc编译时要加上 g 选项 1 进入GDB xff1a gdb 可执行文件名 2 查看GD
  • 华清数据结构项目实训——学生信息管理系统

    模块划分及主要文件 1 主程序模块 主要功能 xff1a 程序的入口 主要文件 xff1a main c 2 菜单模块 主要功能 xff1a 完成菜单的显示以及登录和调用相应功能函数 主要文件 xff1a menu h menu c 3 学
  • sqlite3的安装以及增删改查排序功能的实现

    目录 一 安装sqlite3 1 安装sqlite3数据库 xff1a 2 安装编译依赖库 3 安装可视化界面 4 验证数据库是否安装成功 二 常用数据库指令及SQL数据类型 1 常用数据库指令 2 常用SQL数据类型 三 数据库操作 1
  • C++函数模板

    前言 模板是一个通用框架 xff0c 是C 43 43 泛型编程 思想的主要体现 C 43 43 提供了函数模板 和类模板 两种模板机制 xff0c 本文介绍的是函数模板相关的知识 一 函数模板的作用及语法 作用 xff1a 用一个虚拟的类
  • MQ-2烟雾传感器

    一 MQ 2烟雾传感器简介 MQ 2常用于家庭和工厂的气体泄漏监测装置 xff0c 适宜于液化气 苯 烷 酒精 氢气 烟雾等的探测 故因此 xff0c MQ 2可以准确来说是一个多种气体探测器 MQ 2的探测范围极其的广泛 它的优点 xff
  • PX4姿态解算源码原理理解

    PX4源码原理理解一 xff0e 主要参考资料链接 xff1a 1 1 取PX4源码一小部分姿态解算来进行讲解姿态解算源码中文注释 xff1a https blog csdn net zouxu634866 article details
  • Linux 使用 curl 命令发送带参请求

    1 发送 post 请求 xff08 请求参数为 json 格式 xff09 xff1a curl i X POST H 39 Content type 39 39 application json 39 d 39 34 id 34 34
  • 理解和创建:Anaconda、Jupyterlab、虚拟环境、Kernel

    Anaconda如何创建虚拟环境并作为jupyterlab的内核使用 先明确一波概念一 虚拟环境 1 环境是什么 xff1f 2 虚拟环境是什么 xff1f 3 为什么需要创建虚拟环境 xff1f 4 Anaconda创建 激活 退出 删除
  • 【Windows】六种正确清理C盘的方法,解决你的红色烦恼

    如何正确的清理C盘 前言清理方法1 利用Windows自己附带的磁盘清理工具2 开启自动清理3 通过 配置存储感知或立即运行 来清理4 管理C盘中的程序5 系统文件夹转移6 将C盘现有内容转移到别的盘 参考链接 前言 Windows操作系统
  • 【机器学习】数据增强(Data Augmentation)

    文章目录 一 引言 背景二 为什么需要数据增强 xff1f 三 什么是数据增强 xff1f 定义分类 四 有监督的数据增强1 单样本数据增强 xff08 1 xff09 几何变换类 xff08 2 xff09 颜色变换类 2 多样本数据增强
  • 基于FRFT的雷达辐射源信号特征分析及提取

    信号在FRFT域上表示 xff0c 同时包含了信号的时域信息和频域信息 论文中提出的算法流程如图 xff1a 步骤 xff11 xff1a 提取雷达辐射源信号脉冲序列的脉冲 xff0c 进行相应的预处理 xff0c 包括带宽和能量的归一化
  • 【Linux】查看、激活、退出虚拟环境以及 CommandNotFoundError 错误解决

    文章目录 一 虚拟环境有关命令二 CommandNotFoundError Your shell has not been properly configured to use 39 conda activate 39 参考链接 一 虚拟环
  • 【PyTorch】torch.utils.data.DataLoader 简单介绍与使用

    文章目录 一 torch utils data DataLoader 简介二 实例参考链接 一 torch utils data DataLoader 简介 作用 xff1a torch utils data DataLoader 主要是对
  • 【Python】np.unique() 介绍与使用

    文章目录 一 np unique 介绍二 np unique 原型三 实例参考链接 一 np unique 介绍 对于一维数组或者列表 xff0c np unique 函数 去除其中重复的元素 xff0c 并按元素 由小到大 返回一个新的无
  • 【Pytorch】交叉熵损失函数 CrossEntropyLoss() 详解

    文章目录 一 损失函数 nn CrossEntropyLoss 二 什么是交叉熵三 Pytorch 中的 CrossEntropyLoss 函数参考链接 一 损失函数 nn CrossEntropyLoss 交叉熵损失函数 nn Cross
  • 【Linux】rm 命令:删除文件/文件夹

    文章目录 一 删除文件 文件夹 xff1a rm 命令二 删除文件 xff08 即这个文件被删除 xff09 三 删除文件夹四 注意参考链接 一 删除文件 文件夹 xff1a rm 命令 rm 是强大的删除命令 xff0c 它可以 永久性地
  • 【Pytorch】torch.max() 函数详解

    文章目录 一 一个参数时的 torch max 1 函数介绍2 实例 二 增加指定维度时的 torch max 1 函数介绍2 实例 三 两个输入张量时的 torch max 1 函数介绍2 实例 参考链接 一 一个参数时的 torch m
  • 【机器学习】KNN 算法介绍

    文章目录 一 KNN 简介二 KNN 核心思想实例分析 xff1a K 值的影响 三 KNN 的关键1 距离计算1 闵可夫斯基距离2 曼哈顿距离3 欧氏距离4 切比雪夫距离5 余弦距离总结 2 K值选择 四 KNN 的改进 xff1a KD
  • 【机器学习】Radius Neighbors Classifier(rNN,radius nearest neighbors)

    文章目录 一 半径近邻分类器 简介二 半径近邻分类器算法三 Radius Neighbors Classifier With Scikit Learn参考链接 一 半径近邻分类器 简介 Radius Neighbors Classifier
  • 扫盲:单片机入门分享 晶振 复位电路与电源

    学单片机走过许多弯路 xff0c 挖过许多坑 xff0c 浪费了很多时间 xff0c 做过实际产品后回顾过去的学习经历 xff0c 发现很多坑其实是可以避免的 xff0c 单片机的入门应该可以更轻松一点 xff0c 借CSDN论坛一方宝地

随机推荐

  • VR技术原理分析,【VR原理入门理论篇】

    VR技术原理分析 xff0c VR原理入门理论篇 xff0c 学习研究VR技术必须要了解的理论知识 目录 1 VR沉浸感和交互作用产生的原理 xff1a 2 关于沉浸感和交互作用的定义 3 如何生成符合VR要求的虚拟世界 4 最主流的VR开
  • ST-Link驱动安装不正确,设备管理器黄色感叹号,win10安装stlink驱动

    这是由于驱动没有安装好导致的 xff0c 从该链接下载驱动文件 xff1a http pan baidu com s 1bog5FZ5 我是win10 win7 win8一样的办法 解压缩后 xff0c 直接以管理员身份运行其中的dpins
  • 使用CIDR计算划分子网个数

    概念 CIDR xff08 无类别域间路由 xff0c Classless Inter Domain Routing xff09 是一种IP地址划分的方法 xff0c 其目的是更加有效地使用IPv4地址空间 CIDR的原理是将一个IP地址划
  • 关于字符串的长度和大小的定义

    char a 61 aaaaa 字符串长度为5 xff0c 数组长度 xff08 大小 xff09 为6 xff1b char b 5 61 aaaaa 字符串长度不确定 xff0c 数组长度 xff08 大小 xff09 为5 xff1b
  • 用安卓设备识别ArUco码

    先来看下效果 静态图片中的ArUcon码识别 在之前程序的基础上再添加一个Button和TextView xff0c 点击 识别 按钮检测照片中的ArUco码后 xff0c 在屏幕最下方显示识别到的ArUco的id和四个角点坐标 xff0c
  • VSCode集成Git

    VSCode集成Git流程 一 xff0c 下载git并配置环境变量 1 从git官网下载一个git安装包 xff0c 官网下载地址 git下载 2 下载完成后 xff0c 一路NEXT走下去 xff0c 只需注意下面这几个页面的配置 xf
  • Vscode使用clang-format格式化代码

    使用Vscode格式化代码 使用Vscode格式化代码操作步骤 使用Vscode格式化代码 可以在vscode上使用clang format对C C 43 43 代码自动格式化 xff0c 配置自己想要的格式规范 xff0c 解脱代码格式的
  • 二维数组转稀疏数组的思路

    二维数组转稀疏数组的思路 遍历 原始的二维数组 xff0c 得到有效数据的个数sum根据sum就可以创建稀疏数组sparseArr int sum 43 1 3 将二维数组的有效数据存入到稀疏数组 span class token comm
  • 实例方法和静态方法常识

    1 调用方式上 静态方法依赖于类 xff0c 通过类 静态方法调用 xff1b 实例方法依赖于类的对象 xff0c 需要创建对象后 xff0c 对象 实例方法使用 2 使用上 实例方法内部不能定义静态变量 xff0c 会出现编译错误 xff
  • 设计模式(1)

    设计模式的作用 代码重用性 可读性 可扩展性 可靠性 使程序呈现高内聚 xff0c 低耦合的特性 设计模式常用的七大原则有 单一职责原则 接口隔离原则 依赖倒转原则 里式替换原则 开闭原则OCP 迪米特法则 合成复用原则 单一职责原则 对类
  • windows安装配置zookeeper后启动出现的错误:java.io.IOException: Unable to create data directory

    今天学习zookeeper集群部署在Windows10上出现了很多问题现在一一叙述一下 问题1 再点击zkServer cmd出现闪退 需要用编译工具打开在最后一行加入pause命令 问题2datadir权限问题 在c盘部署是是需要系统管理
  • IDEA 查找接口的实现 的快捷键

    IDEA 风格 ctrl 43 alt 43 B Eclipse 风格 ctrl 43 T 例子
  • WebPack4学习实践笔记(一)

    一 准备 nodejs安装教程 xff1a https blog csdn net FED AF article details 105747632 xff09 二 安装 xff08 1 xff09 全局安装 初始化npm C Users
  • 可重入锁(又名递归锁)

    可重入锁 指的是同一线程外层函数获得锁之后 xff0c 内层递归函数仍能获取该锁的代码 xff0c 在同一线程的外层获取锁的时候 xff0c 在进入内层方法会自动获取锁 xff0c 也就是说线程可以任意进入它已经拥有的锁的同步代码块 syn
  • Java 读取TXT文件-行读取

    Java 读取TXT文件 行读取 span class token keyword public span span class token keyword static span String span class token funct
  • springMVC 指定文件 压缩下载

    span class token keyword package span span class token namespace com span class token punctuation span lyt span class to
  • HC-SR04超声波模块

    1 硬件原理图 2 传感器参数表 电气参数HC SR04 超声波模块工作电压DC 5 V工作电流15mA工作频率40kHz最远射程4m最近射程2cm测量角度15 度输入触发信号10uS 的 TTL 脉冲输出回响信号输出 TTL 电平信号 x
  • STM32F1系列-UCOSIII配置之delay_init()函数详解

    一 时钟选择 SysTick CLKSourceConfig xff08 xff09 xff1b 选择systick时钟 xff0c 函数配置的寄存器如下所示 找到该函数的定义 xff0c 其两个参数的数值如下 该函数选择的参数是SysTi
  • xfce4-session: Unable to access file /home/user/.ICEauthority: Permission denied

    wsl想要运行startxfce4却出现错误 xff1a usr bin startxfce4 X server already running on display 172 18 64 1 0 xfce4 session Unable t
  • YOLO 目标框回归(三)

    边框预测公式分析 Cx xff0c Cy 是 feature map 中 grid cell 的左上角坐标 xff1b Pw xff0c Ph 是预设的 anchor box 映射到 feature map 中的宽和高 最终得到的边框坐标值