Pytorch 实现目标检测二(Pytorch 24)

一 实例操作目标检测

下面通过一个具体的例子来说明锚框标签。我们已经为加载图像中的狗和猫定义了真实边界框,其中第一个 元素是类别(0代表狗,1代表猫),其余四个元素是左上角和右下角的(x, y)轴坐标(范围介于0和1之间)。我 们还构建了五个锚框,用左上角和右下角的坐标进行标记:A0, . . . , A4(索引从0开始)。然后我们在图像中 绘制这些真实边界框和锚框。

ground_truth = torch.tensor([[0, 0.1, 0.08, 0.52, 0.92],[1, 0.55, 0.2, 0.9, 0.88]])
anchors = torch.tensor([[0, 0.1, 0.2, 0.3], [0.15, 0.2, 0.4, 0.4],[0.63, 0.05, 0.88, 0.98], [0.66, 0.45, 0.8, 0.8],[0.57, 0.3, 0.92, 0.9]])
fig = d2l.plt.imshow(img)
show_bboxes(fig.axes, ground_truth[:, 1:] * bbox_scale, ['dog', 'cat'], 'k')
show_bboxes(fig.axes, anchors * bbox_scale, ['0', '1', '2', '3', '4'])

使用上面定义的multibox_target函数,我们可以根据狗和猫的真实边界框,标注这些锚框的分类和偏移量。 在这个例子中,背景、狗和猫的类索引分别为0、1和2。下面我们为锚框和真实边界框样本添加一个维度。

labels = multibox_target(anchors.unsqueeze(dim=0),ground_truth.unsqueeze(dim=0))

返回的结果中有三个元素,都是张量格式。第三个元素包含标记的输入锚框的类别。

1.1 使用非极大值抑制预测边界框

在预测时,我们先为图像生成多个锚框,再为这些锚框一一预测类别和偏移量。一个预测好的边界框则根据 其中某个带有预测偏移量的锚框而生成。下面我们实现了offset_inverse函数,该函数将锚框和偏移量预测 作为输入,并应用逆偏移变换来返回预测的边界框坐标

def offset_inverse(anchors, offset_preds):anc = d2l.box_corner_to_center(anchors)pred_bbox_xy = (offset_preds[:, :2] * anc[:, 2:] / 10) + anc[:, :2]pred_bbox_wh = torch.exp(offset_preds[:, 2:] / 5) * anc[:, 2:]pred_bbox = torch.cat((pred_bbox_xy, pred_bbox_wh), axis=1)predicted_bbox = d2l.box_center_to_corner(pred_bbox)return predicted_bbox

当有许多锚框时,可能会输出许多相似的具有明显重叠的预测边界框,都围绕着同一目标。为了简化输出,我 们可以使用非极大值抑制(non‐maximum suppression,NMS)合并属于同一目标的类似的预测边界框

以下是非极大值抑制的工作原理。对于一个预测边界框B,目标检测模型会计算每个类别的预测概率。假设最大的预测概率为p,则该概率所对应的类别B即为预测的类别。具体来说,我们将p称为预测边界框B的置信度(confidence)。在同一张图像中,所有预测的非背景边界框都按置信度降序排序,以生成列表L。然后 我们通过以下步骤操作排序列表L。

  1. 从L中 选取置信度最高的预测边界框B1作为基准,然后将所有与B1的IoU超过预定阈值ϵ的非基准预测 边界框从L中移除。这时,L保留了置信度最高的预测边界框,去除了与其太过相似的其他预测边界框。 简而言之,那些具有非极大值置信度的边界框被抑制了。
  2. 从L中选取置信度第二高的预测边界框B2作为又一个基准,然后将所有与B2的IoU大于ϵ的非基准预测 边界框从L中移除。
  3. 重复上述过程,直到L中的所有预测边界框都曾被用作基准。此时,L中任意一对预测边界框的IoU都小于阈值ϵ;因此,没有一对边界框过于相似。
  4. 输出列表L中的所有预测边界框

以下nms函数按降序对置信度进行排序并返回其索引。

