锚框的-初步实现

大家好,我是阿林。学习目标检测,就首先学习锚框的生成。希望大家一起学习基础。我在学习中,如有错误还望指出。

%matplotlib inline 
import torch
from d2l import torch as d2l

torch.set_printoptions(2)

##这里是学习锚框使用的pytorch的一些基础的知识。

## 每日一学基础知识

#pytorch.torch.set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, profile=None, sci_mode=None)


设置precision显示的精度,threshold显示的数据数量,超过丢弃。一般都是用于设置精度


#torch.meshgrid(centor_h,centor_w)

一般用于生成网格,一般用连续的数组去制造网格。

C = torch.cat( (A,B),0 )  #按维数0拼接(竖着拼)

C = torch.cat( (A,B),1 )  #按维数1拼接(横着拼)

#torch.stack(sequence, dim=0)横横竖

沿一个新维度对输入张量序列进行连接,序列中所有张量应为相同形状;

stack 函数返回的结果会新增一个维度,而stack()函数指定的dim参数,就是新增维度的(下标)位置。

import torch

a = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

b = torch.tensor([[11, 22, 33], [44, 55, 66], [77, 88, 99]])

c = torch.stack([a, b], 1)

print(a)

print(b)

print(c)

tensor([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]])

tensor([[11, 22, 33],
        [44, 55, 66],
        [77, 88, 99]])

tensor([[[ 1,  2,  3],
         [11, 22, 33]],
 
        [[ 4,  5,  6],
         [44, 55, 66]],
 
        [[ 7,  8,  9],
         [77, 88, 99]]])


 PyTorch中的repeat()函数可以对张量进行重复扩充。

当参数只有两个时:(列的重复倍数,行的重复倍数)。1表示不重复

当参数有三个时:(通道数的重复倍数,列的重复倍数,行的重复倍数)。


#torch.repeat_interleave(input, repeats, dim=None) 

x = torch.tensor([1, 2, 3])

x.repeat_interleave(2)

tensor([1, 1, 2, 2, 3, 3])

y = torch.tensor([[1, 2], [3, 4]])

torch.repeat_interleave(y, 2)

tensor([1, 1, 2, 2, 3, 3, 4, 4])

torch.repeat_interleave(y,3,0)

tensor([[1, 2],
        [1, 2],
        [1, 2],
        [3, 4],
        [3, 4],
        [3, 4]])
torch.repeat_interleave(y, 3, dim=1)

tensor([[1, 1, 1, 2, 2, 2],
        [3, 3, 3, 4, 4, 4]])


torch.repeat_interleave(y, torch.tensor([1, 2]), dim=0)
tensor([[1, 2],
        [3, 4],
        [3, 4]])

torch.squeeze()

这个是对通道进行压缩。可以看出,维度为(1,2,1,3)直接变为了(2,3)。即去掉了维度为1的所有维度。

##基础知识已经学习完,我们再次进入到学习锚框中。


def multibox_prior(data,sizes,ratios):
    """生成以每个像素为中心的具有不同形状的锚框"""
    in_height,in_width = data.shape[-2:]
    #data是什么形状的,data.shape检测一下,sizes是相对于图片所占得面积的比例,ratios是锚框的高宽比。
    device, num_sizes, num_ratios = data.device, len(sizes), len(ratios)
    #size和ratios是一个字典,上面的式子是将其转化为数组
    boxes_per_pixel = (num_sizes + num_ratios - 1)
    #因为如果使用sizes*ratios作为锚框的数量会太多的不利于计算,所以使用规定每个像素的锚框数量。
    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轴上缩放步长
    #为什么要缩放步长呢。获得了每个像素的中心点也是锚框的中心点
    centor_h = (torch.arange(in_height,device=device)+offset_h)*steps_h
    centor_w = (torch.arange(in_width,device=device)+offset_w)*steps_w
    
    #生成网格,用于生成坐标
    shift_y,shift_x = torch.meshgrid(centor_h,centor_w)

    shift_y,shift_x = shift_y.reshape(-1),shift_x.reshape(-1)#固定行数或者列数
 
    # 通过在matplotlib中进行可视化,来查看函数运行后得到的网格化数据的结果
    # plt.plot(shift_x, shift_y, marker='.', color='red', linestyle="none",markersize="0.1")
    # plt.show()

    # 生成“n+m-1”个高和宽
    w = torch.cat((size_tensor * torch.sqrt(ratio_tensor),sizes[0] * torch.sqrt(ratio_tensor[1:])))* in_height / in_width
    h = torch.cat((size_tensor / torch.sqrt(ratio_tensor),sizes[0] /torch.sqrt(ratio_tensor[1:])))


    #相当与生成中心点上下加减高宽的矩形锚框的矩阵 
    anchor_manipulations = torch.stack((-w, -h, w, h)).T.repeat(in_height * in_width, 1) / 2

    #这个相当于得到网格元素中心点的坐标为什么有两对坐标呢,那是因为他要对应加上高宽的坐标,和减去高宽的坐标
    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('./pytorch/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
#相当于将锚框分为某个像素点的的哪一个锚框的四角坐标。
boxes = Y.reshape(h,w,5,4)
boxes[250,250,0,:]
def show_bboxes(axes,bboxes,labels=None,colors=None):
    """显示所有的边界框"""
    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)
    print(labels)
    colors = _make_list(colors,['b', 'g', 'r', 'm', 'c'])
    print(colors)
    for i,bbox in enumerate(bboxes):
        color = colors[i % len(colors)]
        rect = d2l.bbox_to_rect(bbox.detach().numpy(), 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))
d2l.set_figsize()
bbox_scale = torch.tensor((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'])

以上如果还是有些不懂代码的含义的话,可以一步一步的将其变量打印出来,可以有利于理解,阿林我也是这样一步一步的理解的。

最后出现的效果是

 

下一期我将会继续学习锚框的生成,阿林我将会继续学习,尽量快一点出下一期

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值