YOLO中Anchor生成介绍

Anchor生成机制

  • YOLOv1
  • YOLOv2
  • YOLOv4
    • 模型输出decode
      • 1.维度变换
      • 2.读取位置信息
      • 3.坐标变换
      • 4.构建网格
      • 5. 计算实际偏移量
      • 6.得到输出

YOLOv1

利用全连接层直接对边界框进行预测

YOLOv2

YOLOv2通过缩减网络,使用416x416的输入,模型下采样的总步长为32,最后得到13x13的特征图,然后对13x13的特征图的每个cell预测5个anchor boxes,对每个anchor box预测边界框的位置信息、置信度和一套分类概率值。使用anchor boxes之后,YOLOv2可以预测13x13x5=845个边界框

YOLOv4

完成cfg文件的解析,模型的创建与权重文件的加载之后,现在要做的就是执行检测操作,主要调用了utils/utils.py中的do_detect() 函数,在demo.py中:

boxes = do_detect(m, sized, 0.5, 0.4, use_cuda)

模型forward后输出结果存在list_boxes中,因为有3个yolo输出层,所以这个列表list_boxes中又分为3个子列表;

其中list_boxes[0]中存放的是第一个yolo层输出,其特征图大小对于原图缩放尺寸为8,即strides[0], 对于608x608图像来说,该层的featuremap尺寸为608/8=76;则该层的yolo输出数据维度为[batch, (classnum+4+1)*num_anchors, feature_h, feature_w] , 对于80类的coco来说,测试图像为1,每个yolo层每个特征图像点有3个锚点,该yolo层输出是[1,255,76,76];对应锚点大小为[1.5,2.0,2.375,4.5,5.0,3.5]; (这6个数分别是3个锚点的w和h,按照 w 1 , h 1 , w 2 , h 2 , w 3 , h 3 w_1,h_1,w_2,h_2,w_3,h_3 w1,h1,w2,h2,w3,h3排列);

  • 第二个yolo层检测结果维度为[1,255,38,38],对应锚点大小为:[2.25,4.6875,4.75,3.4375,4.5,9.125],
    输出为 [1,255,38,38]
  • 第三个yolo层检测维度为[1,255,19,19],对应锚点大小为:[4.4375,3.4375,6.0,7.59375,14.34375,12.53125],
    输出为 [1,255,19,19];

do_detect() 函数中主要是调用了
get_region_boxes1(output, conf_thresh, num_classes, anchors, num_anchors, only_objectness=1, validation=False)
这个函数对forward后的output做解析并做nms操作;

每个yolo层输出数据分析,对于第一个yolo层,输出维度为[1,85*3,76,76 ]; 会将其reshape为[85, 1*3*76*76],即有1*3*76*76个锚点在预测,每个锚点预测信息有80个类别的概率和4个位置信息和1个是否包含目标的置信度;

yolov4的输出需要包含的信息有:物体的位置信息、有物体的概率、物体的分类,可以写为:( t x , t y , t w , t h , o b j , c l s t_x, t_y, t_w, t_h, obj, cls tx,ty,tw,th,obj,cls),其中前四个是物体的位置信息,最后一个cls,根据分类的类别数,维度不同,如果只有1个类别,那就只占1个位置,如果是2个类别,就是2个位置,使用one-hot编码。

而在实际的yolov4的最终输出之前是(19,19,1024),通过蓝色的18个(当只有1个分类类别的时候,如果有2个,那就是19个卷积核)111024的卷积核,得到(19,19,18),最后reshape成(3,19,19,tx, ty, tw, th, obj, cls)。后面的是检测的物体信息,而前面的(3,19,19)的理解如下:

19*19个特征点,等同于把原图分成了19 *19个网格,原图的输入是608 *608的,那么每一个网格的大小就是608/19=32,每一个特征点只关注对应的网格,判断对应的网格是否有物体。

模型输出decode

模型的输出有三个,分别是(B, 255, 19, 19),(B, 255, 38, 38),(B, 255, 76, 76),因此需要对这三个输出分别解码。

1.维度变换