#@save
def nms(boxes, scores, iou_threshold):B = torch.argsort(scores, dim=-1, descending=True)keep = []while B.numel() > 0:i = B[0]keep.append(i)if B.numel() == 1:break iou = box_iou(boxes[i, :].reshape(-1, 4), boxes[B[1:], :].reshape(-1, 4)).reshape(-1)inds = torch.nonzero(iou <= iou_threshold).reshape(-1)B = B[inds + 1]return torch.tensor(keep, device=boxes.device)

我们定义以下multibox_detection函数来 将非极大值抑制应用于预测边界框。这里的实现有点复杂,请不要 担心。我们将在实现之后,马上用一个具体的例子来展示它是如何工作的。

#@save
def multibox_detection(cls_probs, offset_preds, anchors, nms_threshold=0.5,pos_threshold=0.009999999):device, batch_size = cls_probs.device, cls_probs.shape[0]anchors = anchors.squeeze(0)num_classes, num_anchors = cls_probs.shape[1], cls_probs.shape[2]out = []for i in range(batch_size):cls_prob, offset_pred = cls_probs[i], offset_preds[i].reshape(-1, 4)conf, class_id = torch.max(cls_prob[1:], 0)predicted_bb = offset_inverse(anchors, offset_pred)keep = nms(predicted_bb, conf, nms_threshold)all_idx = torch.arange(num_anchors, dtype=torch.long, device=device)combined = torch.cat((keep, all_idx))uniques, counts = combined.unique(return_counts=True)non_keep = uniques[counts == 1]all_id_sorted = torch.cat((keep, non_keep))class_id[non_keep] = -1class_id = class_id[all_id_sorted]conf, predicted_bb = conf[all_id_sorted], predicted_bb[all_id_sorted]below_min_idx = (conf < pos_threshold)class_id[below_min_idx] = -1conf[below_min_idx] = 1 - conf[below_min_idx]pred_info = torch.cat((class_id.unsqueeze(1),conf.unsqueeze(1), predicted_bb), dim=1)out.append(pred_info)return torch.stack(out)

现在让我们将上述算法应用到一个带有四个锚框的具体示例中。为简单起见,我们假设预测的偏移量都是零, 这意味着预测的边界框即是锚框。对于背景、狗和猫其中的每个类,我们还定义了它的预测概率。

