神经网络与深度学习-学习笔记(5)

1.目标检测与YOLO

目标检测问题
目标检测是在给定的图片中精确找到物体所在位置,并标注出物体的类别。物体的尺寸变化范围很大,摆放物体的角度,姿态不定,而且可以出现在图片的任何地方,并且物体还可以是多个类别。

目标检测问题发展
① R-CNN
② SPP NET
③ Fast R-CNN
④ Faster R-CNN
⑤ 最终实现YOLO
YOLO是一个集大成的方法,不了解之前的方法,很难掌握YOLO的思路。
YOLO: You Only Look Once

2.目标检测实现:

预备知识:

① 目标检测基本原理
        很多时候图像里有多个我们感兴趣的目标,我们不仅想知道它们的类别,还想得到它们在图像中的具体位置。在计算机视觉里,我们将这类任务称为目标检测(object detection)或物体检测。目标检测在多个领域中被广泛使用。例如,在无人驾驶里,我们需要通过识别拍摄到的视频图像里的车辆、行人、道路和障碍的位置来规划行进线路。机器人也常通过该任务来检测感兴趣的目标。安防领域则需要检测异常目标,如歹徒或者炸弹。

在目标检测里,我们通常使用边界框(bounding box)来描述目标位置。边界框是一个矩形框,可以由矩形左上角的x和y轴坐标与右下角的x和y轴坐标确定。我们根据下面的图的坐标信息来定义图中狗和猫的边界框。图中的坐标原点在图像的左上角,原点往右和往下分别为x轴和y轴的正方向。

dog_bbox, cat_bbox = [60, 45, 378, 516], [400, 112, 655, 493]

我们可以在图中将边界框画出来,以检查其是否准确。画之前,我们定义一个辅助函数bbox_to_rect。它将边界框表示成matplotlib的边界框格式。

锚框:

目标检测算法通常会在输入图像中采样大量的区域,然后判断这些区域中是否包含我们感兴趣的目标,并调整区域边缘从而更准确地预测目标的真实边界框(ground-truth bounding box)。
不同的模型使用的区域采样方法可能不同。这里我们介绍其中的一种方法:它以每个像素为中心生成多个大小和宽高比(aspect ratio)不同的边界框。这些边界框被称为(anchor box)。我们将在后面基于锚框实践目标检测。

导入相关包:

生成多个锚框:

假设输入图像高为h,宽为w。我们分别以图像的每个像素为中心生成不同形状的锚框。设大小为s∈(0,1]且宽高比为r>0,那么锚框的宽和高将分别为𝑤𝑠√𝑟 和ℎ𝑠/ √𝑟。当中心位置给定时,已知宽和高的锚框是确定的。
下面我们分别设定好一组大小s1,…,sn和一组宽高比r1,…,rm。如果以每个像素为中心时使用所有的大小与宽高比的组合,输入图像将一共得到w*h*n*m个锚框。虽然这些锚框可能覆盖了所有的真实边界框,但计算复杂度容易过高。因此,我们通常只对包含s1或r1的大小与宽高比的组合感兴趣,即 

 也就是说,以相同像素为中心的锚框的数量为n+m−1。对于整个输入图像,我们将一共生成w*h(n+m−1)个锚框。
以上生成锚框的方法实现在下面的MultiBoxPrior函数中。指定输入、一组大小和一组宽高比,该函数将返回输入的所有锚框。

 

shifts_x和shifts_y是将宽高进行归一化处理然后用meshgrid函数生成一个向量矩阵,最后reshape成一行向量。 

将reshape之后的向量进行stack操作,之后将得到的shift与原始的base_anchors相加从而自动生成所有的anchor 。

我们看到,返回锚框变量y的形状为(1,锚框个数,4)。将锚框变量y的形状变为(图像高,图像宽,以相同像素为中心的锚框个数,4)后,我们就可以通过指定像素位置来获取所有以该像素为中心的锚框了。下面的例子里我们访问以(250,250)为中心的第一个锚框。它有4个元素,分别是锚框左上角的x和y轴坐标和右下角的x和y轴坐标,其中x和y轴的坐标值分别已除以图像的宽和高,因此值域均为0和1之间。

 为了描绘图像中以某个像素为中心的所有锚框,我们先定义show_bboxes函数以便在图像上画出多个边界框。这里将数据打包成列表。

为了描绘图像中以某个像素为中心的所有锚框,我们先定义show_bboxes函数以便在图像上画出多个边界框。每个bbox进行迭代然后在图像上画出边界框 。

