FCOS难点记录

在这里插入图片描述
FCOS 中有计算 特征图(Feature map中的每个特征点到gt_box的左、上、右、下的距离)

1、特征点到gt_box框的 左、上、右、下距离计算

		x = coords[:, 0] # h*w,2   即 第一列
        y = coords[:, 1] 
        l_off = x[None, :, None] - gt_boxes[..., 0][:, None, :]  # [1,h*w,1]-[batch_size,1,m]-->[batch_size,h*w,m]
        t_off = y[None, :, None] - gt_boxes[..., 1][:, None, :]
        r_off = gt_boxes[..., 2][:, None, :] - x[None, :, None]
        b_off = gt_boxes[..., 3][:, None, :] - y[None, :, None]
        ltrb_off = torch.stack([l_off, t_off, r_off, b_off], dim=-1)  # [batch_size,h*w,m,4]
        areas = (ltrb_off[..., 0] + ltrb_off[..., 2]) * (ltrb_off[..., 1] + ltrb_off[..., 3])  # [batch_size,h*w,m]
        off_min = torch.min(ltrb_off, dim=-1)[0]  # [batch_size,h*w,m]
        off_max = torch.max(ltrb_off, dim=-1)[0]  # [batch_size,h*w,m]

根据上边的画的图可以看出,假设对应的 feature map 大小为 2x2,stride=4,原始图片为8x8。将特征图中的每个特征点映射回去,可以得到相应的 4个(h*w个)坐标。对应图中的 红色a,绿色b,黄色c和蓝色d的点。

print(x,"\n",y,x.shape)
'''
tensor([2., 6., 2., 6.]) 
tensor([2., 2., 6., 6.]) torch.Size([4])
'''

print(x[None,:,None]) # [1,4,1]
'''
tensor([[[2.],
         [6.],
         [2.],
         [6.]]]) 
'''
 
print(gt_boxes) # [1,2,4]  batch=1, 两个框,每个框左上角和右下角坐标
'''
tensor([[[5, 4, 7, 6],
         [1, 1, 4, 6]]])
'''

print(gt_boxes[...,0],gt_boxes[...,0][:,None,:])
''' 
tensor([[5, 1]]) tensor([[[5, 1]]])
'''
l_off = [2,2]-[5,1]=[-3,1]  以此类推


print(l_off,"\n", l_off.shape)

'''
**第一列代表,所有的点abcd横坐标与第一个框的左边偏移量。第二列代表到第二个框的偏移量**
tensor([[[-3.,  1.],
         [ 1.,  5.],
         [-3.,  1.],
         [ 1.,  5.]]]) 
 torch.Size([1, 4, 2])
 '''

print(ltrb_off)
'''
第一列代表,所有的投影点abcd,到两个框的左边偏移量。第一行第二行分别代表两个框。
tensor([[[[-3., -2.,  5.,  4.], # a 点到第一个框的左边、上边、右边、下边的偏移
          [ 1.,  1.,  2.,  4.]], # a 点到第二框的左边、上边、右边、下边的偏移

         [[ 1., -2.,  1.,  4.], # b 点到第一个框的左边、上边、右边、下边的偏移
          [ 5.,  1., -2.,  4.]],

         [[-3.,  2.,  5.,  0.],
          [ 1.,  5.,  2.,  0.]],

         [[ 1.,  2.,  1.,  0.],
          [ 5.,  5., -2.,  0.]]]]) torch.Size([1, 4, 2, 4]) #[batch_size,h*w,m,4]
'''

print(ltrb_off[...,0])
'''

tensor([[[-3.,  1.],
         [ 1.,  5.],
         [-3.,  1.],
         [ 1.,  5.]]]) torch.Size([1, 4, 2])
'''

print(areas)
'''
areas: tensor([[[ 4., 15.],
         [ 4., 15.],
         [ 4., 15.],
         [ 4., 15.]]])
'''

torch.return_types.min(
values=tensor([[[-3.,  1.],
         [-2., -2.],
         [-3.,  0.],
         [ 0., -2.]]]),
indices=tensor([[[0, 0],
         [1, 2],
         [0, 3],
         [3, 2]]])) 
 torch.return_types.max(
values=tensor([[[5., 4.],
         [4., 5.],
         [5., 5.],
         [2., 5.]]]),
indices=tensor([[[2, 3],
         [3, 0],
         [2, 1],
         [1, 0]]]))



2、确定该特征点在哪一个框内,是否在该FPN特征层进行尺寸判断并进行后续预测

