Anchor Boxes示例实战

目标检测算法通常对输入图像中的大量区域进行采样,判断这些区域是否包含感兴趣的目标,并调整这些区域的边缘,以便更准确地预测目标的真实边界框。不同的模型可能使用不同的区域采样方法。在这里,我们介绍一种这样的方法:它生成多个大小和纵横比不同的边框,同时以每个像素为中心。这些边界框称为锚框。我们将练习基于锚盒的对象检测。

首先,导入此部分所需的包或模块。在这里,我们修改了NumPy的打印精度。因为打印张量实际上调用了NumPy的print函数,所以本节打印的张量中的浮点数更简洁。

%matplotlib inline

from d2l import mxnet as d2l

from mxnet import gluon, image, np, npx

np.set_printoptions(2)

npx.set_np()

1. Generating Multiple Anchor Boxes

img = image.imread('../img/catdog.jpg').asnumpy()

h, w = img.shape[0:2]

print(h, w)

X = np.random.uniform(size=(1, 3, h, w))  # Construct input data

Y = npx.multibox_prior(X, sizes=[0.75, 0.5, 0.25], ratios=[1, 2, 0.5])

Y.shape

561 728

(1, 2042040, 4)

我们可以看到返回的锚框变量y的形状是(批大小,锚框数量,4)(batch size, number of anchor boxes, 4)。将锚框变量y的形状更改为(图像高度、图像宽度、以同一像素为中心的锚框数量,4)(image height, image width, number of anchor boxes centered on the same pixel, 4)后,我们可以获得所有以指定像素位置为中心的锚定框。在下面的示例中,我们访问位于(250,250)中心的第一个锚定框。它有四个元素:位于锚定框左上角的x、y轴坐标和右下角的x、y轴坐标。x轴和y轴的坐标值分别除以图像的宽度和高度,因此值范围在0和1之间。

boxes = Y.reshape(h, w, 5, 4)

boxes[250, 250, 0, :]

array([0.06, 0.07, 0.63, 0.82])

为了描述图像中所有以一个像素为中心的锚框,我们首先定义show_bboxes函数来绘制图像上的多个边界框。

#@save

def show_bboxes(axes, bboxes, labels=None, colors=None):

"""Show bounding boxes."""

def _make_list(obj, default_values=None):

if obj is None:

obj = default_values

elif not isinstance(obj, (list, tuple)):

obj = [obj]

return obj

labels = _make_list(labels)

colors = _make_list(colors, ['b', 'g', 'r', 'm', 'c'])

for i, bbox in enumerate(bboxes):

color = colors[i % len(colors)]

rect = d2l.bbox_to_rect(bbox.asnumpy(), color)

axes.add_patch(rect)

if labels and len(labels) > i:

text_color = 'k' if color == 'w' else 'w'

axes.text(rect.xy[0], rect.xy[1], labels[i],

va='center', ha='center', fontsize=9, color=text_color,

bbox=dict(facecolor=color, lw=0))

正如我们刚才看到的,变量框中x轴和y轴的坐标值分别除以图像的宽度和高度。在绘制图像时,我们需要恢复锚定框的原始坐标值,从而定义变量bbox_scale。现在,我们可以在图像中以(250,250)为中心绘制所有的锚框。你也可以看到一个0.75大小的锚框的图像。

d2l.set_figsize((3.5, 2.5))

bbox_scale = np.array((w, h, w, h))

fig = d2l.plt.imshow(img)

show_bboxes(fig.axes, boxes[250, 250, :, :] * bbox_scale,

['s=0.75, r=1', 's=0.5, r=1', 's=0.25, r=1', 's=0.75, r=2',

's=0.75, r=0.5'])

2. Intersection over Union

我们刚刚提到了锚盒很好地覆盖了图像中的狗。如果已知目标的真实边界框,这里的“井”如何量化?相似性是一种直观地度量盒与地之间的相似性的方法。我们知道Jaccard索引可以度量两个集合之间的相似性。给定集合A和B,其Jaccard索引是其交集的大小除以其并集的大小:

J(A, B)= |A∩B|/ |A∪B|

实际上,我们可以将边界框的像素区域视为像素集合。这样,我们就可以通过像素集的Jaccard索引来度量两个边界框的相似度。当我们测量两个边界框的相似性时,我们通常将Jaccard索引称为intersection over union(IoU),即两个边界框的相交面积与并集面积的比值,如图1所示。IoU的值范围在0到1之间:0表示两个边界框之间没有重叠的像素,而1表示两个边界框相等。