anchors = torch.tensor([[0.1, 0.08, 0.52, 0.92], [0.08, 0.2, 0.56, 0.95],[0.15, 0.3, 0.62, 0.91], [0.55, 0.2, 0.9, 0.88]])
offset_preds = torch.tensor([0] * anchors.numel())
cls_probs = torch.tensor([[0] * 4, # 背景的预测概率[0.9, 0.8, 0.7, 0.1], # 狗的预测概率[0.1, 0.2, 0.3, 0.9]]) # 猫的预测概率

我们可以在图像上绘制这些预测边界框和置信度。

fig = d2l.plt.imshow(img)
show_bboxes(fig.axes, anchors * bbox_scale,['dog=0.9', 'dog=0.8', 'dog=0.7', 'cat=0.9'])

现在我们可以调用multibox_detection函数来 执行非极大值抑制,其中阈值设置为0.5。请注意,我们在示例 的张量输入中添加了维度。

我们可以看到返回结果的形状是(批量大小,锚框的数量,6)。最内层维度中的六个元素提供了同一预测 边界框的输出信息。第一个元素是预测的类索引,从0开始(0代表狗,1代表猫),值‐1表示背景或在非极大 值抑制中被移除了。第二个元素是预测的边界框的置信度。其余四个元素分别是预测边界框左上角和右下角 的(x, y)轴坐标(范围介于0和1之间)。

output = multibox_detection(cls_probs.unsqueeze(dim=0),offset_preds.unsqueeze(dim=0),anchors.unsqueeze(dim=0),nms_threshold=0.5)
output

删除‐1类别(背景)的预测边界框后,我们可以 输出由非极大值抑制保存的最终预测边界框

fig = d2l.plt.imshow(img)
for i in output[0].detach().numpy():if i[0] == -1:continue label = ('dog=', 'cat=')[int(i[0])] + str(i[1])show_bboxes(fig.axes, [torch.tensor(i[2:]) * bbox_scale], label)

实践中,在执行非极大值抑制前,我们甚至 可以将置信度较低的预测边界框移除,从而减少此算法中的计算量。我们也可以对非极大值抑制的输出结果进行后处理。例如,只保留置信度更高的结果作为最终输出。

小结:

  • 我们 以图像的每个像素为中心生成不同形状的锚框
  • 交并比(IoU)也被称为杰卡德系数,用于衡量两个边界框的相似性。它是相交面积与相并面积的比率。
  • 在训练集中,我们需要给每个锚框两种类型的标签。一个是与锚框中目标检测的类别,另一个是锚框真实相对于边界框的偏移量
  • 预测期间可以使用非极大值抑制(NMS)来移除类似的预测边界框,从而简化输出。

 

二 多尺度目标检测

我们以输入图像的每个像素为中心,生成了多个锚框。基本而言,这些锚框代表了图像不同区域 的样本。然而,如果为每个像素都生成的锚框,我们最终可能会得到太多需要计算的锚框。想象一个 561×728的 输入图像如果以每个像素为中心生成五个形状不同的锚框,就需要在图像上标记和预测超过200万个锚框 (561 × 728 × 5)。

减少图像上的锚框数量并不困难。比如,我们可以在输入图像中均匀采样一小部分像素,并以它们为中心生 成锚框。此外,在不同尺度下,我们可以生成不同数量和不同大小的锚框。直观地说,比起较大的目标,较小的目标在图像上出现的可能性更多样。例如,1 × 1、1 × 2和2 × 2的目标可以分别以4、2和1种可能的方式 出现在2 × 2图像上。因此,当使用较小的锚框检测较小的物体时,我们可以采样更多的区域,而对于较大的 物体,我们可以采样较少的区域。

为了演示如何在多个尺度下生成锚框,让我们先读取一张图像。

%matplotlib inline
import torch
from d2l import torch as d2limg = d2l.plt.imread('../img/catdog.jpg')
img.shape  # (360, 640, 3)

display_anchors函数定义如下。我们 在特征图(fmap)上生成锚框(anchors),每个单位(像素)作为锚框的中心。由于锚框中的(x, y)轴坐标值(anchors)已经被除以特征图(fmap)的宽度和高度,因此这些值介 于0和1之间,表示特征图中锚框的相对位置。

由于锚框(anchors)的中心分布于特征图(fmap)上的所有单位,因此这些中心必须根据其相对空间位置在任何输入图像上均匀分布。更具体地说,给定特征图的宽度和高度fmap_w和fmap_h,以下函数将均匀地对任 何输入图像中fmap_h行和fmap_w列中的像素进行采样。以这些均匀采样的像素为中心,将会生成大小为s(假 设列表s的长度为1)且宽高比(ratios)不同的锚框

def display_anchors(fmap_w, fmap_h, s):d2l.set_figsize()fmap = torch.zeros((1, 10, fmap_h, fmap_w))anchors = d2l.multibox_prior(fmap, sizes=s, ratios=[1, 2, 0.5])bbox_scale = torch.tensor((w, h, w, h))d2l.show_bboxes(d2l.plt.imshow(img).axes, anchors[0] * bbox_scale)

首先,让我们考虑探测小目标。为了在显示时更容易分辨,在这里具有不同中心的锚框不会重叠:锚框的尺 度设置为0.15,特征图的高度和宽度设置为4。我们可以看到,图像上4行和4列的锚框的中心是均匀分布的。

display_anchors(fmap_w=4, fmap_h=4, s=[0.15])

然后,我们将特征图的高度和宽度减小一半,然后使用较大的锚框来检测较大的目标。当尺度设置为0.4时, 一些锚框将彼此重叠。

display_anchors(fmap_w=2, fmap_h=2, s=[0.4])

最后,我们进一步将特征图的高度和宽度减小一半,然后将锚框的尺度增加到0.8。此时,锚框的中心即是图 像的中心。
 

display_anchors(fmap_w=1, fmap_h=1, s=[0.8])

小结:

  • 在多个尺度下,我们 可以生成不同尺寸的锚框来检测不同尺寸的目标
  • 通过定义特征图的形状,我们 可以决定任何图像上均匀采样的锚框的中心
  • 我们 使用输入图像在某个感受野区域内的信息,来预测输入图像上与该区域位置相近的锚框类别和偏 移量。
  • 我们可以通过深入学习,在 多个层次上的图像分层表示进行多尺度目标检测

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

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

相关文章

【网络安全】【深度学习】【入侵检测】SDN模拟网络入侵攻击并检测,实时检测,深度学习

文章目录 1. 前言2. Mininet 和 Ryu 的区别2.1 Mininet2.2 Ryu2.3 总结 3. 模拟攻击3.1 环境准备3.2 创建 Mininet 网络拓扑3.2 启动 Ryu 控制器3.3 模拟网络攻击3.4 捕获流量 4. 实时异常检测4.1 在 Ryu 控制器中4.2 在 h2 机器上的实验结果4.3 深度学习模型部署上h2机器 帮助…

电感十大供应商

电感品牌-电感器品牌排行榜-电感十大品牌-Maigoo品牌榜

Fences 5 激活码 - 电脑桌面整理软件

提起桌面整理&#xff0c;经典老牌工具 Fences 必有一席之地&#xff0c;Stardock 发布了最新的 Fences 5 版本。 可以将文件和图标归类放入各个栅栏分区&#xff0c;并支持文件夹展开至桌面、分区置顶、淡化隐藏图标等功能&#xff0c;能让你的桌面焕然一新&#xff0c;不再混…

(2024,扩散,DMP,提示混合,动态门控,阶段特异性,微调)通过混合提示进行扩散模型修补

Diffusion Model Patching via Mixture-of-Prompts 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0 摘要 1 简介 2 相关工作 3 扩散模型修补&#xff08;DMP&#xff09; 3.1 架构…

用大模型理解爆火的KAN网络

上个月五一假期的时候&#xff0c;KAN突然成为了热门话题。虽然最初我并没有计划弄懂它&#xff0c;但在老板的要求下&#xff0c;我还是探索了一下。 一、KAN是什么&#xff1f; Kolmogorov-Arnold 定理是数学领域的一个里程碑&#xff0c;它揭示了多元函数能够通过一组更简…

SpringBoot 参数验证的几种方式

文章目录 SpringBoot 参数验证1、为什么要进行参数验证2、验证方式2.1 if 语句判断2.2 Assert2.3 Validator2.3.1 引入依赖2.3.2 定义参数实体类2.3.4 定义特定异常全局拦截方法2.3.5 定义校验类进行测试2.3.6 测试 2.4 自定义验证注解2.4.1 定义自定义注解2.4.2 定义自定义验证…

Python第二语言(八、Python包)

目录 1. 什么是Python包 2. 创包步骤 2.1 new包 2.2 查看创建的包 2.3 拖动文件到包下 3. 导入包 4. 安装第三方包 4.1 什么是第三方包 4.2 安装第三方包-pip 4.3 pip网络优化 1. 什么是Python包 包下有__init__.py就是包&#xff0c;无__init__.py就是文件夹。于Ja…

嵌入式学习——Linux高级编程复习(进程)——day39

1. 进程 进程是计算机科学中的一个核心概念&#xff0c;它是操作系统进行资源分配和调度的基本单位&#xff0c;代表了一个正在执行中的程序实例。当一个程序被加载到内存并开始执行时&#xff0c;它就变成了一个进程。 1. 程序&#xff1a;存放在外存中的一段代码的集合 2. 进…

牛客 NC129 阶乘末尾0的数量【简单 基础数学 Java/Go/PHP/C++】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/aa03dff18376454c9d2e359163bf44b8 https://www.lintcode.com/problem/2 思路 Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff…

Python 很好用的爬虫框架:Scrapy:

了解Scrapy 爬虫框架的工作流程&#xff1a; 在scrapy中&#xff0c; 具体工作流程是这样的&#xff1a; 首先第一步 当爬虫引擎<engine>启动后&#xff0c; 引擎会到 spider 中获取 start_url<起始url> 然后将其封装为一个request对象&#xff0c; 交给调度器<…

Elastic Search 8.14:更快且更具成本效益的向量搜索,使用 retrievers 和重新排序提升相关性,RAG 和开发工具

作者&#xff1a;来自 Elastic Yaru Lin, Ranjana Devaji 我们致力于突破搜索开发的界限&#xff0c;并专注于为搜索构建者提供强大的工具。通过我们的最新更新&#xff0c;Elastic 对于处理以向量表示的大量数据的客户来说变得更加强大。这些增强功能保证了更快的速度、降低的…

Activity->Activity中动态添加Fragment->add和replace方式添加的区别

XML文件 Activity布局文件R.layout.activity_main <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/root_ll"android:orientation"v…

Linux本地搭建DataEase并发布公网远程访问进行数据分析

文章目录 前言1. 安装DataEase2. 本地访问测试3. 安装 cpolar内网穿透软件4. 配置DataEase公网访问地址5. 公网远程访问Data Ease6. 固定Data Ease公网地址 前言 DataEase 是开源的数据可视化分析工具&#xff0c;帮助用户快速分析数据并洞察业务趋势&#xff0c;从而实现业务…

【RAG入门教程01】Langchian框架 v0.2介绍

LangChain 是一个开源框架&#xff0c;旨在简化使用大型语言模型 (LLM) 创建应用程序的过程。可以将其想象成一套使用高级语言工具进行搭建的乐高积木。 它对于想要构建复杂的基于语言的应用程序而又不必管理直接与语言模型交互的复杂性的开发人员特别有用。它简化了将这些模型…

数据库之PostgreSQL详解

一、PostgreSQL介绍 PostgreSQL是一个功能强大的 开源 的关系型数据库。底层基于C实现。 PostgreSQL的开源协议和Linux内核版本的开源协议是一样的。。BDS协议&#xff0c;这个协议基本和MIT开源协议一样&#xff0c;说人话&#xff0c;就是你可以对PostgreSQL进行一些封装&a…

如何在本地和远程删除 Git 分支

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;目前是武汉城市开发者社区主理人 擅长.net、C、python开发&#xff0c; 如果遇…

SpringBoot之Mybatis-plus实战

文章目录 MybatisPlus 介绍一、MyBatisPlus 集成步骤第一步、引入依赖第二步、定义mapper 二、注解TableNameTableldTableField 加解密实现步骤 在SpringBoot项目中使用Mybatis-plus&#xff0c;记录下来&#xff0c;方便备查。 MybatisPlus 介绍 为简化开发而生&#xff0c;官…

CSAPP Lab01——Data Lab完成思路

陪你把想念的酸拥抱成温暖 陪你把彷徨写出情节来 未来多漫长再漫长还有期待 陪伴你 一直到 故事给说完 ——陪你度过漫长岁月 完整代码见&#xff1a;CSAPP/datalab-handout at main SnowLegend-star/CSAPP (github.com) 01 bitXor 这道题是用~和&计算x^y。 异或是两个…

红黑树的介绍与实现

前言 前面我们介绍了AVL树&#xff0c;AVL树是一棵非常自律的树&#xff0c;有着严格的高度可控制&#xff01;但是正它的自律给他带来了另一个问题&#xff0c;即虽然他的查找效率很高&#xff0c;但是插入和删除由于旋转而导致效率没有那么高。我们上一期的结尾说过经常修改…

C语言:双链表

一、什么是双链表&#xff1f; 双链表&#xff0c;顾名思义&#xff0c;是一种每个节点都包含两个链接的链表&#xff1a;一个指向下一个节点&#xff0c;另一个指向前一个节点。这种结构使得双链表在遍历、插入和删除操作上都表现出色。与单链表相比&#xff0c;双链表不仅可以…