首页 > 解决方案 > 可变批量大小张量的显式广播

问题描述

我正在尝试Layer在 Tensorflow 2.0RC 中实现自定义 Keras,并且需要将成形张量连接[None, Q][None, H, W, D]成形张量以产生[None, H, W, D + Q]成形张量。假设两个输入张量具有相同的批量大小,即使事先不知道。此外,H、W、D 和 Q 在写入时都不知道,但在build第一次调用层时在层的方法中进行评估。我遇到的问题是在将成形张量广播到[None, Q]成形张[None, H, W, Q]量以进行连接时。

这是一个尝试使用功能 API 创建 Keras 的示例,该 API 执行从 shape到 shapeModel的可变批量广播:[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

然后当我改变它-1None我:

TypeError: Failed to convert object of type <class 'list'> to Tensor. Contents: [None, 5, 5, 3]. Consider casting elements to a supported type.

如何执行指定的广播?

标签: pythonkerastensorflow2.0tf.keras

解决方案


您需要使用的动态形状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:形状和动态维度”


推荐阅读