对训练图像做一系列随机改变,扩大数据集规模,降低模型对某些属性的依赖,提高模型泛化能力。
# 指定RGB三个通道的均值和方差来将图像通道归一化
normalize = gdata.vision.transforms.Normalize(
[0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
TargetImgAugs = gdata.vision.transforms.Compose([
gdata.vision.transforms.RandomFlipLeftRight()
gdata.vision.transforms.RandomFlipTopBottom()
gdata.vision.transforms.RandomResizedCrop((200, 200), scale=(0.1, 1), ratio=(0.5, 2))
gdata.vision.transforms.RandomBrightness(0.5)
gdata.vision.transforms.RandomHue(0.5)
gdata.vision.transforms.RandomColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.5)
gdata.vision.transforms.ToTensor() #将小批量图像转成MXNet需要的格式,即形状为(批量大小, 通道数, 高, 宽)、值域在0到1之间且类型为32位浮点数。
normalize
])
迁移学习中的一种常用技术
当目标数据集远小于源数据集时,微调有助于提升模型的泛化能力。
生成大量区域,然后判断目标是否在此区域内,并调整区域边缘从而更准确地预测目标的真实边界框(ground-truth bounding box)。不同的模型使用的区域采样方法可能不同。其中的一种方法:它以每个像素为中心生成多个大小和宽高比(aspect ratio)不同的边界框。这些边界框被称为锚框(anchor box)。我们将在后面基于锚框实践目标检测。
假设输入图像高为 h h h,宽为 w w w。我们分别以图像的每个像素为中心生成不同形状的锚框。设大小为 s ∈ ( 0 , 1 ] s\in (0,1] s∈(0,1]且宽高比为 r > 0 r > 0 r>0,那么锚框的宽和高将分别为 w s r ws\sqrt{r} wsr和 h s / r hs/\sqrt{r} hs/r。当中心位置给定时,已知宽和高的锚框是确定的。
交并比
Jaccard系数(Jaccard index)可以衡量两个集合的相似度。给定集合 A \mathcal{A} A和 B \mathcal{B} B,它们的Jaccard系数即二者交集大小除以二者并集大小:
J ( A , B ) = ∣ A ∩ B ∣ ∣ A ∪ B ∣ . J(\mathcal{A},\mathcal{B}) = \frac{\left|\mathcal{A} \cap \mathcal{B}\right|}{\left| \mathcal{A} \cup \mathcal{B}\right|}. J(A,B)=∣A∪B∣∣A∩B∣.
我们通常将Jaccard系数称为交并比(intersection over union,IoU),即两个边界框相交面积与相并面积之比
标注训练集的锚框
我们将每个锚框视为一个训练样本。为每个锚框标注两类标签:一是锚框所含目标的类别,简称类别;二是真实边界框相对锚框的偏移量,简称偏移量(offset)。
在目标检测的训练集中,每个图像已标注了真实边界框的位置以及所含目标的类别。在生成锚框之后,我们主要依据与锚框相似的真实边界框的位置和类别信息为锚框标注。
我们可以通过contrib.nd
模块中的MultiBoxTarget
函数来为锚框标注类别和偏移量。该函数将背景类别设为0,并令从零开始的目标类别的整数索引自加1(1为狗,2为猫)。我们通过expand_dims
函数为锚框和真实边界框添加样本维,并构造形状为(批量大小, 包括背景的类别个数, 锚框数)的任意预测结果。返回的结果里有3项,均为NDArray。
第三项表示为锚框标注的类别。第二项为掩码(mask)变量,形状为(批量大小, 锚框个数的四倍)。第一项是为每个锚框标注的四个偏移量,其中负类锚框的偏移量标注为0。
labels = contrib.nd.MultiBoxTarget(anchors.expand_dims(axis=0),
ground_truth.expand_dims(axis=0),
nd.zeros((1, 3, 5)))
输出预测边界框
为了使结果更加简洁,我们可以移除相似的预测边界框。常用的方法叫作非极大值抑制(non-maximum suppression,NMS)。
下面我们来介绍一种基于卷积神经网络的方法。
在某个尺度下,假设我们依据 ci 张形状为 h×w 的特征图生成 h×w 组不同中心的锚框,且每组的锚框个数为 a 。例如,在刚才实验的第一个尺度下,我们依据10(通道数)张形状为 4×4 的特征图生成了16组不同中心的锚框,且每组含3个锚框。 接下来,依据真实边界框的类别和位置,每个锚框将被标注类别和偏移量。在当前的尺度下,目标检测模型需要根据输入图像预测 h×w 组不同中心的锚框的类别和偏移量。
假设这里的 ci 张特征图为卷积神经网络根据输入图像做前向计算所得的中间输出。既然每张特征图上都有 h×w 个不同的空间位置,那么相同空间位置可以看作含有 ci 个单元。 根据“二维卷积层”一节中感受野的定义,特征图在相同空间位置的 ci 个单元在输入图像上的感受野相同,并表征了同一感受野内的输入图像信息。 因此,我们可以将特征图在相同空间位置的 ci 个单元变换为以该位置为中心生成的 a 个锚框的类别和偏移量。 不难发现,本质上,我们用输入图像在某个感受野区域内的信息来预测输入图像上与该区域位置相近的锚框的类别和偏移量。
当不同层的特征图在输入图像上分别拥有不同大小的感受野时,它们将分别用来检测不同大小的目标。例如,我们可以通过设计网络,令较接近输出层的特征图中每个单元拥有更广阔的感受野,从而检测输入图像中更大尺寸的目标。
R-CNN
快速的R-CNN(Fast R-CNN)
只对整个图像做卷积神经网络的前向计算。
R-CNN的主要性能瓶颈在于需要对每个提议区域独立抽取特征。由于这些区域通常有大量重叠,独立的特征抽取会导致大量的重复计算。
更快的R-CNN(Faster R-CNN)
Faster R-CNN提出将选择性搜索替换成区域提议网络(region proposal network),从而减少提议区域的生成数量,并保证目标检测的精度。
区域提议网络的计算步骤如下。
掩码R-CNN(Mask R-CNN)
Mask R-CNN在Faster R-CNN基础上引入一个全卷积网络,从而借助目标的像素级位置进一步提升目标检测的精度。
Mask R-CNN将兴趣区域池化层替换成了兴趣区域对齐层,即通过双线性插值(bilinear interpolation)来保留特征图上的空间信息,从而更适于像素级预测。
兴趣区域对齐层的输出包含了所有兴趣区域的形状相同的特征图。它们既用来预测兴趣区域的类别和边界框,又通过额外的全卷积网络预测目标的像素级位置。我们将在“全卷积网络(FCN)”一节介绍如何使用全卷积网络预测图像中像素级的语义。
由一个基础网络块和若干个多尺度特征块串联而成
基础网络块用来从原始图像中抽取特征,因此一般会选择常用的深度卷积神经网络。
类别预测层
指定参数 a a a和 q q q后,它使用一个填充为1的 3 × 3 3\times3 3×3卷积层。该卷积层的输入和输出的高和宽保持不变。
def cls_predictor(num_anchors, num_classes):
return nn.Conv2D(num_anchors * (num_classes + 1), kernel_size=3,
padding=1)
使用一个保持输入高和宽的卷积层。输出和输入在特征图宽和高上的空间坐标一一对应。
考虑输出和输入同一空间坐标 ( x , y ) (x,y) (x,y):输出特征图上 ( x , y ) (x,y) (x,y)坐标的通道里包含了以输入特征图 ( x , y ) (x,y) (x,y)坐标为中心生成的所有锚框的类别预测。因此输出通道数为 a ( q + 1 ) a(q+1) a(q+1),其中索引为 i ( q + 1 ) + j i(q+1) + j i(q+1)+j( 0 ≤ j ≤ q 0 \leq j \leq q 0≤j≤q)的通道代表了索引为 i i i的锚框有关类别索引为 j j j的预测。
边界框预测层
边界框预测层的设计与类别预测层的设计类似。唯一不同的是,这里需要为每个锚框预测4个偏移量,而不是 q+1 个类别。
def bbox_predictor(num_anchors):
return nn.Conv2D(num_anchors * 4, kernel_size=3, padding=1)
连结多尺度的预测