TF2 / Keras 切片张量使用 [:, :, 0]

Nic*_*Nic 8 python deep-learning keras tensorflow tensorflow2.0

在 TF 2.0 Beta 中,我正在尝试:

x = tf.keras.layers.Input(shape=(240, 2), dtype=tf.float32)
print(x.shape) # (None, 240, 2)
a = x[:, :, 0]
print(a.shape) # <unknown>
Run Code Online (Sandbox Code Playgroud)

在 TF 1.x 中,我可以这样做:

x = tf1.placeholder(tf1.float32, (None, 240, 2)
a = x[:, :, 0]
Run Code Online (Sandbox Code Playgroud)

它会正常工作。我如何在 TF 2.0 中实现这一点?我认为

tf.split(x, 2, axis=2)
Run Code Online (Sandbox Code Playgroud)

可能有用,但是我想使用切片而不是硬编码 2(轴 2 的尺寸)。

Ste*_*t_R 5

不同之处在于返回的对象Input代表一个层,而不是任何类似于占位符或张量的东西。因此,x上面 tf 2.0 代码中的 是一个图层对象,而xtf 1.x 代码中的 是张量的占位符。

您可以定义切片层来执行操作。有现成可用的层,但是,对于像这样的简单切片,Lambda层非常容易阅读,并且可能最接近您在 tf 1.x 中用于切片的方式。

像这样的东西:

input_lyr = tf.keras.layers.Input(shape=(240, 2), dtype=tf.float32)
sliced_lyr = tf.keras.layers.Lambda(lambda x: x[:,:,0])
Run Code Online (Sandbox Code Playgroud)

您可以在您的 keras 模型中使用它,如下所示:

model = tf.keras.models.Sequential([
    input_lyr,
    sliced_lyr,
    # ...
    # <other layers>
    # ...
])

Run Code Online (Sandbox Code Playgroud)

当然,以上是特定于keras模型的。相反,如果您有一个张量而不是 keras 层对象,那么切片的工作方式与以前完全一样。像这样的东西:

my_tensor = tf.random.uniform((8,240,2))
sliced = my_tensor[:,:,0]

print(my_tensor.shape)
print(sliced.shape)
Run Code Online (Sandbox Code Playgroud)

输出:

(8, 240, 2)
(8, 240)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样