【问题标题】:Non Max Suppression settings and postprocessing for EfficientDetEfficientDet 的非最大抑制设置和后处理
【发布时间】:2021-05-04 00:30:02
【问题描述】:

我已经下载并安装了 Tensorflow 对象检测 API 并下载了一个 EfficientDet models. 因为我想在非最大抑制将原始分数降低为类输出之前直接对原始分数做一些工作,所以我的第一个目标是使用下载的模型配置作为指导,尝试从原始分数中获得相同的最终输出。

    post_processing {
      batch_non_max_suppression {
        score_threshold: 9.99999993922529e-09
        iou_threshold: 0.5
        max_detections_per_class: 100
        max_total_detections: 100
      }
      score_converter: SIGMOID

由于Object Detection API在后处理下没有分数转换器方法,我不确定这是做什么的,但utils中唯一的批处理NMS方法似乎是batch_multiclass_non_max_suppression

因此,将图像输入网络并获得输出检测,以尝试复制其结果:

    result = post_processing.batch_multiclass_non_max_suppression(tf.expand_dims(detections['raw_detection_boxes'], 2), detections['raw_detection_scores'], 9.99999993922529e-09, 0.5, 100, max_total_size=100)
    detections['detection_boxes'] = result[0]
    detections['detection_scores'] = result[1]
    detections['detection_classes'] = result[2]

即将检测中的相关分数替换为 NMS 的输出,并插入批处理功能工作所需的维度。然后在per the TensorFlow Hub colab 之后对其进行可视化。

问题在于,虽然输入图像(来自 MSCOCO 数据集)应该生成以下图像:

它会产生这个:

边界框全部(似乎)向上移动,类别完全关闭,这表明在原始分数、NMS 和输出之间进行了更多处理,但完全不清楚是什么。分数是正确的,所以看起来修剪正确。

编辑:我怀疑,在查看 SSD 模型模板后,未对齐边界框的问题是因为我没有将调整大小的图像尺寸传递给 NMS,这是由预处理步骤,这应该很容易通过生成图像调整大小函数来解决。但是,在应用切片操作删除背景类后,并没有解决不正确的标签:

相反,它似乎完全失去了 person 类——这是有道理的;它未配置为包含任何类型的背景类,如果 Person (id 1) 以索引 0 的形式出现,那么这将切断它们。

编辑 2:我进一步查看了原始元架构并复制了图像大小调整功能,即:

from object_detection.protos import image_resizer_pb2
from object_detection.utils import config_util as c
from object_detection.utils import shape_utils

config =  c.get_configs_from_pipeline_file(r"C:\Users\Person\.keras\datasets\efficientdet_d7_coco17_tpu-32\pipeline.config")
image_config = c.get_image_resizer_config(config['model'])
resize = image_resizer_builder.build(image_config)

def compute_clip_window(preprocessed_images, true_image_shapes):
# identical to the meta-arch definition

# image resizing 
im = tf.cast(input_tensor, tf.float32)
channel_offset = [0.485, 0.456, 0.406]
channel_scale = [0.229, 0.224, 0.225]
im = ((im / 255.0) - [[channel_offset]]) / [[channel_scale]]
resized = shape_utils.resize_images_and_return_shapes(im, resize)

clip = compute_clip_window(resized[0], resized[1])

因此允许将剪辑参数提供给 NMS。但是,这并没有改变任何东西,它仍然返回与第二张图像相同的未对齐框。这令人难以置信的混乱,因为这似乎应该复制模型在预处理和后处理步骤中所需的一切以生成自己的输出:图像被标准化和调整大小;真实图像大小与调整大小的图像一起保留;在将原始框或原始分数传递给 NMS 之前,不会对其进行进一步处理(原始值的返回版本与传递给 NMS 的值相同,除了一维 and the model itself 不会干扰后处理完全没有——调用签名依次调用预处理、预测和后处理,因此在此期间不应发生任何其他事情。

编辑 3: 我添加了另一行(无效)——将 NMS 附加字段中的多类分数设置为具有背景的检测分数(即原始分数)。通过为所有标签类添加+1,我得到了以下图像:

虽然这是正确的,但这仅适用于数据集的早期部分,即唯一的空类是第 0 个。似乎仍然有一些我没有遵循的映射步骤,以及导致图像错位的任何原因。

【问题讨论】:

    标签: tensorflow object-detection object-detection-api


    【解决方案1】:

    就我而言,最简单的解决方案是从检查点和配置加载模型,而不是直接使用保存的模型,以便访问原始的预处理、预测和后处理方法,而不是使用单个函数调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      • 2011-10-19
      • 2014-07-22
      • 1970-01-01
      • 2013-03-25
      • 2015-05-17
      • 1970-01-01
      相关资源
      最近更新 更多