TensorFlow broadcasting of RaggedTensor



如何从粗糙张量中减去一个张量?

的例子:

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

预期结果:

[[[2, 0], [1]],
[[1], [1, 2]]]
但是,它返回一个错误:

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

我知道我可以逐行执行:

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)

然而,这只适用于等待模式-在图形模式下,我得到:

ValueError: No gradients provided for any variable

因为代码只会有条件地执行…

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

for row in range(2):
result.append(X[row] - y)
result = tf.stack(result)

但这不能很好地概括。

我也知道我可以写:

X - tf.expand_dims(y, axis=1)

但是返回的结果是&;转置&;y:

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

我还知道我还可以使用:

def subtract(x):
return x - y
tf.map_fn(subtract, X)

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

ValueError: Unable to broadcast: unknown rank

要达到预期效果,请尝试以下操作:

X - tf.expand_dims(y, axis=2)

注意,我们只在原来的y上添加了tf.expand_dims(),它仍然是tf.constant([[1], [2]])

得到了以下期望的结果(在TF 2.6版本上测试):

<tf.RaggedTensor [[[2, 0], [2]], [[0], [1, 2]]]>

如下面的代码所示:
import tensorflow as tf # TensorFlow 2.6
print("TensorFlow version:", tf. version )
X = tf.ragged.constant([[[3, 1], [3]],
[[2], [3, 4]]], ragged_rank=2)
y = tf.constant([[1], [2]])
print(X-tf.expand_dims(y, axis=2))

与输出:

<tf.RaggedTensor [[[2, 0], [2]], [[0], [1, 2]]]> 

这对你有用吗?

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)

x - y输出

<tf.RaggedTensor [[[2, 0], [1]],
[[1], [1, 2]]]>

一种较好的方法是将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)

不幸的是,tf.RaggedTensors有点不稳定。

tldr;tf.RaggedTensortf.Tensor之间的操作并不总是如预期的那样。有时将tf.Tensor转换为tf.RaggedTensor也可以。

解决方案如下:X可以保持原样,

X = tf.ragged.constant([[[3, 1], [3]],
[[2], [3, 4]]], ragged_rank=2)
形状(X.shape)为[2, None, None]

解决方案接下来我们将y转换为tf.RaggedTensor,如下所示。

y = tf.ragged.constant(pylist=[[[1], [2]]], ragged_rank=1)

的形状(y.shape)为[1, None, 1]。,

X-y给出

<tf.RaggedTensor [[[2, 0], [1]], [[1], [1, 2]]]>

警告

对于yaragged_rank=2将导致以下错误:

InvalidArgumentError: Expected 'tf.Tensor(False, shape=(), dtype=bool)' to be true. Summarized data: b'Unable to broadcast: dimension size mismatch in dimension'
2
b'lengths='
1, 1, 1, 1
b'dim_size='
2, 1, 1, 2

我不完全理解。避免这种情况的最佳方法是尽可能多地固定维度。随着张量的维数增加,这个会变得更复杂。为此,您可以使用RaggedTensor结构,如from_uniform_row_length(此处和此处有更多信息)

相关内容

  • 没有找到相关文章

最新更新