我已经使用自定义数据集(电池)训练了SSD Mobilenet模型。下面给出了电池的示例图像,并且还附带了我用来训练模型的配置文件。
当物体离摄像机更近(通过网络摄像头测试)时,它可以准确地检测到物体,概率超过 0.95 ,但是当我将物体移到更长的距离时,它并没有被检测到。调试后,发现该对象被检测到,但可能性较低, 0.35 。最小阈值设置为0.5。如果将阈值0.5更改为0.2,则可以检测到物体,但是错误检测的次数会更多。
请参阅此link,SSD不能很好地用于小型对象,并且另一种解决方案是使用FasterRCNN,但是这种模型的实时性很慢。我也希望使用SSD也能从更远的距离检测电池。
请帮助我进行以下操作
答案 0 :(得分:4)
更改长宽比和比例将无助于提高小物体的检测精度(因为原始比例已经足够小,例如min_scale = 0.2
)。您需要更改的最重要的参数是feature_map_layout
。 feature_map_layout
确定要素图的数量(及其大小)及其对应的深度(通道)。但是遗憾的是,无法在pipeline_config文件中配置此参数,您必须直接在功能提取器中对其进行修改。
这就是为什么此feature_map_layout
对检测小物体很重要的原因。
在上图中,(b)和(c)是两个具有不同布局的特征图。地面真相图像中的狗与4x4特征图上的红色锚框匹配,而猫与8x8特征图上的蓝色锚框匹配。现在,如果您要检测的物体是猫的耳朵,那么将没有匹配该物体的锚框。 因此直觉是:如果没有锚框与某个对象匹配,则根本不会检测到该对象。要成功检测到猫的耳朵,您需要的可能是16x16特征图。
您可以在此处更改feature_map_layout
。在每个特定的特征提取器实现中都配置了此参数。假设您使用ssd_mobilenet_v1_feature_extractor
,则可以在this文件中找到它。
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个不同比例的特征图。前两层直接取自移动网络层(因此深度均为-1),而其余四层则来自额外的卷积运算。可以看出,最低级别的功能图来自移动网的Conv2d_11_pointwise
层。 通常,图层越低,要素地图的特征越细,检测小物体的效果越好。因此,您可以将此Conv2d_11_pointwise
更改为Conv2d_5_pointwise
(为什么呢?可以从tensorflow图中找到,该层的特征图比Conv2d_11_pointwise
层大),它应该有助于检测较小的对象
但是更好的准确性是要付出额外的代价的,这里额外的代价是检测速度会下降一点,因为有更多的锚盒需要照顾。 (更大的功能图)。同样,由于我们选择Conv2d_5_pointwise
而不是Conv2d_11_pointwise
,因此失去了Conv2d_11_pointwise
的检测能力。
如果您不想更改图层,而只需添加一个额外的要素贴图,例如使其总共具有7个功能图,则还必须将配置文件中的num_layers
更改为7。 您可以将此参数视为检测网络的分辨率,级别越低,分辨率就越好。
现在,如果您已执行上述操作,则还有另一件事需要帮助:添加带有小对象的更多图像。如果这样做不可行,至少您可以尝试添加诸如random_image_scale