Fig. 1.  IoU is the ratio of the intersecting area to the union area of two bounding boxes.

我们将使用IoU来测量锚定框和真实边界框之间以及不同锚定框之间的相似性。

3. Labeling Training Set Anchor Boxes

在训练集中,我们将每个锚盒视为一个训练示例。为了训练目标检测模型,我们需要为每个锚框标记两种类型的标签:第一种是锚框中包含的目标的类别(类别),第二种是真实边界框相对于锚定框的偏移量(offset)。在目标检测中,首先生成多个锚框,预测每个锚框的类别和偏移量,根据预测的偏移量调整锚定框的位置,得到用于预测的边界框,最后过滤出需要输出的预测边界框。

我们知道,在目标检测训练集中,每幅图像都标有真实边界框的位置和所包含目标的类别。锚盒生成后,我们主要根据与锚盒相似的真实边界框的位置和类别信息对锚盒进行标记。那么,我们如何将真实边界框指定给与它们类似的锚框呢?

Fig. 2  Assign ground-truth bounding boxes to anchor boxes

现在我们可以标记锚定框的类别和偏移量。如果锚箱A被指定为真实边界框B,锚箱类别A 设置为B类。以及锚箱A的偏移量,根据B的中心坐标的相对位置设置。还有一个以及两个盒子的相对大小。由于数据集中不同方框的位置和大小可能不同,这些相对位置和相对大小通常需要一些特殊的转换,以使偏移分布更加均匀,更易于拟合。

下面我们展示一个详细的例子。我们为读取图像中的cat和dog定义了基本真实边界框,其中第一个元素是category(0表示dog,1表示cat),其余四个元素是左上角x,y轴坐标和右下角x、y的轴坐标(值范围在0和1之间)。在这里,我们构造了五个锚框,用左上角和右下角的坐标来标记,它们被记录为A0,…,A4。分别为(程序中的索引从0开始)。首先,画出这些锚框和真实边界框在图像中的位置。

ground_truth = np.array([[0, 0.1, 0.08, 0.52, 0.92],

[1, 0.55, 0.2, 0.9, 0.88]])

