在我的网络中,两个子模型预测了2个单独的张量,它们分别是2个对象的边界框。我需要将这两组边界框张量合并为一个包含2个边界框的张量。
以下是我的尝试。 p_outputs是来自一个子模型的一个张量,而l_outputs是来自另一个子模型的另一个张量。它们已经通过NMS运行,因此根据p_outputs和l_outputs的分数对边界框进行了排序。
outputs = backend.map_fn(
_merge_panel_label,
elems=p_outputs + l_outputs,
dtype=[keras.backend.floatx()] + [keras.backend.floatx()],
parallel_iterations=self.parallel_iterations
)
def _merge_panel_label(args):
p_boxes = args[0]
l_boxes = args[1]
return merge_panel_label(p_boxes, l_boxes, self.merge_max_detections)
实际的合并逻辑在下面实现。基本上,对于p_output中的每个项目p_output来说,这非常简单,我只想从p_output中的l_boxes中选择得分最高的项目。
def merge_panel_label(p_boxes,l_boxes,max_detections):
def _merge_panel_label(p_box):
p_x1 = p_box[0]
p_y1 = p_box[1]
p_x2 = p_box[2]
p_y2 = p_box[3]
l_x1 = l_boxes[:, 0]
l_y1 = l_boxes[:, 1]
l_x2 = l_boxes[:, 2]
l_y2 = l_boxes[:, 3]
condition1 = keras.backend.greater_equal(l_x1, p_x1) # l_x1 >= p_x1
condition2 = keras.backend.greater(l_x2, p_x1) # l_x2 >= p_x1
condition3 = keras.backend.greater_equal(l_y1, p_y1) # l_y1 >= p_y1
condition4 = keras.backend.greater(l_y2, p_y1) # l_y2 >= p_y1
condition5 = keras.backend.less(l_x1, p_x2) # l_x1 <= p_x2
condition6 = keras.backend.less_equal(l_x2, p_x2) # l_x2 <= p_x2
condition7 = keras.backend.less(l_y1, p_y2) # l_y1 <= p_y2
condition8 = keras.backend.less_equal(l_y2, p_y2) # l_y2 <= p_y2
inside_flag = condition1
inside_flag = backend.logical_and(inside_flag, condition2)
inside_flag = backend.logical_and(inside_flag, condition3)
inside_flag = backend.logical_and(inside_flag, condition4)
inside_flag = backend.logical_and(inside_flag, condition5)
inside_flag = backend.logical_and(inside_flag, condition6)
inside_flag = backend.logical_and(inside_flag, condition7)
inside_flag = backend.logical_and(inside_flag, condition8)
indices = backend.where(inside_flag)
return indices # we just pick the top one
inside_indices = backend.map_fn(
_merge_panel_label,
elems=p_boxes,
dtype='int64'
)
# collect label candidate based on indices
l_boxes = keras.backend.gather(l_boxes, inside_indices[:, 0, 0])
# zero pad the outputs
pad_size = keras.backend.maximum(0, max_detections - keras.backend.shape(p_scores)[0])
p_boxes = backend.pad(p_boxes, [[0, pad_size], [0, 0]], constant_values=-1)
l_boxes = backend.pad(l_boxes, [[0, pad_size], [0, 0]], constant_values=-1)
# set shapes, since we know what they are
p_boxes.set_shape([max_detections, 4])
l_boxes.set_shape([max_detections, 4])
return [p_boxes, l_boxes]
在模型编译和训练期间没有错误。但是,当我运行预测时,出现以下错误消息:
tensorflow.python.framework.errors_impl.UnimplementedError: TensorArray的大小为零,但元素形状[?,1]并不完全 定义。目前仅在包装时支持静态形状 零大小的TensorArrays。
我认为这是因为对于某些p_output,没有l_output。在某些情况下,l_outputs的大小可能为0。如何解决此问题?确实非常感谢。