5

我已经用自定义数据集(电池)训练了一个 SSD Mobilenet 模型。下面给出了电池的示例图像,并附上了我用来训练模型的配置文件。

示例电池图像

当物体更靠近相机(使用网络摄像头测试)时,它会以超过0.95的概率准确地检测到物体,但是当我将物体移动到更长的距离时,它不会被检测到。经过调试,发现对象被检测到但概率较低0.35。最小阈值设置为 0.5。如果我将阈值 0.5 更改为 0.2,则会检测到对象,但会有更多错误检测。

参考这个链接,SSD对于小物体的表现不是很好,一个替代的解决方案是使用FasterRCNN,但是这个模型在实时上很慢。我也希望使用 SSD 从更远的距离检测电池。

请帮我解决以下问题

  1. 如果我们想以更高的概率检测更远距离的物体,我们是否需要更改配置中的纵横比和比例参数?
  2. 如果我们想要纵横比,如何选择与对象相关的那些值?
4

1 回答 1

12

更改纵横比和比例尺无助于提高小物体的检测精度(因为原始比例尺已经足够小,例如min_scale = 0.2)。您需要更改的最重要的参数是feature_map_layout. feature_map_layout确定特征图的数量(及其大小)及其对应的深度(通道)。但遗憾的是,此参数无法在 pipeline_config 文件中配置,您必须直接在特征提取器中对其进行修改。

这就是为什么这feature_map_layout在检测小物体时很重要。 在此处输入图像描述

上图中,(b)和(c)是两个不同布局的特征图。groundtruth 图像中的狗与 4x4 特征图上的红色锚框匹配,而猫与 8x8 特征图上的蓝色锚框匹配。现在,如果您要检测的对象是猫的耳朵,那么将没有锚框来匹配该对象。所以直觉是:如果没有锚框匹配一个对象,那么这个对象就不会被检测到。 要成功检测到猫的耳朵,您需要的可能是一张 16x16 的特征图。

以下是如何更改为feature_map_layout. 此参数在每个特定的特征提取器实现中配置。假设你使用ssd_mobilenet_v1_feature_extractor,那么你可以在这个文件中找到它。

feature_map_layout = {
    'from_layer': ['Conv2d_11_pointwise', 'Conv2d_13_pointwise', '', '',
                   '', ''],
    'layer_depth': [-1, -1, 512, 256, 256, 128],
    'use_explicit_padding': self._use_explicit_padding,
    'use_depthwise': self._use_depthwise,
}

这里有 6 个不同尺度的特征图。前两层直接取自 mobilenet 层(因此深度均为 -1),其余四层来自额外的卷积操作。可以看出,最底层的feature map来自Conv2d_11_pointwisemobilenet这一层。一般层越低,特征图特征越精细,对小物体的检测效果越好。所以你可以把它Conv2d_11_pointwise改成Conv2d_5_pointwise(为什么是这个?可以从张量流图中找到,这个层比层有更大的特征图Conv2d_11_pointwise),它应该有助于检测更小的物体。

但是更好的准确性需要额外的成本,这里的额外成本是检测速度会下降一点,因为有更多的锚框需要处理。(更大的特征图)。也因为我们选择Conv2d_5_pointwiseConv2d_11_pointwise,我们失去了 的检测能力Conv2d_11_pointwise

如果您不想更改图层而只是添加一个额外的特征图,例如使其总共有 7 个特征图,则您也必须将num_layers配置文件的 int 更改为 7。 你可以把这个参数想象成检测网络的分辨率,层数越低,分辨率越精细。

现在,如果您已经执行了上述操作,还有一件事可以帮助您添加更多带有小物体的图像。如果这不可行,至少您可以尝试添加数据增强操作,例如random_image_scale

于 2019-05-10T11:34:57.060 回答