首先需要将输出view成(B, A, n_ch, H, W)的形式,其中H和W就是输出的尺寸,A是锚框数量,n_ch是包含了bx, by, bw, bh, obj, cls的信息,维度为4+1+80=85。之后再进行一个维度变换,最终得到(B, 3, 19, 19, 85)的维度(以第一个为例)。此时,最后一个维度85,包含了我们解码所需的所有信息,也就是说,我们需要对前面B319*19这么多的数据,都进行同样方式的解码。

2.读取位置信息

接下来我们取出来bx, by, bw, bh, obj, cls。注意,此时除了cls之外,其他所有的维度,都减少了一维变成了(B, 3, 19, 19),因为cls是以切片形式取的,所以维度数量不变,是(B, 3, 19, 19, 80)。

# 取出来 bx, by, bw, bh
bx, by = output[..., 0], output[..., 1]
bw, bh = output[..., 2], output[..., 3]
# 取出来obj和cls
obj = output[..., 4]
cls = output[..., 5:]

3.坐标变换

我们需要先把bx, by取一个sigmoid,把bw和bh取一个exp。这里加上了缩放因子,据说当图片中的目标既有大又有小的时候,会起作用,暂时没见到实际起作用的情况,不过先加上了,当缩放因子为1的时候,相当于不起作用。这里我们同时也对物体以及分类的置信度取sigmoid。

    # 进行初步转换bx = torch.sigmoid(bx)by = torch.sigmoid(by)bw = torch.exp(bw) * scale_x_y - 0.5 * (scale_x_y - 1)bh = torch.exp(bh) * scale_x_y - 0.5 * (scale_x_y - 1)# 对物体置信度,分类置信度也取sigmoiddet_confs = torch.sigmoid(obj)cls_confs = torch.sigmoid(cls)

4.构建网格

目标是找到点相对于整张图的偏移的比例,但由于我们分了网格,因此先找相对于网格的偏移比例。

这里,图像被分成了19*19个网格,假如中心点在第2行第3列的网格里面。

相对网格的偏移量肯定是小数,比如在x轴方向上偏移是0.5,在y轴上偏移是0.2,也就是在网格中间偏上的位置。

那么,以网格为单位,相对于所有网格来说,中心点的实际偏移量:

在x轴方向的0.5,加上偏移的网格数,也就是2(从0开始计数),那么得到了2.5就是以网格为单位,相对于整张网格图的x轴偏移量。同理,y轴方向上,相对于y轴的,就是1.5。

因此我们需要把x和y方向上的网格数量构建一下,并找到以网格为单位的偏移量。

    # 构建网格grid_x和grid_ygrid_x = torch.arange(W, dtype=torch.float).repeat(1, 3, W, 1).to(device)grid_y = torch.arange(W, dtype=torch.float).repeat(1, 3, H, 1).permute(0, 1, 3, 2).to(device)# 求bx和bybx = bx + grid_xby = by + grid_y

5. 计算实际偏移量

既然找到了相对于网格的偏移量,那么偏移的比例就是偏移量除以网格长度,这个比例,就是相对于网格的偏移比例,同时也是相对于整张图的偏移比例。另外根据解码图,我们对于w和h,还需要乘上先验框的宽、高,得到最终的bw和bh。

    # 取每个anchor的长和宽,求bw和bhfor i in range(num_anchors):bw[:, i, ...] *= anchors[i * 2]bh[:, i, ...] *= anchors[i * 2 + 1]# 对数据转换,除以网格数量,得到相对整张图的偏移的比例,并增加一个维度bx = (bx / W).unsqueeze(-1)by = (by / H).unsqueeze(-1)bw = (bw / W).unsqueeze(-1)bh = (bh / H).unsqueeze(-1)

6.得到输出

现在对于中心点相对于原图的偏移量,以及宽高都得到了,我们把这四个数据结合起来,再把obj和cls的置信度都合在一起,就得到了我们最终解码后的输出,用于后续的画图等计算。

    # 四个数据拼接起来,并reshape成[B, -1, 4]的形状boxes = torch.cat([bx, by, bw, bh], dim=-1).reshape(B,A*W*H, 4)det_confs = det_confs.unsqueeze(-1).reshape(B,A*W*H, 1)cls_confs = cls_confs.reshape(B,A*W*H, num_classes)outputs = torch.cat([boxes, det_confs, cls_confs], dim=-1)