刚刚我们看到,变量boxes中xx和yy轴的坐标值分别已除以图像的宽和高。在绘图时,我们需要恢复锚框的原始坐标值,并因此定义了变量bbox_scale。现在,我们可以画出图像中以(250, 250)为中心的所有锚框了。可以看到,大小为0.75且宽高比为1的锚框较好地覆盖了图像中的狗。 

交互比:

刚刚提到某个锚框较好地覆盖了图像中的狗。如果该目标的真实边界框已知,这里的“较好”该如何量化呢?一种直观的方法是衡量锚框和真实边界框之间的相似度。我们知道,Jaccard系数(Jaccard index)可以衡量两个集合的相似度。给定集合A和B,它们的Jaccard系数即二者交集大小除以二者并集大小:

实际上,我们可以把边界框内的像素区域看成是像素的集合。如此一来,我们可以用两个边界框的像素集合的Jaccard系数衡量这两个边界框的相似度。当衡量两个边界框的相似度时,我们通常将Jaccard系数称为交并比,即两个边界框相交面积与相并面积之比,如图所示。交并比的取值范围在0和1之间:0表示两个边界框无重合像素,1表示两个边界框相等。

下面我们对齐进行实现:

set1和set2分别为(n1,4),(n2,4)大小的张量,利用clamp函数和向量运算直接计算了相交面积大小,当二者不相交时clamp函数将二者的upper_boundslower_bounds置为零,IOU计算时就不会有负值。

计算IOU来衡量锚框与真实边界框以及锚框与锚框之间的相似度。

标注训练集的锚框:

在训练集中,我们将每个锚框视为一个训练样本。为了训练目标检测模型,我们需要为每个锚框标注两类标签:一是锚框所含目标的类别,简称类别;二是真实边界框相对锚框的偏移量,简称偏移量(offset)。
在目标检测时,我们首先生成多个锚框,然后为每个锚框预测类别以及偏移量。
接着根据预测的偏移量调整锚框位置从而得到预测边界框。
最后筛选需要输出的预测边界框。

依此类推,直到矩阵X中所有n[b]列元素全部被丢弃。这个时候,我们已为n[b]个锚框各分配了一个真实边界框。 接下来,我们只遍历剩余的n[a]−n[b]个锚框:给定其中的锚框Ai,根据矩阵X的第i行找到与Ai交并比最大的真实边界框Bj,且只有当该交并比大于预先设定的阈值时,才为锚框Ai分配真实边界框Bj。

如果一个锚框A被分配了真实边界框B,将锚框A的类别设为B的类别,并根据B和A的中心坐标的相对位置以及两个框的相对大小为锚框A标注偏移量。设锚框A及其被分配的真实边界框B的中心坐标分别为(x[a],y[a])和(x[b],y[b]),A和B的宽分别为w[a]和w[b],高分别为h[a]和h[b],一个常用的技巧是将A的偏移量标注为

其中常数的默认值为μx=μy=μw=μh=0,σx=σy=0.1,σw=σh=0.2,如果一个锚框没有被分配真实边界框,我们只需将该锚框的类别设为背景。类别为背景的锚框通常被称为负类锚框,其余则被称为正类锚框。 

 下面是一个真实例子的演示:

输入gt和anchor并且在图中显示,显示出的gt和anchor如下图:

下面实现MultiBoxTarget函数来为锚框标注类别和偏移量。该函数将背景类别设为0,并令从零开始的目标类别的整数索引自加1(1为狗,2为猫)。

实现MultiBoxTarget函数来为锚框标注类别和偏移量 

我们根据锚框与真实边界框在图像中的位置来分析这些标注的类别。例如,在所有的“锚框—真实边界框”的配对中,锚框A4与猫的真实边界框的交并比最大,因此锚框A4类别标注为猫。

返回值的第二项为掩码(mask)变量,形状为(批量大小, 锚框个数的四倍)。掩码变量中的元素与每个锚框的4个偏移量一一对应。 由于我们不关心对背景的检测,有关负类的偏移量不应影响目标函数。通过按元素乘法,掩码变量中的0可以在计算目标函数之前过滤掉负类的偏移量。
labels[1]

输出:

tensor([[0., 0., 0., 0., 1., 1., 1., 1., 1.,1., 1., 1., 0., 0., 0., 0., 1., 1.,1., 1.]])

输出预测边界框:

锚框数量较多时,同一个目标上可能会输出较多相似的预测边界框。为了使结果更加简洁&#

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值