off_min = torch.min(ltrb_off, dim=-1)[0]  # [batch_size,h*w,m] # off_min 找出所有 特征点  到 每个框的 四条边 最小的距离
off_max = torch.max(ltrb_off, dim=-1)[0]  # [batch_size,h*w,m]  #off_max 找出所有 特征点  到 每个框的 四条边 最大的距离

mask_in_gtboxes = off_min > 0
mask_in_level = (off_max > limit_range[0]) & (off_max <= limit_range[1]) # 锁定在这个limit range上的所有的特征的点	
print("ltrf_off",ltrb_off)
print("off_min",off_min,"\n","off_max",off_max)
print("mask_in_gtboxes-->",mask_in_gtboxes)
print("mask_in_level-->",mask_in_level)

'''
ltrf_off tensor([[[[-3., -2.,  5.,  4.], # a 点到第一个框的左边、上边、右边、下边的偏移
          [ 1.,  1.,  2.,  4.]],  # a 点到第二个框的左边、上边、右边、下边的偏移

         [[ 1., -2.,  1.,  4.], # b 点到第一个框的左边、上边、右边、下边的偏移
          [ 5.,  1., -2.,  4.]],

         [[-3.,  2.,  5.,  0.],
          [ 1.,  5.,  2.,  0.]],

         [[ 1.,  2.,  1.,  0.],
          [ 5.,  5., -2.,  0.]]]])
          
off_min 
tensor([[[-3.,  1.], # a点到第一个框最小距离-3,  a点到第二个框的最小偏移距离 1
         [-2., -2.], #b点到第一个框最小距离-2,  b点到第二个框的最小偏移距离 -2
         [-3.,  0.], # c点到第一个框最小距离-3,  a点到第二个框的最小偏移距离 0
         [ 0., -2.]]]) # d点到第一个框最小距离0,  a点到第二个框的最小偏移距离 -2
         
 off_max 
 tensor([[[5., 4.],
         [4., 5.],
         [5., 5.],
         [2., 5.]]])
         
mask_in_gtboxes-->  # 判断了 特征点是否在框内
tensor([[[False,  True],  # a点到第一个框四边最小偏移距离小于0,所以,a点不属于第一个框,为false;以此类推。
         [False, False],
         [False, False],
         [False, False]]]) # [batch,h*w,m]
         
mask_in_level-->  # 锁定在这个limit range上的所有的特征的点	
tensor([[[True, True],  # 锁定了a 在这个level中
         [True, True],  # 锁定了b
         [True, True],  # 锁定了c
         [True, True]]])# 锁定了d  都在这个FPN级别上  [batch,h*w,m]
'''

3、特征点是否在框中心的范围内,用来判断是否为正样本

	radiu = stride * sample_radiu_ratio # 4*1.15 = 4.6
    gt_center_x = (gt_boxes[..., 0] + gt_boxes[..., 2]) / 2
    gt_center_y = (gt_boxes[..., 1] + gt_boxes[..., 3]) / 2
    c_l_off = x[None, :, None] - gt_center_x[:, None, :]  # [1,h*w,1]-[batch_size,1,m]-->[batch_size,h*w,m]
    c_t_off = y[None, :, None] - gt_center_y[:, None, :]
    c_r_off = gt_center_x[:, None, :] - x[None, :, None]
    c_b_off = gt_center_y[:, None, :] - y[None, :, None]
    c_ltrb_off = torch.stack([c_l_off, c_t_off, c_r_off, c_b_off], dim=-1)  # [batch_size,h*w,m,4]
    c_off_max = torch.max(c_ltrb_off, dim=-1)[0]
    mask_center = c_off_max < radiu
print("c_ltrb_off",c_ltrb_off)
print("c_off_max",c_off_max)
print("mask_center",mask_center)

