如何在张量流中将多个 2dim 张量垂直连接成一个?

Jer*_*rry 0 python tensorflow

我想知道我们应该如何将多个不同形状的张量连接成 keras 中的一个张量。我尝试tf.keras.layers.concatenate如下:

import tensorflow as tf
from tf.keras.layers import concatenate

print(tensor_1.shape)
print(tensor_2.shape)

new_tensor = concatenate([tensor_1, tensor_2],axis=1)
new_tensor
Run Code Online (Sandbox Code Playgroud)

但我得到以下值错误:

shape of tensor_1 (?, 30, 30, 128)
shape of tensor_2 (?, 26, 26, 128)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-24-96d471a8e99e> in <module>()
----> 1 concatenate([tensor_1, tensor_2], axis=1)

4 frames
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/layers/merge.py in build(self, input_shape)
    517             shape[axis] for shape in shape_set if shape[axis] is not None)
    518         if len(unique_dims) > 1:
--> 519           raise ValueError(err_msg)
    520 
    521   def _merge_function(self, inputs):

ValueError: A `Concatenate` layer requires inputs with matching shapes except for the concat axis. Got inputs shapes: [(None, 30, 30, 128), (None, 26, 26, 128)]
Run Code Online (Sandbox Code Playgroud)

我认为在 Conv1D 中,连接很简单,在 Conv2D 中,我不知道如何进行连接。有谁知道如何在keras中做到这一点?任何想法?

更新

我还尝试将每个张量视为矩阵并尝试将它们连接起来:

tf.concat(0, [[tensor_1], [tensor_2]])
Run Code Online (Sandbox Code Playgroud)

但仍然,我最终遇到了类似的值错误,如下所示:

ValueError:两个形状中的维度 2 必须相等,但分别为 30 和 26。形状为 [1,?,30,30,128] 和 [1,?,26,26,128]。将形状 0 与其他形状合并。对于 '{{node concat/concat_dim}} = Pack[N=2, T=DT_INT32, axis=0](concat/concat_dim/0, concat/concat_dim/1)',输入形状: [1,?,30, 30,128], [1,?,26,26,128]。

期望的输出

我不确定如何连接多个张量,所以我可以将输出作为形状为 的张量 (W, H, C)。我们应该如何在 keras 中做到这一点?任何想法?

Wat*_*e.N 5

仅当两个张量具有相同的形状(但连接的轴除外)时,才可以连接它们。

x = np.arange(20).reshape(2, 2, 5)
y = np.arange(20, 30).reshape(2, 1, 5)
tf.keras.layers.concatenate([x, y], axis=1)  # (2, 3, 5)
Run Code Online (Sandbox Code Playgroud)

tf.keras.layers.concatenate

我建议您重新考虑整个网络,这样您就不必担心两个不同形状的张量。如果你做不到,我会说你

  1. 庄稼
x = np.arange(2*30*30*128).reshape(2, 30, 30, 128)
y = np.arange(2*26*26*128).reshape(2, 26, 26, 128)
x2 = tf.keras.layers.Cropping2D(cropping=((0, 0), (2, 2)))(x)
tf.keras.layers.concatenate([x2, y], axis=1)  # (2, 56, 26, 128)
Run Code Online (Sandbox Code Playgroud)

tf.keras.layers.Cropping2D

  1. 零垫
x = np.arange(2*30*30*128).reshape(2, 30, 30, 128)
y = np.arange(2*26*26*128).reshape(2, 26, 26, 128)
y = tf.keras.layers.ZeroPadding2D(padding=((0, 0), (2, 2)))(y)
tf.keras.layers.concatenate([x, y2], axis=1)  # (2, 56, 30, 128)
Run Code Online (Sandbox Code Playgroud)

tf.keras.layers.ZeroPadding2D

注意:tf.keras.layers.concatenatetf.keras.layers.Conatenate,继承自tf.keras.layers.Layer是不同的。

  • 您无法重塑,因为它们没有相同数量的元素,batchsize * 30*30*128 !== batchsize*26*26*128。您可以将零填充到 ```(?, 26, 26, 128)``` 来生成 ```(?, 30, 30, 128)```,或者您可以裁剪 ```(?, 30, 30, 128)``` 转换为 ```(?, 26, 26, 128)```。但我更想说的是,你必须重新考虑网络的整体结构。 (2认同)
  • 我不确定“数学上正确”是什么意思。但如果你不选择 2**N 维度,有时构建网络会很麻烦。比如你做U-Net的时候,你会一些Conv2D,一些Upsampling2D。当输入维度为256时,隐藏层将是256、128、64、129、256。但是如果输入255、255、127、63、126、252。你会看到输入和输出维度不同,你必须这样做与之匹配的东西。如果正确选择输入维度,您将无法工作。 (2认同)