0
点赞
收藏
分享

微信扫一扫

(二)汇编语句组成

之——对边缘框的简化

目录

之——对边缘框的简化

杂谈

正文

1.锚框操作

2.IoU交并比

3.锚框标号

4.非极大值抑制

5.实现

拓展


杂谈

        边缘框这样一个指定roi区域的操作对卷积神经网络实际上是很不友好的,这可能会对网络感受野提出一些特定的要求,所以诞生了锚框的技术:

        锚框使得神经网络可以从不同尺度去关注图片以确定最好的物体roi。 


正文

1.锚框操作

        很多目标检测算法都是基于锚框的:

        可以理解为,当图片进来的时候,需要有一个算法来衡量我要关注的区域,因为各个图片感兴趣的物体的大小肯定是不一样的,那么对于每一个图片就需要生成一些区域来投入到卷积网络中。 这更多的是为了解决预测时候的需求,因为预测时候才会需要考虑各个尺寸的框。


2.IoU交并比

        度量两个框之间的相似度:


3.锚框标号

        要对每个锚框进行预测,要么认为是背景什么都没有,要么跟某一个真实类关联并标注差距,这是在训练时候需要的:

        通过计算所有锚框与真实边缘框的IoU,找到最大值,可以绑定锚框和边缘框的类别:

        注意看上面的过程,每次读取一张图片都会按照锚框数生成多个训练样本,所以才需要进行锚框标号,将与真实边缘框相关的锚框赋予类别,但一个锚框又只能用一次,所以才会这样做 ,要保证每个真实框被分配到一个或多个锚框,其他低于要求的锚框变成负样本,这样就可以一次性处理所有生成的锚框并给他们赋予类别。上面这种方案比较极端,只保留了和真实框最接近的锚框,实际情况肯定是有阈值的。


4.非极大值抑制

        原理:

        步骤就是,要输出时候,对于每一个锚框,也就是先验框,先去掉属于背景的(保留 softmax有类别输出的);然后确定softmax预测最大值也就是置信度最高的类别;然后去掉所有其他和这个框的IoU值过大的框(去掉重复的)。


5.实现

        对于每个像素为中心,生成不同宽度和高度的锚框:

import torch
from d2l import torch as d2l

torch.set_printoptions(2)  # 精简输出精度


def multibox_prior(data, sizes, ratios):
    """生成以每个像素为中心具有不同形状的锚框"""
    in_height, in_width = data.shape[-2:]
    device, num_sizes, num_ratios = data.device, len(sizes), len(ratios)
    boxes_per_pixel = (num_sizes + num_ratios - 1)
    size_tensor = torch.tensor(sizes, device=device)
    ratio_tensor = torch.tensor(ratios, device=device)

    # 为了将锚点移动到像素的中心,需要设置偏移量。
    # 因为一个像素的高为1且宽为1,我们选择偏移我们的中心0.5
    offset_h, offset_w = 0.5, 0.5
    steps_h = 1.0 / in_height  # 在y轴上缩放步长
    steps_w = 1.0 / in_width  # 在x轴上缩放步长

    # 生成锚框的所有中心点
    center_h = (torch.arange(in_height, device=device) + offset_h) * steps_h
    center_w = (torch.arange(in_width, device=device) + offset_w) * steps_w
    shift_y, shift_x = torch.meshgrid(center_h, center_w, indexing='ij')
    shift_y, shift_x = shift_y.reshape(-1), shift_x.reshape(-1)

    # 生成“boxes_per_pixel”个高和宽,
    # 之后用于创建锚框的四角坐标(xmin,xmax,ymin,ymax)
    w = torch.cat((size_tensor * torch.sqrt(ratio_tensor[0]),
                   sizes[0] * torch.sqrt(ratio_tensor[1:])))\
                   * in_height / in_width  # 处理矩形输入
    h = torch.cat((size_tensor / torch.sqrt(ratio_tensor[0]),
                   sizes[0] / torch.sqrt(ratio_tensor[1:])))
    # 除以2来获得半高和半宽
    anchor_manipulations = torch.stack((-w, -h, w, h)).T.repeat(
                                        in_height * in_width, 1) / 2

    # 每个中心点都将有“boxes_per_pixel”个锚框,
    # 所以生成含所有锚框中心的网格,重复了“boxes_per_pixel”次
    out_grid = torch.stack([shift_x, shift_y, shift_x, shift_y],
                dim=1).repeat_interleave(boxes_per_pixel, dim=0)
    output = out_grid + anchor_manipulations
    return output.unsqueeze(0)

        查看:

img = d2l.plt.imread('../img/catdog.jpg')
h, w = img.shape[:2]

print(h, w)
X = torch.rand(size=(1, 3, h, w))
Y = multibox_prior(X, sizes=[0.75, 0.5, 0.25], ratios=[1, 2, 0.5])
Y.shape

        非常贵的锚框数量。 


拓展

        其他的一些方法:

  • 直接把图片隔开成很多个块预测
  • 对每个像素中去比例预测
  • 其他的聚焦方法
举报

相关推荐

0 条评论