'''
c_ltrb_off 
tensor([[[[-4.0000, -3.0000,  4.0000,  3.0000],  # 同上边一样,a到 第一个框 小的中心框四边 的距离
          [-0.5000, -1.5000,  0.5000,  1.5000]], # a到 第二个框 小的中心框四边 的距离

         [[ 0.0000, -3.0000,  0.0000,  3.0000], # b到 第一个框 小的中心框四边 的距离
          [ 3.5000, -1.5000, -3.5000,  1.5000]], # # b到 第二个框 小的中心框四边 的距离

         [[-4.0000,  1.0000,  4.0000, -1.0000],
          [-0.5000,  2.5000,  0.5000, -2.5000]],

         [[ 0.0000,  1.0000,  0.0000, -1.0000],
          [ 3.5000,  2.5000, -3.5000, -2.5000]]]])
          
c_off_max tensor([[[4.0000, 1.5000], # 找到a特征点到第一个框中心框和第二个框的中心框的 最大距离
         [3.0000, 3.5000],
         [4.0000, 2.5000],
         [1.0000, 3.5000]]]) # [batch,h*w,m] 4个特征点(a,b,c,d) x 框的个数2个(第一个框,第二个框)
         
mask_center tensor([[[True, True], # 判断是否在这个框里中心点里边 正样本
         [True, True],
         [True, True],
         [True, True]]]) ## [batch,h*w,m]
'''

3、制定mask,根据上边的 gt_box、fpn_level、mask_center

‘’’
mask_pos 是三个约束条件的交集,分别是特征点在gt中,特征点在level中,以及特征点距离Gt中的center小于指定的范围
‘’’

mask_pos = mask_in_gtboxes & mask_in_level & mask_center  # [batch_size,h*w,m]

areas[~mask_pos] = 99999999
areas_min_ind = torch.min(areas, dim=-1)[1]  # [batch_size,h*w]
mask_pos = mask_in_gtboxes & mask_in_level & mask_center  # [batch_size,h*w,m]
print("pre_areas:",areas)
areas[~mask_pos] = 99999999
areas_min_ind = torch.min(areas, dim=-1)[1]  # [batch_size,h*w] # 返回索引,注意和上边的区别,上边返回值,比大小
# torch.max()  or  torch.min() dim=0 找列,dim=1  找行
print("mask_pos-->",mask_pos)
print("post_ares",areas)
print("areas_min_ind",areas_min_ind)

'''
mask_in_gtboxes--> 
tensor([[[False,  True],
         [False, False],
         [False, False],
         [False, False]]])
mask_in_level--> 
tensor([[[True, True],
         [True, True],
         [True, True],
         [True, True]]])
mask_center 
tensor([[[True, True],
         [True, True],
         [True, True],
         [True, True]]])

mask_pos--> 
tensor([[[False,  True],  # 只有a点在第二个框在这个fpn这个level, 同时满足这三个条件
         [False, False],
         [False, False],
         [False, False]]])
         
post_ares 
tensor([[[1.0000e+08, 1.5000e+01],
         [1.0000e+08, 1.0000e+08],
         [1.0000e+08, 1.0000e+08],
         [1.0000e+08, 1.0000e+08]]]) # #[batch_size,h*w,m] 将 满足要求的 保持面积不面,其他设置为很大的值
         
areas_min_ind tensor([[1, 0, 0, 0]]) # [batch_size,h*w] min[1]返回的是对应的indices  找到最小的面积,返回索引。

'''



4、

