【问题标题】:Custom layer with Keras and Tensorflow使用 Keras 和 Tensorflow 的自定义层
【发布时间】:2021-10-20 09:51:53
【问题描述】:

我正在使用 Keras 和 Tensorflow 构建一个自定义层,用于计算一组框之间的交集。 a有两组具有不同尺寸的anchors和gt_boxes,我将计算anchors和gt_boxes中每个元素之间的交集 当我执行代码时出现以下错误:

Use fn_output_signature instead
Traceback (most recent call last):
  File "acceuil.py", line 60, in <module>
    train(train_data[1], val_data[1], dataset_name)
  File "acceuil.py", line 28, in train
    model.train()
  File "/home/imene/APP-M/ROI/mod.py", line 40, in train
    inputs, outputs =   self.worker() 
  File "/home/imene/APP-M/ROI/mod.py", line 135, in worker
    iou_anchors = ioulayer([tf_rois, tf_anchors])
  File "/home/imene/anaconda3/envs/master/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer_v1.py", line 786, in __call__
    outputs = call_fn(cast_inputs, *args, **kwargs)
  File "/home/imene/anaconda3/envs/master/lib/python3.6/site-packages/tensorflow/python/autograph/impl/api.py", line 670, in wrapper
    raise e.ag_error_metadata.to_exception(e)
ValueError: in user code:

    /home/imene/APP-M/ROI/IoULayer.py:25 call  *
        IoU_anchors = tf.map_fn(compute_IoU, (inputs[0], inputs[1] ), dtype=tf.float32)
    /home/imene/anaconda3/envs/master/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py:538 new_func  **
        return func(*args, **kwargs)
    /home/imene/anaconda3/envs/master/lib/python3.6/site-packages/tensorflow/python/ops/map_fn.py:451 map_fn
        tensor.get_shape().with_rank_at_least(1)[0])))
    /home/imene/anaconda3/envs/master/lib/python3.6/site-packages/tensorflow/python/framework/tensor_shape.py:315 merge_with
        self.assert_is_compatible_with(other)
    /home/imene/anaconda3/envs/master/lib/python3.6/site-packages/tensorflow/python/framework/tensor_shape.py:282 assert_is_compatible_with
        (self, other))

    ValueError: Dimensions 3 and 10 are not compatible

这是我的自定义层的代码,用python编写的:

import sys
import numpy as np 
import keras
from tensorflow.keras.layers import Layer
from tensorflow.python.keras.backend import map_fn

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

class IoULayer(Layer):
    def __init__(self, **kwargs):
        super(IoULayer, self).__init__(**kwargs)
        
        
# -------------------------------------------------------------------------------------------------
    def call(self, inputs):
        '''
        inputs[0]: ground truth boxes
        inputs[1]: anchors boxes
        '''    
        def compute_IoU(inputs):
            
            return IoULayer.multiple_IoU(inputs[0], inputs[1])

        IoU_anchors = tf.map_fn(compute_IoU, (inputs[0], inputs[1] ), dtype=tf.float32)
        
        return IoU_anchors

    def multiple_IoU(gt_boxes, anchors):

        def get_anchor_IoUs(gt_boxes, anchor):
            
            return IoULayer.get_single_IoU(gt_boxes, anchor)

        IoU = tf.map_fn(get_anchor_IoUs, gt_boxes, anchors, dtype=tf.float32)
        return IoU

    def get_single_IoU(gt_boxes, anchors):
        iou_list = []
        
        def single_iou(anchor):
            result = []
            for gt_bbx in gt_boxes:
                
                x_left   = max(gt_bbx[0], anchor[0])
                y_top    = max(gt_bbx[1], anchor[1])
                x_right  = min(gt_bbx[2], anchor[2])
                y_bottom = min(gt_bbx[3], anchor[3])

                bb1_area = (gt_bbx[2]- gt_bbx[0])*(gt_bbx[3]- gt_bbx[1])
                anchor_area = (anchor[2]- anchor[0])*(anchor[3]- anchor[1])

                intersect_area = abs(max((x_right - x_left), 0) * max((y_bottom - y_top),0))
                iou = intersect_area / float(bb1_area + anchor_area - intersect_area)
                result.append(iou)
                return result
        iou_list = tf.stack(single_iou(anchor) for anchor in anchors)
        return iou_list

我不明白是什么问题? 谢谢回复

【问题讨论】:

  • 看起来您的图层可能输出的数据维度与其输入的图层不兼容。您能提供模型架构代码吗?
  • 目前,我没有模型架构。我只是执行这一层,我想得到它的输出。我这样称呼图层: ioulayer = IoULayer() iou_anchors = ioulayer([tf_rois, tf_anchors]) print(iou_anchors)

标签: python tensorflow keras deep-learning layer


【解决方案1】:

问题可能出在您输入的维度上。来自tf.map_fn documentation

如果 elems 是张量的元组(或嵌套结构),那么这些张量必须都具有相同的外维大小(num_elems); fn 用于从 elems 转换相应切片的每个元组(或结构)。例如,如果 elems 是一个元组 (t1, t2, t3),则 fn 用于转换切片的每个元组 (t1[i], t2[i], t3[i])(其中 0

因此,在您的情况下,如果 tf_roistf_anchors 具有不同的维度(例如 3 和 10),fn_map 将失败,因为较小张量中没有足够的元素与较大的张量元素配对。

如果您需要针对两个张量的所有排列运行您的函数,您需要找到这些组合并将两个相同大小的张量作为elems 输入fn_map

编辑:有关组合的更多详细信息。

您可以找到所有成对组合,而不是将两个原始张量提供给 tf.map_fn,所以如果您的张量如下所示:

tensor_1 = [1, 2, 3]
tensor_2 = [100, 200, 300]

成对组合的张量如下所示:

pairwise_combinations = [
    [1, 100],
    [1, 200],
    [1, 300], 
    [2, 100],
    [2, 200],
    [2, 300],
    [3, 100],
    [3, 200],
    [3, 300]
]

现在您可以将此张量的列作为相同大小的elems 提供给map_fn

关于找到这些组合的实际方法,这里有一个 link 和一个 tensorflow 示例,here 是它可以在 python 标准库中完成的方法。希望对您有所帮助!

【讨论】:

  • 感谢重播,你说得对,两个张量的大小不同,我别无选择。一定是这样的。除了 map_fn 之外,还有什么函数可以让我在不同大小的张量上映射函数?
  • 我认为您不需要找到不同的函数,您只需将正确的参数提供给tf.map_fn。如果要检查框和锚点的所有组合,首先需要找到这些组合,然后将它们提供给映射。我现在会更新答案
  • 好主意的坦克
猜你喜欢
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-05
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 2021-08-02
相关资源
最近更新 更多