anchors = np.array([[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(1表示dog,2表示cat)。我们在锚定框和真值边界框中添加实例维数,并使用expand_dims函数构造形状为(批次大小、类别数包括背景、锚框数量)的随机预测结果。

labels = npx.multibox_target(np.expand_dims(anchors, axis=0),

np.expand_dims(ground_truth, axis=0),

np.zeros((1, 3, 5)))

返回的结果中有三项,都是张量格式。第三项由标记为锚定框的类别表示。

labels[2]

array([[0., 1., 2., 0., 2.]])

根据锚框和真实边界框在图像中的位置来分析这些标记类别。首先,在所有“anchor box–ground-truth bounding box”对中,锚框A4的IoU对ground-truth盒的猫是最大的,所以锚盒类A4标记为cat。不考虑锚箱A4或者猫的ground-truth真实边界框,在剩余的“nchor box–ground-truth bounding box”对中,IoU最大的一对是锚框A1,而ground-truth盒的狗,则锚盒A1类被标记为狗。接下来,穿过剩余的三个未标记的锚箱。锚框A0最大IoU ground-truth包围盒类别为dog,但IoU小于阈值(默认值为0.5),因此该类别被标记为背景;具有最大IoU的ground-truth真相边界框的类别具有锚框A2是cat,IoU大于阈值,因此该类别被标记为cat;IoU最大的真相边界框的类别,锚框A3是cat,但IoU小于阈值,因此该类别被标记为background。

返回值的第二项是一个mask变量,其形状为(批大小,锚框数量的四倍)。mask变量中的元素与每个定位框的四个偏移值一一对应。因为我们不关心背景检测,所以负类的偏移量不应该影响目标函数。通过乘以元素,mask变量中的0可以在计算目标函数之前过滤掉负的类偏移量。

labels[1]

array([[0., 0., 0., 0., 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0.,

1., 1., 1., 1.]])

返回的第一项是为每个定位框标记的四个偏移量值,负类定位框的偏移量标记为0。

labels[0]

array([[ 0.00e+00,  0.00e+00,  0.00e+00,  0.00e+00,  1.40e+00,  1.00e+01,

2.59e+00,  7.18e+00, -1.20e+00,  2.69e-01,  1.68e+00, -1.57e+00,

0.00e+00,  0.00e+00,  0.00e+00,  0.00e+00, -5.71e-01, -1.00e+00,

-8.94e-07,  6.26e-01]])

4. Bounding Boxes for Prediction

在模型预测阶段,我们首先为图像生成多个锚框,然后逐个预测这些锚框的类别和偏移量。然后,基于锚定框及其预测偏移量得到预测边界框。当有多个锚盒时,同一个目标可以输出许多相似的预测边界框。为了简化结果,我们可以去掉类似的预测边界框。一种常用的方法称为非最大抑制(NMS)。

让我们来看看NMS是如何工作的。对于预测边界框B,模型计算每个类别的预测概率。假设最大预测概率为p,与该概率相对应的范畴是B的预测范畴. 我们也指p作为预测边界框B的置信水平. 在同一幅图像上,我们对除背景外的其他预测类别的预测边界框按置信度从高到低排序,得到列表L. 选择预测边界框B1以L的最高置信水平作为基线,并删除所有带有B1 IoU的非基准预测边界框大于L的某个阈值. 这里的阈值是一个预设的超参数。在这一点上,我保留具有最高置信级别的预测边界框,并删除与之类似的其他预测边界框。接下来,选择预测边界框B2以L的第二高信心水平作为基线,并使用B2删除所有带IoU的非基准预测边界框大于L的某个阈值. 重复此过程,直到L中的所有预测边界框被用作基线。此时,L中任意一对预测边界框的IoU小于阈值。最后,输出列表L中的所有预测边界框.接下来,我们将看一个详细的例子。首先,建造四个锚箱。为了简单起见,我们假设预测的偏移量都为0。这意味着预测边界框是锚定框。最后,我们为每个类别构造一个预测概率。

anchors = np.array([[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 = np.array([0] * anchors.size)

cls_probs = np.array([[0] * 4,  # Predicted probability for background

[0.9, 0.8, 0.7, 0.1],  # Predicted probability for dog

[0.1, 0.2, 0.3, 0.9]])  # Predicted probability for cat

在图像上打印预测边界框及其置信级别。

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函数来执行NMS,并将阈值设置为0.5。这将向张量输入添加一个示例维度。我们可以看到返回结果的形状是(批量大小,锚框数量,6)。每行的6个元素表示同一预测边界框的输出信息。第一个元素是预测的类别索引,从0开始(0表示dog,1表示cat)。值-1表示NMS中的背景或删除。第二个元素是预测边界框的置信度。剩下的四个元素是x,y左上角和x、y轴坐标预测边界框右下角的轴坐标(值范围在0到1之间)。

output = npx.multibox_detection(

np.expand_dims(cls_probs, axis=0),

np.expand_dims(offset_preds, axis=0),

np.expand_dims(anchors, axis=0),

nms_threshold=0.5)

output

array([[[ 0.  ,  0.9 ,  0.1 ,  0.08,  0.52,  0.92],

[ 1.  ,  0.9 ,  0.55,  0.2 ,  0.9 ,  0.88],

[-1.  ,  0.8 ,  0.08,  0.2 ,  0.56,  0.95],

[-1.  ,  0.7 ,  0.15,  0.3 ,  0.62,  0.91]]])

我们移除了类别1的预测边界框,并将NMS保留的结果可视化。

fig = d2l.plt.imshow(img)

for i in output[0].asnumpy():

if i[0] == -1:

continue

label = ('dog=', 'cat=')[int(i[0])] + str(i[1])

show_bboxes(fig.axes, [np.array(i[2:]) * bbox_scale], label)

在实际应用中,我们可以在执行NMS之前移除置信水平较低的预测边界框,从而减少NMS的计算量。我们还可以过滤NMS的输出,例如,只保留具有较高置信水平的结果作为最终输出。

5. Summary

  • We generate multiple anchor boxes with different sizes and aspect ratios, centered on each pixel.
  • IoU, also called Jaccard index, measures the similarity of two bounding boxes. It is the ratio of the intersecting area to the union area of two bounding boxes.
  • In the training set, we mark two types of labels for each anchor box: one is the category of the target contained in the anchor box and the other is the offset of the ground-truth bounding box relative to the anchor box.
  • When predicting, we can use non-maximum suppression (NMS) to remove similar prediction bounding boxes, thereby simplifying the results.

Anchor Boxes示例实战的更多相关文章

  1. 深度学习Anchor Boxes原理与实战技术

    深度学习Anchor Boxes原理与实战技术 目标检测算法通常对输入图像中的大量区域进行采样,判断这些区域是否包含感兴趣的目标,并调整这些区域的边缘,以便更准确地预测目标的地面真实边界框.不同的模型 ...

  2. 经典论文系列 | 目标检测--CornerNet & 又名 anchor boxes的缺陷

    ​ 前言: 目标检测的预测框经过了滑动窗口.selective search.RPN.anchor based等一系列生成方法的发展,到18年开始,开始流行anchor free系列,CornerNe ...

  3. [DeeplearningAI笔记]卷积神经网络3.6-3.9交并比/非极大值抑制/Anchor boxes/YOLO算法

    4.3目标检测 觉得有用的话,欢迎一起讨论相互学习~Follow Me 3.6交并比intersection over union 交并比函数(loU)可以用来评价对象检测算法,可以被用来进一步改善对 ...

  4. 【57】目标检测之Anchor Boxes

    Anchor Boxes 到目前为止,对象检测中存在的一个问题是每个格子只能检测出一个对象,如果你想让一个格子检测出多个对象,你可以这么做,就是使用anchor box这个概念. 我们还是先吃一颗栗子 ...

  5. SpringCloudAlibaba微服务docker容器打包和部署示例实战

    概述 我们使用前面<SpringCloudAlibaba注册中心与配置中心之利器Nacos实战与源码分析(中)>的两个微服务示例,分别是库存微服务和订单微服务,基于Nacos注册中心和配置 ...

  6. 巩固一下:SpringMVC详细示例实战教程

    一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...

  7. [转]史上最全最强SpringMVC详细示例实战教程

    原文:http://www.cnblogs.com/sunniest/p/4555801.html?utm_source=tuicool&utm_medium=referral SpringM ...

  8. 史上最全最强SpringMVC详细示例实战教程

    一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...

  9. SpringMVC详细示例实战教程

    一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...

随机推荐

  1. SpringCloud之配置中心(config)的使用Git+数据库实现

    SpringCloud微服务实战系列教程 -------------------------目录------------------------------ 一.配置中心应用(Git) 二.配置中心的 ...

  2. POJ 1201 差分约束(集合最小元素个数)

    题意:       给你一个集合,然后有如下输入,a ,b ,c表示在范围[a,b]里面有至少有c个元素,最后问你整个集合最少多少个元素. 思路:       和HDU1384一模一样,首先这个题目可 ...

  3. <JVM下篇:性能监控与调优篇>05-分析GC日志

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  4. WPF之事件绑定命令

    目录 事件绑定意义 无参数的事件绑定 带EventArgs参数的事件绑定 使用事件绑定 扩展:基于InvokeCommandAction源码的实现(推荐) 参考资料 事件绑定意义 一般事件的处理程序都 ...

  5. Day004 选择结构

    选择结构 if单选择结构(if) if双选择结构(if...else...) if多选择结构(if..else if...else) 嵌套的if结构 switch多选择结构 switch语句中的变量类 ...

  6. 运维告诉我CPU飙升300%,为什么我的程序上线就奔溃了

    线上服务CPU飙升 前言 功能开发完成仅仅是项目周期中的第一步,一个完美的项目是在运行期体现的 今天我们就来看看笔者之前遇到的一个问题CPU飙升的问题. 代码层面从功能上看没有任何问题但是投入使用后却 ...

  7. QQ账号登录测试用例

  8. 关于MySQL参数,这些你要知道

    前言: 在前面一些文章中,经常能看到介绍某某参数的作用,可能有些小伙伴仍搞不清楚 MySQL 参数是啥.本篇文章我们来聊聊 MySQL 参数,学习下如何管理维护 MySQL 参数. 1.MySQL参数 ...

  9. linux远程下载文件 的两种方法之 ftp命令和scp命令

    ftp命令: 服务器有安装ftp Server,另外一台linux可以使用ftp的client程序来进行文件的拷贝读取和下载. 1. 连接ftp服务器  格式:ftp [hostname| ip-ad ...

  10. 5分钟让你理解K8S必备架构概念,以及网络模型(上)

    写在前面 在这用XMind画了一张导图记录Redis的学习笔记和一些面试解析(源文件对部分节点有详细备注和参考资料,欢迎关注我的公众号:阿风的架构笔记 后台发送[导图]拿下载链接, 已经完善更新): ...