![在这里插入图片描述](https://img-blog.csdnimg.cn/3e504ea230ff47c097ba9eb6caddca55.png在这里插入图片描述

reg_targets = ltrb_off[torch.zeros_like(areas, dtype=torch.bool)
.scatter_(-1, areas_min_ind.unsqueeze(dim=-1), 1)]  # [batch_size*h*w,4]
reg_targets = torch.reshape(reg_targets, (batch_size, -1, 4))  # [batch_size,h*w,4]
scatter_的用法:参考 https://blog.csdn.net/weixin_43496455/article/details/103870889
scatter(dim, index, src)将src中数据根据index中的索引按照dim的方向进行填充。

dim=0
'''
areas: 
tensor([[[ 4., 15.],
         [ 4., 15.],
         [ 4., 15.],
         [ 4., 15.]]]) [1,4,2]
扩展维度之后  [1,4] --> torch.Size([1, 4, 1]) ===> [[[1,0,0,0]]]
torch.zeros_like(areas, dtype=torch.bool) 
tensor([[[False, False],
         [False, False],
         [False, False],
         [False, False]]])
         
after scatter_--> 
tensor([[[False,  True],
         [ True, False],
         [ True, False],
         [ True, False]]]) # [1,4,2]
         
ltrf_off 
tensor([[[[-3., -2.,  5.,  4.], # a 点到第一个框的左边、上边、右边、下边的偏移
          [ 1.,  1.,  2.,  4.]],  # a 点到第二个框的左边、上边、右边、下边的偏移

         [[ 1., -2.,  1.,  4.], # b 点到第一个框的左边、上边、右边、下边的偏移
          [ 5.,  1., -2.,  4.]],

         [[-3.,  2.,  5.,  0.],
          [ 1.,  5.,  2.,  0.]],

         [[ 1.,  2.,  1.,  0.],
          [ 5.,  5., -2.,  0.]]]])
          
reg_targets1 
tensor([[ 1.,  1.,  2.,  4.], # a 点 第二个框
        [ 1., -2.,  1.,  4.], # b 点 第一个框
        [-3.,  2.,  5.,  0.], # c 点 第一个框
        [ 1.,  2.,  1.,  0.]])# d 点 第一个框
        # torch.Size([4, 4])
        
reg_targets2 tensor([[[ 1.,  1.,  2.,  4.],
         [ 1., -2.,  1.,  4.],
         [-3.,  2.,  5.,  0.],
         [ 1.,  2.,  1.,  0.]]]) # torch.Size([1, 4, 4])
'''

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《研发效能(DevOps)工程师》课程简介(五)丨IDCF

由国家工业和信息化部教育与考试中心颁发的职业技术证书&#xff0c;也是国内首个研发效能&#xff08;DevOps&#xff09;职业技术认证&#xff0c;内涵1000页学习教材2000分钟的课程内容讲解460多个技术知识点300多道练习题。 在这里&#xff0c;你不仅可以了解到华为、微软、…

6.2.1 邻接矩阵

邻接矩阵 表示方法&#xff1a;优点&#xff1a;缺点&#xff1a;适用情况&#xff1a;案例代码 邻接矩阵是一种常见的图的存储结构&#xff0c;用于表示图中顶点之间的连接关系。它是一个二维数组&#xff0c;其中行和列分别表示图中的顶点&#xff0c;而数组中的值表示连接顶…

Geotrust的企业型通配符SSL证书申请

Geotrust作为世界知名的CA认证机构之一&#xff0c;颁发了各种SSL证书&#xff0c;其签发的数字证书被广泛应用于电子商务、企业间通信、网络安全等领域&#xff0c;SSL数字证书可以验证网络中用户的身份&#xff0c;确保数据的机密性和完整性。今天随SSL盾小编了解如何申请Geo…

FPGA UDP RGMII 千兆以太网(1)

1 RGMII 接口 PHY 的 MII 接口有很多种, 例如 MII、 GMII、 RGMII、 SGMII、 XGMII、 TBI、 RTBI 等。其中 RGMII的主要优势在于,它可同时适用于 1000M、 100M、 10M 三种速率,而且接口占用引脚数较少。但也存在缺点,其一, PCB 布线时需要尽可能对数据、控制和时钟线迚行…

GitHub Copilot Chat将于12月全面推出;DeepLearning.AI免费新课

&#x1f989; AI新闻 &#x1f680; GitHub Copilot Chat将于12月全面推出&#xff0c;提升开发者的生产力 摘要&#xff1a;GitHub宣布将于12月全面推出GitHub Copilot Chat&#xff0c;这是GitHub Copilot的一个新功能&#xff0c;旨在帮助开发者编写代码。它能够集成到开…

不定积分第一类换元法(凑微分法)

将其中的 分解为 相当于 令 那么. 就可以得到 例题1 令 那么 因为 所以 利用基本积分公式 结果 例题2 上下同除 接下来需要一些技巧 这个形式需要联想到一个基本积分公式 不巧是这里是2不是1需要利用技巧把2变成1

在Rust中使用多线程并发运行代码

1.Rust线程实现理念 在大部分现代操作系统中&#xff0c;已执行程序的代码在一个 进程&#xff08;process&#xff09;中运行&#xff0c;操作系统则会负责管理多个进程。在程序内部&#xff0c;也可以拥有多个同时运行的独立部分。这些运行这些独立部分的功能被称为 线程&am…

竞赛选题 深度学习猫狗分类 - python opencv cnn

文章目录 0 前言1 课题背景2 使用CNN进行猫狗分类3 数据集处理4 神经网络的编写5 Tensorflow计算图的构建6 模型的训练和测试7 预测效果8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习猫狗分类 ** 该项目较为新颖&a…

GUI:贪吃蛇

以上是准备工作 Data import javax.swing.*; import java.net.URL;public class Data {public static URL headerURLData.class.getResource("static/header.png");public static ImageIcon header new ImageIcon(headerURL);public static URL upURLData.class.getR…

【vector题解】连续子数组的最大和 | 数组中出现次数超过一次的数字

连续子数组的最大和 连续子数组的最大和_牛客题霸_牛客网 描述 输入一个长度为n的整型数组array&#xff0c;数组中的一个或连续多个整数组成一个子数组&#xff0c;子数组最小长度为1。求所有子数组的和的最大值。 要求:时间复杂度为 O(n)&#xff0c;空间复杂度为 O(n) 进…

Python爬虫框架Scrapy:实现高效数据抓取

目录 一、引言 二、Scrapy框架概述 1、Scrapy框架特点 2、Scrapy框架结构 三、Scrapy框架的使用 1、安装Scrapy框架 2、创建Scrapy项目 3、创建爬虫 4、运行爬虫 四、Scrapy框架常见问题及解决方案 1、请求被网站封禁 2、处理动态加载的页面 3、避免被网站检测到爬…

C#查看启用或关闭的Windows功能

通过命令查看启用或关闭的Windows功能&#xff0c;以管理员身份打开powershell&#xff0c;输入命令get-windowsoptionalfeature -online 得出结果如下&#xff1a; 如果使用C#查看&#xff0c;需要先安装System.Management 代码如下&#xff1a; private void isInstall() …

pinpoint监控tomcat应用,页面显示No data collected

pinpoint安装部署教程大家都可以搜到。这里就不说了。单说一下 页面没有数据的情况。 部署环境&#xff0c;pinpoint安装部署在A服务器上。现在是在C、D、E、F……linux机器上安装pinpoint-agnet 1. 将文件 pinpoint-agent-1.8.5.tar.gz 上传到 服务器C、D、E、F…… 2. 解压…

MQTT协议消息代理服务公网远程连接

文章目录 前言1. Linux 搭建 Mosquitto2. Linux 安装Cpolar3. 创建MQTT服务公网连接地址4. 客户端远程连接MQTT服务5. 代码调用MQTT服务6. 固定连接TCP公网地址7. 固定地址连接测试 前言 Mosquitto是一个开源的消息代理&#xff0c;它实现了MQTT协议版本3.1和3.1.1。它可以在不…

Spring Cloud 微服务入门篇

文章目录 什么是微服务架构 Microservice微服务的发展历史微服务的定义微小的服务微服务 微服务的发展历史1. 微服务架构的发展历史2. 微服务架构的先驱 微服务架构 Microservice 的优缺点1. 微服务 e Microservice 优点2. 微服务 Microservice 缺点微服务不是银弹&#xff1a;…

C语言---插入排序、希尔排序、冒泡排序、选择排序、快速排序简单介绍

文章目录 插入排序希尔排序冒泡排序选择排序快速排序 本文主要介绍用C语言实现的一些排序方法&#xff0c;有插入排序、希尔排序、冒泡排序、选择排序和快速排序&#xff0c;文章中给出的例子都是按照升序排列的。 插入排序 若数组只有一个元素&#xff0c;自然不用排序&#…

和数链“分布式存储”技术结合隐私计算让数据更安全

存储是IT业的核心技术&#xff0c;全球存储行业历经半个世纪的洗礼&#xff0c;在技术和需求相互促进的演变下沧桑变幻&#xff0c;经历桌面级存储、企业级存储、云存储多次迭代变迁。 目前的存储方式主要是“大数据中心”等集中式存储&#xff0c;随着数据规模和复杂度的迅速…

如何用Java实现一个基于机器学习的情感分析系统,用于分析文本中的情感倾向

背景&#xff1a;练习两年半&#xff08;其实是两周半&#xff09;&#xff0c;利用工作闲余时间入门一下机器学习&#xff0c;本文没有完整的可实施的案例&#xff0c;由于知识体系不全面&#xff0c;目前代码只能运行&#xff0c;不能准确的预测 卡点&#xff1a; 1 由于过…

Java自学第6课:电商项目(2)

1 创建工具类并连接数据库 在工程src右键单击new&#xff0c;新建util包 再创建DBUtil类 数据库交互需要有数据库支持的包&#xff0c;这是官方给出的类库。 先声明1个代码块 // 静态代码块 只加载1次static{try {Class.forName("com.mysql.jdbc.Driver");} catch (…

Kotlin文件和类为什么不是一对一关系

在Java中&#xff0c;一个类文件的public类名必须和文件名一致&#xff0c;如何不一致就会报异常&#xff0c;但是在kotlin的文件可以和类名一致&#xff0c;也可以不一致。这种特性&#xff0c;就跟c有点像&#xff0c;毕竟c的.h 和 .cpp文件是分开的。只要最终编译的时候对的…