注:(网格生成)

grid_x = torch.linspace(0, input_width - 1, input_width).repeat(input_height, 1).repeat(batch_size * len(self.anchors_mask[i]), 1, 1).view(x.shape).type(FloatTensor)
#先生成一行(width),在重复一列(height),再扩充维度,最后view成[batchsize, 3, h, w]grid_y = torch.linspace(0, input_height - 1, input_height).repeat(input_width, 1).t().repeat(batch_size * len(self.anchors_mask[i]), 1, 1).view(y.shape).type(FloatTensor)

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

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

相关文章

flutter开发实战-实现自定义按钮类似UIButton效果

flutter开发实战-实现自定义按钮类似UIButton效果 最近开发过程中需要实现一下UIButton效果的flutter按钮,这里使用的是监听手势点击事件。 一、GestureDetector GestureDetector属性定义 GestureDetector({super.key,this.child,this.onTapDown,this.onTapUp,t…

附件展示 点击下载

效果图 实现代码 <el-table-column prop"attachment" label"合同附件" width"250" show-overflow-tooltip><template slot-scope"scope"><div v-if"scope.row.cceedcAppendixInfoList &&scope.row.ccee…

路由的hash和history模式的区别

目录 ✅ 路由模式概述 一. 路由的hash和history模式的区别 1. hash模式 2. history模式 3. 两种模式对比 二. 如何获取页面的hash变化 ✅ 路由模式概述 单页应用是在移动互联时代诞生的&#xff0c;它的目标是不刷新整体页面&#xff0c;通过地址栏中的变化来决定内容区…

SQL 表别名 和 列别名

列表名 列表名之后 order by 可以用别名 也可以用原名&#xff0c; where 中不能用别名的 SQL语句执行顺序&#xff1a; from–>where–>group by -->having — >select --> order 第一步&#xff1a;from语句&#xff0c;选择要操作的表。 第二步&#xff1…

SpringBoot图片上传并对大小进行压缩(缩放比例)

前言 最近有个新需求&#xff0c;项目中对客户上传jpg图片的时候&#xff0c;每次都是校验大小必须≤30KB&#xff0c;但是客户实际使用的时候&#xff0c;总是会自己去进行压缩&#xff0c;压缩到30KB以内之后再上传&#xff0c;使用时间长了之后&#xff0c;客户总会觉得很麻…

react学习笔记——1. hello react

包含的包一共有4个&#xff0c;分别的作用如下&#xff1a; babel.min.js&#xff1a;可以进行ES6到ES5的语法转换&#xff1b;可以用于import&#xff1b;可以用于将jsx转换为js。注意&#xff0c;在开发的时候&#xff0c;这个转换&#xff08;jsx转换js&#xff09;不在线上…

Tcp的粘包和半包问题及解决方案

目录 粘包&#xff1a; 半包&#xff1a; 应用进程如何解读字节流&#xff1f;如何解决粘包和半包问题&#xff1f; ①&#xff1a;固定长度 ②&#xff1a;分隔符 ③&#xff1a;固定长度字段存储内容的长度信息 粘包&#xff1a; 一次接收到多个消息&#xff0c;粘包 应…

HBase概述

HBase 一 HBase简介与环境部署 1.1 HBase简介&在Hadoop生态中的地位 1.1.1 什么是HBase HBase是一个分布式的、面向列的开源数据库HBase是Google BigTable的开源实现HBase不同于一般的关系数据库, 适合非结构化数据存储 1.1.2 BigTable BigTable是Google设计的分布式…

mysql的update_time

CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50) NOT NULL,age INT,update_time TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间 );具体解释如下&#xff1a; DEFAULT CURRENT_TIMESTAMP: 这部分表示当插入…

【CI/CD】图解六种分支管理模型

图解六种分支管理模型 任何一家公司乃至于一个小组织&#xff0c;只要有写代码的地方&#xff0c;就有代码版本管理的主场&#xff0c;初入职场&#xff0c;总会遇到第一个拦路虎 git 管理流程&#xff0c;但是每一个企业似乎都有自己的 git 管理流程&#xff0c;倘若我们能掌握…

