RaggedTensor 的 TensorFlow 广播

use*_*276 5 python tensorflow tensorflow2.0

如何从参差不齐的张量中减去张量?

例子:

import tensorflow as tf    # TensorFlow 2.6

X = tf.ragged.constant([[[3, 1], [3]],
                        [[2], [3, 4]]], ragged_rank=2)
y = tf.constant([[1], [2]])
X-y
Run Code Online (Sandbox Code Playgroud)

预期结果:

[[[2, 0], [1]],
 [[1], [1, 2]]]
Run Code Online (Sandbox Code Playgroud)

但是,它返回一个错误:

tensorflow.python.framework.errors_impl.InvalidArgumentError: Expected 'tf.Tensor(False, shape=(), dtype=bool)' to be true. Summarized data: b'Unable to broadcast: dimension size mismatch in dimension'
1
b'lengths='
2
b'dim_size='
2, 2
Run Code Online (Sandbox Code Playgroud)

我知道我可以逐行完成:

tensorflow.python.framework.errors_impl.InvalidArgumentError: Expected 'tf.Tensor(False, shape=(), dtype=bool)' to be true. Summarized data: b'Unable to broadcast: dimension size mismatch in dimension'
1
b'lengths='
2
b'dim_size='
2, 2
Run Code Online (Sandbox Code Playgroud)

然而,这仅适用于急切模式 - 在图形模式下,我得到:

result = []
if X.shape[0] is not None:  # Placeholders have None everywhere -> range(None) raises an exception -> this condition
    for row in range(X.shape[0]):
        result.append(X[row] - y)
    result = tf.stack(result)
Run Code Online (Sandbox Code Playgroud)

因为代码只是有条件地执行......

有效的方法是对行数进行硬编码:

ValueError: No gradients provided for any variable
Run Code Online (Sandbox Code Playgroud)

但这并不能很好地概括。

我也知道我可以写:

for row in range(2):
    result.append(X[row] - y)
result = tf.stack(result)
Run Code Online (Sandbox Code Playgroud)

但这会返回“转置”y 的结果:

X - tf.expand_dims(y, axis=1)
Run Code Online (Sandbox Code Playgroud)

我也知道我还可以使用:

[[[2, 0], [2]],
 [[0], [1, 2]]]
Run Code Online (Sandbox Code Playgroud)

但是当在图形模式下使用结果时,我得到:

ValueError: Unable to broadcast: unknown rank
Run Code Online (Sandbox Code Playgroud)

小智 0

这对你有用吗?

x = tf.ragged.constant([[[3, 1], [3]],
                        [[2], [3, 4]]])  # shape(2,None,None)

x = tf.RaggedTensor.from_uniform_row_length(x.values, uniform_row_length=2) # shape(2,2,None)
Run Code Online (Sandbox Code Playgroud)

输出x - y

<tf.RaggedTensor [[[2, 0], [1]],
 [[1], [1, 2]]]>
Run Code Online (Sandbox Code Playgroud)

更好的方法是x从一开始就构建为等级 1 的张量

x = tf.ragged.constant([[3, 1], [3],
                        [2], [3, 4]], ragged_rank=1)  # shape(4,None)
x = tf.RaggedTensor.from_uniform_row_length(x, uniform_row_length=2)  # shape(2,2,None)
Run Code Online (Sandbox Code Playgroud)