可变批量张量的显式广播
Explicit broadcasting of variable batch-size tensor
我正在尝试在 Tensorflow 2.0RC 中实现自定义 Keras Layer
,并且需要将 [None, Q]
形张量连接到 [None, H, W, D]
形张量以生成 [None, H, W, D + Q]
形张量。假设两个输入张量具有相同的批量大小,即使事先不知道。此外,H、W、D 和 Q 的 none 在写入时已知,但在层首次调用时在层的 build
方法中进行评估。我遇到的问题是在将 [None, Q]
形张量广播到 [None, H, W, Q]
形张量以便连接时。
下面是一个尝试使用函数 API 创建 Keras Model
的示例,它执行从形状 [None, 3]
到形状 [None, 5, 5, 3]
的可变批次广播:
import tensorflow as tf
import tensorflow.keras.layers as kl
import numpy as np
x = tf.keras.Input([3]) # Shape [None, 3]
y = kl.Reshape([1, 1, 3])(x) # Need to add empty dims before broadcasting
y = tf.broadcast_to(y, [-1, 5, 5, 3]) # Broadcast to shape [None, 5, 5, 3]
model = tf.keras.Model(inputs=x, outputs=y)
print(model(np.random.random(size=(8, 3))).shape)
Tensorflow 产生错误:
InvalidArgumentError: Dimension -1 must be >= 0
然后当我将 -1
更改为 None
时,它会给我:
TypeError: Failed to convert object of type <class 'list'> to Tensor. Contents: [None, 5, 5, 3]. Consider casting elements to a supported type.
如何进行指定的广播?
您需要使用y
的动态形状来确定批量大小。张量 y
的动态形状由 tf.shape(y)
给出,它是一个表示 y
在运行时评估的形状的张量运算。修改后的示例通过在旧形状 [None, 1, 1, 3]
和使用 tf.where
.
的新形状之间进行选择来演示这一点
import tensorflow as tf
import tensorflow.keras.layers as kl
import numpy as np
x = tf.keras.Input([3]) # Shape [None, 3]
y = kl.Reshape([1, 1, 3])(x) # Need to add empty dims before broadcasting
# Retain the batch and depth dimensions, but broadcast along H and W
broadcast_shape = tf.where([True, False, False, True],
tf.shape(y), [0, 5, 5, 0])
y = tf.broadcast_to(y, broadcast_shape) # Broadcast to shape [None, 5, 5, 3]
model = tf.keras.Model(inputs=x, outputs=y)
print(model(np.random.random(size=(8, 3))).shape)
# prints: "(8, 5, 5, 3)"
参考文献:
我正在尝试在 Tensorflow 2.0RC 中实现自定义 Keras Layer
,并且需要将 [None, Q]
形张量连接到 [None, H, W, D]
形张量以生成 [None, H, W, D + Q]
形张量。假设两个输入张量具有相同的批量大小,即使事先不知道。此外,H、W、D 和 Q 的 none 在写入时已知,但在层首次调用时在层的 build
方法中进行评估。我遇到的问题是在将 [None, Q]
形张量广播到 [None, H, W, Q]
形张量以便连接时。
下面是一个尝试使用函数 API 创建 Keras Model
的示例,它执行从形状 [None, 3]
到形状 [None, 5, 5, 3]
的可变批次广播:
import tensorflow as tf
import tensorflow.keras.layers as kl
import numpy as np
x = tf.keras.Input([3]) # Shape [None, 3]
y = kl.Reshape([1, 1, 3])(x) # Need to add empty dims before broadcasting
y = tf.broadcast_to(y, [-1, 5, 5, 3]) # Broadcast to shape [None, 5, 5, 3]
model = tf.keras.Model(inputs=x, outputs=y)
print(model(np.random.random(size=(8, 3))).shape)
Tensorflow 产生错误:
InvalidArgumentError: Dimension -1 must be >= 0
然后当我将 -1
更改为 None
时,它会给我:
TypeError: Failed to convert object of type <class 'list'> to Tensor. Contents: [None, 5, 5, 3]. Consider casting elements to a supported type.
如何进行指定的广播?
您需要使用y
的动态形状来确定批量大小。张量 y
的动态形状由 tf.shape(y)
给出,它是一个表示 y
在运行时评估的形状的张量运算。修改后的示例通过在旧形状 [None, 1, 1, 3]
和使用 tf.where
.
import tensorflow as tf
import tensorflow.keras.layers as kl
import numpy as np
x = tf.keras.Input([3]) # Shape [None, 3]
y = kl.Reshape([1, 1, 3])(x) # Need to add empty dims before broadcasting
# Retain the batch and depth dimensions, but broadcast along H and W
broadcast_shape = tf.where([True, False, False, True],
tf.shape(y), [0, 5, 5, 0])
y = tf.broadcast_to(y, broadcast_shape) # Broadcast to shape [None, 5, 5, 3]
model = tf.keras.Model(inputs=x, outputs=y)
print(model(np.random.random(size=(8, 3))).shape)
# prints: "(8, 5, 5, 3)"
参考文献: