Pytorch目标检测算法(2)(基于李沐老师的课程)

目录

二.锚框

2.1 定义

2.2 实现过程

1.锚框数量

2.实现思路

3.实现


二.锚框

2.1 定义

目标检测算法,顾名思义我们需要在输入图像上检测是否存在我们关注的目标。因此我们需要在输入图像上进行大量的采样,然后进行判断是否存在目标,并调整区域边界从而更准确的预测目标的真实边框。故在图像上的大量采样所得到的不同缩放比和宽高比的边界框就称为锚框

图示:

2.2 实现过程

1.锚框数量

在李沐老师的课程中,讲解的是根据每个像素中心位置生成不同边长比 (其实应该是面积比,但是根据老师的公式推到下来得到的是边长比) 和宽高比的锚框。

输入:s = (0.3, 0.5, 0.75)  r = (1, 0.5, 2),其中s为边长比, r为宽高比

如果根据每一个边长比和宽高比配对生成锚框那么每个像素应该生成 len(s) * len(r) 个锚框,如果图片的像素为480 * 480 那么就会生成480 * 480 * 3 * 3 = 2073600 这样计算量太大了 ,因此我们在锚框的配对上采取如下策略:

 这样每个像素点生成 ( len(s) + len(r) - 1)的锚框,对于整个输入图像产生wh(len(s) + len(r) - 1)个锚框。

2.实现思路

1)生成中心点坐标位置矩阵

2)生成锚框对于每个中心点的宽高矩阵

3)两者进行相加,得到锚框矩阵

3.实现

第一步:生成我们需要的辅助变量

def multibox_prior(data, sizes, ratios):
    # in_height, in_width 为输入的高宽
    in_height, in_width = data.shape[-2:]
    
    # num_sizes, num_ratios 为输入的边长比和宽高比数量
    device, num_sizes, num_ratios = data.device, len(sizes), len(ratios)
    
    # boxes_per_pixel 为每个像素点生成的锚框数量
    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轴上缩放步长

第二步:生成坐标中心矩阵 

由如下代码生成每个像素点中心位置的x坐标 和 y坐标 因为共有 h * w 个像素点,因此最终得到的一维tnesor的长度为 h * w, 如下代码存在一个尺度问题,也就是x匹配y, 还是y匹配x的选择问题,如下代码中选择的是x匹配y。

eg : h = 5, w = 5 X = (x1, x2, x3, x4, x5), Y = (y1, y2, y3, y4, y5)

        shift_x = (x1, x2, x3, x4, x5) * 5 ,   shift_y = (yi, yi, yi, yi, yi) * 5   i = [1, 5]

    # 生成锚框的所有中心点
    # center_h, center_w 为缩放后的y轴,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 为 将一维的tensor转换为 h * w 的二维tensor
    # 其中shift_y 的每列为center_y shift_x 的每行为center_w
    shift_y, shift_x = torch.meshgrid(center_h, center_w)
    
    # 将其拉成一维tensor shape = [in_heifht * in_width]
    shift_y, shift_x = shift_y.reshape(-1), shift_x.reshape(-1)

将得到的shift_y, shift_x 进行组合得到每个像素点的坐标矩阵

out_grid = torch.stack([shift_x, shift_y, shift_x, shift_y],
                dim=1).repeat_interleave(boxes_per_pixel, dim=0)

 其中的难点为 tensor.repeat()tensor.repeat_interleave()的区别,这里个人理解是

 tensor.repeat(*size) :将tensor看作一个元素,生成*size的尺寸

tensor.repeat_interleave() : 对于输入,在指定维度上进行重复

eg:

第三步:创建锚框宽高矩阵

在李沐老师的课程中选择的锚框的宽高为 ws√r  和 hs / √r  ,

但在实际的操作上, 为了保持锚框的宽高比为r,他在宽上 *( h / w) , 这样虽然锚框的宽高比为r ,但是面积比就不再是s^2,但是毕竟只是一个锚框是个人指定的大小,影响不大。因此在代码中我们选择使用李沐老师的锚框高宽,但下面对于实际的高宽进行一个推导。

锚框的高宽满足两个公式 : w'h' = WH * s^2 , w' / h' = r

解得: w' = √(WHr) * s   h'  = √(WH / r) * s 

归一化后 w0' = √(Hr / W) * s   h0' = √(W / rH) * s

当H == W时, 李沐老师的公式完全正确。

当H != W时,面积比会发生偏差h/w,如果图片的高宽比相差不是很大,结果的变动不会很大。

"""生成w, h的一维tensor"""
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

第四步:相加返回

output = out_grid + anchor_manipulations
return output.unsqueeze(0)

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch是一个广泛用于机器学习和深度学习的开源框架。YOLO(You Only Look Once)是一种流行的目标检测算法,它通过将目标检测任务转化为一个回归问题,在一次前向传播中同时预测目标的边界框和类别。 使用PyTorch实现YOLO目标检测算法,需要以下步骤: 1. 数据准备:收集和标注图像数据集,标注每个图像中的目标位置和类别。 2. 网络模型定义:使用PyTorch定义YOLO网络模型。YOLO网络通常由卷积层、池化层和全连接层组成。网络的最后一层输出包含目标边界框的坐标和类别概率。 3. 损失函数定义:为了训练模型,需要定义损失函数。YOLO使用交叉熵损失函数来度量预测类别和真实类别之间的差异,以及预测边界框和真实边界框之间的差异。 4. 数据加载和预处理:使用PyTorch提供的数据加载函数加载和预处理图像数据集。预处理步骤可能包括图像缩放、裁剪、归一化和数据增强(如随机翻转、旋转等)。 5. 网络训练:使用加载的数据集和定义的网络模型进行训练。通过计算损失函数,并使用反向传播算法更新网络权重,来调整网络模型以更好地预测目标。 6. 目标检测:使用训练好的模型对新的图像进行目标检测。首先将图像输入网络,然后解码预测的边界框和类别概率,最后根据设定的阈值和非极大值抑制方法,确定最终的目标检测结果。 总之,使用PyTorch实现YOLO目标检测算法需要进行数据准备、网络模型定义、损失函数定义、数据加载和预处理、网络训练以及目标检测等步骤。这个过程可以通过PyTorch提供的丰富功能和易于使用的API实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值