如何在不使用脚本和插件的情况下手动删除 3Ds Max 中的病毒?

如何加快3D项目的渲染速度&#xff1f; 3D项目渲染慢、渲染卡顿、渲染崩溃&#xff0c;本地硬件配置不够&#xff0c;想要加速渲染&#xff0c;在不增加额外的硬件成本投入的情况下&#xff0c;最好的解决方式是使用渲云云渲染&#xff0c;在云端批量渲染&#xff0c;批量出结…

ABAP 自定义搜索功能 demo1

ABAP 自定义搜索功能 demo1 效果&#xff1a; 双击选中行则为选中对应发票 实现 1定义 定义屏幕筛选参数 SELECTION-SCREEN BEGIN OF SCREEN 9020. SELECT-OPTIONS:s1_belnr FOR rbkp-belnr, s1_gjahr FOR rbkp-gjahr, s1_lifnr FOR rbkp-lifnr, s1_erfna FOR rbkp-erfnam, …

go入门实践二-tcp服务端

文章目录 前言接口与方法并发-协程项目管理bufio包使用其他代码 前言 上一篇&#xff0c;我们通过go语言的hello-world入门&#xff0c;搭建了go的编程环境&#xff0c;并对go语法有了简单的了解。本文实现一个go的tcp服务端。借用这个示例&#xff0c;展示接口、协程、bufio的…

php运算符的短路特性

php运算符的短路特性 1、逻辑运算符&#xff1a;逻辑与&#xff08;&&)和逻辑或&#xff08;||&#xff09;&#xff0c;存在着短路特性 PHP中有以下两个运算符具有短路的特性&#xff0c;他们是逻辑运算符的逻辑与&#xff08;&&)和逻辑或&#xff08;||&am…

线程概念linux

何为线程&#xff1a; 线程是程序中负责执行的单位&#xff0c;它可以被看作是进程的一部分&#xff0c;是进程的子任务。线程与进程的区别在于&#xff0c;进程是一个资源单位&#xff0c;而线程是进程的一部分&#xff0c;它只有栈这个独立的资源&#xff0c;其他资源如代码…

Java SpringBoot集成Activiti7工作流

Activiti7 Java SpringBoot集成Activiti7工作流介绍项目集成引入依赖YML配置文件配置类 启动项目生成表结构Activiti的数据库支持 Activiti数据表介绍项目Demo地址&#xff1a; Java SpringBoot集成Activiti7工作流 本文项目Demo地址附在文章后方 官网主页&#xff1a;http://a…

Vue npm 128

npm #降低版本 npm install npm3.8.6 -g升级到最新版本 npm install -g npmvue用npm 安装指定element-ui 版本 npm i element-ui2.0.10查看当前镜像源 npm config get registry切换镜像 npm config set registry https://registry.npmmirror.com --registryhttps://registry.n…

C++ 万能引用实现完美转发示例

万能引用 万能引用的一种常见使用场景是用在模板函数中&#xff1a; template<class T> void fun(T&& t) { //... }函数参数t就是一个万能引用&#xff0c;万能引用在这里的作用&#xff0c;简单来说就是它既能够接收左值也能接受右值 验证函数 定义一个参数…

组件化、跨平台…未来前端框架将如何演进?

前端框架在过去几年间取得了显著的进步和演进。前端框架也将继续不断地演化&#xff0c;以满足日益复杂的业务需求和用户体验要求。从全球web发展角度看&#xff0c;框架竞争已经从第一阶段的前端框架之争&#xff08;比如Vue、React、Angular等&#xff09;&#xff0c;过渡到…

powerdesigner各种字体设置;preview字体设置;sql字体设置

1.设置左侧菜单&#xff1a; 步骤如下&#xff1a; tools —> general options —> fonts —> defalut UI font ,选择字体样式及大小即可&#xff0c;同下图。 2.设置preview字体大小&#xff08;sql预览&#xff09; 步骤如下&#xff1a; tools —> general o…