任务:
我正在尝试将通过 Tensorflow 对象检测 API 训练和导出的模型集成到一个更大的图形中,该图形会将模型结果转换为检测掩码;本质上是与输入图像具有相同(高度 x 宽度)尺寸的 float32 张量,其中每个值反映了模型对相应像素位于检测到的对象的边界框内的置信度。这与分割网络的输出非常相似,除了我要查找的输出不是维度(高度 x 宽度 x num_classes),而是维度(高度 x 宽度),好像只有一个类被检测。我想完全在 Tensorflow 图中完成此操作。
我如何尝试完成它:
我正在尝试使用 tf.boolean_mask() 和 tf.foldl() 从检测模型返回的框边界增量构建掩码。请注意,在此示例中,掩码值是二进制的;为了让问题保持简单,我取出了通过检测置信度来衡量结果的代码。
def __init__(self, graph_protobuf, threshold=0.6):
#Import code omitted...
#Grab the model detection results:
boxes = tf.squeeze(detection_graph.get_tensor_by_name('detection_boxes:0'), axis=0)
scores = tf.squeeze(detection_graph.get_tensor_by_name('detection_scores:0'), axis=0)
classes = tf.squeeze(detection_graph.get_tensor_by_name('detection_classes:0'), axis=0)
num_detect = detection_graph.get_tensor_by_name('num_detections:0')
#Only consider boxes above a provided threshold:
over_threshold = tf.greater(scores, threshold)
detections = tf.logical_and(over_threshold, tf.equal(classes, 1))
#Debugging: Print out what the model result dimensions are.
test = detection_graph.get_tensor_by_name('detection_scores:0')
print("Shape of mask: {} Shape of scores: {} Shape of classes: {} Raw score shape: {}".format(str(detections.shape), str(scores.shape), str(classes.shape), str(test.shape)))
print("Boxes: {}".format(str(test)))
#Remove under-threshold results:
detection_boxes = tf.boolean_mask(boxes, detections)
#Build the mask:
self.result = tf.foldl(processBox, detection_boxes, initializer=tf.zeros([720,1280]))
def processBox(self, res, box):
res[box[0]:box[2],box[1]:box[3]].assign(tf.ones(((box[2]-box[0]),(box[3]-box[1]))))
问题:
我认为 Tensorflow 遇到了模型返回的未知数量的框的问题。这是尝试使用此图表的结果:
Shape of mask: <unknown> Shape of scores: <unknown> Shape of classes: <unknown> Raw score shape: <unknown>
Boxes: Tensor("detection_scores:0", dtype=float32)
<...uninteresting stack trace omitted...>
File "/home/username/.local/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py", line 1121, in boolean_mask
"Number of mask dimensions must be specified, even if some dimensions"
ValueError: Number of mask dimensions must be specified, even if some dimensions are None. E.g. shape=[None] is ok, but shape=None is not.
这是对 tf.boolean_mask() 的抱怨。如您所见,在运行时我根本无法获取模型输出尺寸。tf.boolean_mask() 与 tf.constants 作为输入一起工作得很好,所以这让我得出结论,这种方法可能存在一些基本问题。
有没有办法使这种方法起作用?如果不是,那么构建我正在寻找的掩码结果的正确方法是什么?