Keras / TensorFlow在特定条件下结合2个张量

时间:2018-07-25 19:06:49

标签: tensorflow keras tensor

在我的网络中,两个子模型预测了2个单独的张量,它们分别是2个对象的边界框。我需要将这两组边界框张量合并为一个包含2个边界框的张量。

以下是我的尝试。 p_outputs是来自一个子模型的一个张量,而l_o​​utputs是来自另一个子模型的另一个张量。它们已经通过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。如何解决此问题?确实非常感谢。

0 个答案:

没有答案
相关问题