【问题标题】:Error with tensorflow map_fn. Unable to specify output signaturetensorflow map_fn 出错。无法指定输出签名
【发布时间】:2022-01-19 05:00:52
【问题描述】:

我正在尝试使用 tensorflow 的 tf.map_fn 来映射一个参差不齐的张量,但我遇到了一个无法修复的错误。 这是一些演示错误的最小代码:

import tensorflow as tf

X = tf.ragged.constant([[0,1,2], [0,1]])
def outer_product(x):
  return x[...,None]*x[None,...]
tf.map_fn(outer_product, X)

我想要的输出是:

tf.ragged.constant([
 [[0, 0, 0],
  [0, 1, 2],
  [0, 2, 4]],
 [[0, 0],
  [0, 1]]
])

我得到的错误是:

“InvalidArgumentError:所有 flat_values 必须具有兼容的形状。 索引 0 处的形状:[3]。索引 1 处的形状:[2]。如果您正在使用 tf.map_fn,那么您可能需要指定一个显式 具有适当 ragged_rank 的 fn_output_signature,和/或转换 将张量输出到 RaggedTensors。 [Op:RaggedTensorFromVariant]"

我意识到我需要指定 fn_output_signature,但尽管进行了实验,但我无法弄清楚它应该是什么。

编辑:我稍微清理了 AloneTogether 的出色答案,并创建了一个映射参差不齐的张量的函数。他的回答使用tf.ragged.stack 函数将张量转换为tf.map_fn 出于某种原因需要的参差不齐的张量

def ragged_map_fn(func, t): 
  def new_func(t):
    return tf.ragged.stack(func(t),0)
  signature = tf.type_spec_from_value(new_func(t[0]))
  ans = tf.map_fn(new_func, t, fn_output_signature=signature)
  ans = tf.squeeze(ans, 1)
  return ans

【问题讨论】:

    标签: python tensorflow tensorflow2.0 tensor ragged-tensors


    【解决方案1】:

    参差不齐的张量有时真的很棘手。这是您可以尝试的一种选择:

    import tensorflow as tf
    
    X = tf.ragged.constant([
                            [0,1,2], 
                            [0,1]
                           ])
    def outer_product(x):
      t = x[...,None] * x[None,...]
      return tf.ragged.stack(t)
    
    
    y = tf.map_fn(outer_product, X, fn_output_signature=tf.RaggedTensorSpec(shape=[1, None, None],
                                                                        dtype=tf.type_spec_from_value(X).dtype,
                                                                        ragged_rank=2,
                                                                        row_splits_dtype=tf.type_spec_from_value(X).row_splits_dtype))
    tf.print(y)
    #y = tf.concat([y[0, :], y[1, :]], axis=0) # Remove additional dimension from Ragged Tensor
    y = y.merge_dims(0, 1)
    tf.print(y)
    
    [
     [
      [
       [0, 0, 0], 
       [0, 1, 2], 
       [0, 2, 4]
      ]
     ], 
     [
      [
       [0, 0], 
       [0, 1]
      ]
     ]
    ]
    

    在使用y.merge_dims(0, 1)tf.concat 删除附加维度后:

    [
     [
      [0, 0, 0], 
      [0, 1, 2], 
      [0, 2, 4]
     ], 
     [
      [0, 0], 
      [0, 1]
     ]
    ]
    

    【讨论】:

    • 感谢您的回答!我希望了解您是如何得出这个解决方案的。我注意到您在 outer_product 函数中添加了一个参差不齐的堆栈。这是因为我需要将张量转换为参差不齐的张量吗?我还能够删除 row_splits_dtype=tf.type_spec_from_value(X).row_splits_dtype 并且代码仍然有效,您包含它有什么原因吗?
    • 是的,确实,但使用tf.RaggedTensor 将不起作用,因为tf.map_fn 需要这个“额外”维度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多