Python 连接不同形状的keras层输出

Python 连接不同形状的keras层输出,python,keras,keras-layer,Python,Keras,Keras Layer,keras模型如下所示: input_x = Input(shape=input_shape) x=Conv2D(...)(input_x) ... y_pred1 = Conv2D(...)(x) # shape of (None, 80, 80, 2) y_pred2 = Dense(...)(x) # shape of (None, 4) y_merged = Concatenate(...)([y_pred1, y_pred2]) model = Model(input_x,

keras模型如下所示:


input_x = Input(shape=input_shape)

x=Conv2D(...)(input_x)
...
y_pred1 = Conv2D(...)(x) # shape of (None, 80, 80, 2)
y_pred2 = Dense(...)(x) # shape of (None, 4)

y_merged = Concatenate(...)([y_pred1, y_pred2])


model = Model(input_x, y_merged)
input_x = Input(shape=input_shape)
x=Conv2D(...)(input_x)
...
y_pred1 = Conv2D(...)(x) # shape of (None, 80, 80, 2)

y_pred2 = Dense(4)(x) # (None, 4)

# =========transform to concatenate:===========
y_pred2_matrix = Lambda(lambda x: K.expand_dims(K.expand_dims(x, -1)))(y_pred2) # (None,4, 1,1)

y_pred2_matrix = ZeroPadding2D(padding=((0,76),(0,79)))(y_pred2_matrix) # (None, 80, 80,1)

y_merged = Concatenate(axis=-1)([y_pred1, y_pred2_matrix]) # (None, 80, 80, 3)
y_pred1
y_pred2
是我希望模型学习预测的结果

但是
y_pred1
分支的损失函数
fcn1
需要
y_pred2
预测结果,因此我必须将两个分支的结果串联起来,以获得
y_merged
,这样
fcn1
将可以访问
y_pred2

问题是,我想使用
Concatenate
层将
y_pred1(None,4)
输出与
y_pred2(None,80,80,2)
输出连接起来,但我不知道怎么做

如何将
(无,4)
重塑为
(无,80,80,1)
?例如,用
y_pred2
中的4个元素和零填充
(无、80、80、1)


有没有比使用
连接层更好的解决方案?

也许这段提取的代码可以帮助您:

tf.print(condi_input.shape)
# shape is TensorShape([None, 1])
condi_i_casted = tf.expand_dims(condi_input, 2)
tf.print(condi_i_casted.shape)
# shape is TensorShape([None, 1, 1])
broadcasted_val = tf.broadcast_to(condi_i_casted, shape=tf.shape(decoder_outputs))
tf.print(broadcasted_val.shape)
# shape is TensorShape([None, 23, 256])
当您想要广播一个值时,首先考虑您到底想要广播什么。在本例中,condi_输入具有
形状(None,1)
,并作为编码器-解码器lstm网络的条件帮助我。为了匹配lstm编码器状态的所有维度,首先我必须使用
tf.expand_dims()
将条件值从类似
[[1]]
的形状扩展到
[[1]]

这是你首先需要做的。如果您有一个来自密集层的softmax预测,您可能希望首先使用
tf.argmax()
,因此您只有一个值,这更容易广播。但是,也可以使用4,但请记住,尺寸需要匹配。您不能将
形状(无,4)
广播到
形状(无,6)
,而是广播到
形状(无,8)
,因为8可以通过4进行区分

然后可以使用
tf.broadcast()
将值广播到所需的形状中。然后有两个形状,可以连接在一起。
希望这对您有所帮助。

也许这段提取的代码可以帮助您:

tf.print(condi_input.shape)
# shape is TensorShape([None, 1])
condi_i_casted = tf.expand_dims(condi_input, 2)
tf.print(condi_i_casted.shape)
# shape is TensorShape([None, 1, 1])
broadcasted_val = tf.broadcast_to(condi_i_casted, shape=tf.shape(decoder_outputs))
tf.print(broadcasted_val.shape)
# shape is TensorShape([None, 23, 256])
当您想要广播一个值时,首先考虑您到底想要广播什么。在本例中,condi_输入具有
形状(None,1)
,并作为编码器-解码器lstm网络的条件帮助我。为了匹配lstm编码器状态的所有维度,首先我必须使用
tf.expand_dims()
将条件值从类似
[[1]]
的形状扩展到
[[1]]

这是你首先需要做的。如果您有一个来自密集层的softmax预测,您可能希望首先使用
tf.argmax()
,因此您只有一个值,这更容易广播。但是,也可以使用4,但请记住,尺寸需要匹配。您不能将
形状(无,4)
广播到
形状(无,6)
,而是广播到
形状(无,8)
,因为8可以通过4进行区分

然后可以使用
tf.broadcast()
将值广播到所需的形状中。然后有两个形状,可以连接在一起。
希望这对您有所帮助。

解决了这个问题,代码如下:


input_x = Input(shape=input_shape)

x=Conv2D(...)(input_x)
...
y_pred1 = Conv2D(...)(x) # shape of (None, 80, 80, 2)
y_pred2 = Dense(...)(x) # shape of (None, 4)

y_merged = Concatenate(...)([y_pred1, y_pred2])


model = Model(input_x, y_merged)
input_x = Input(shape=input_shape)
x=Conv2D(...)(input_x)
...
y_pred1 = Conv2D(...)(x) # shape of (None, 80, 80, 2)

y_pred2 = Dense(4)(x) # (None, 4)

# =========transform to concatenate:===========
y_pred2_matrix = Lambda(lambda x: K.expand_dims(K.expand_dims(x, -1)))(y_pred2) # (None,4, 1,1)

y_pred2_matrix = ZeroPadding2D(padding=((0,76),(0,79)))(y_pred2_matrix) # (None, 80, 80,1)

y_merged = Concatenate(axis=-1)([y_pred1, y_pred2_matrix]) # (None, 80, 80, 3)

y_pred2的4个元素可以被索引为
y_merged[None,:4,0,2]
算出它,代码如下:


input_x = Input(shape=input_shape)

x=Conv2D(...)(input_x)
...
y_pred1 = Conv2D(...)(x) # shape of (None, 80, 80, 2)
y_pred2 = Dense(...)(x) # shape of (None, 4)

y_merged = Concatenate(...)([y_pred1, y_pred2])


model = Model(input_x, y_merged)
input_x = Input(shape=input_shape)
x=Conv2D(...)(input_x)
...
y_pred1 = Conv2D(...)(x) # shape of (None, 80, 80, 2)

y_pred2 = Dense(4)(x) # (None, 4)

# =========transform to concatenate:===========
y_pred2_matrix = Lambda(lambda x: K.expand_dims(K.expand_dims(x, -1)))(y_pred2) # (None,4, 1,1)

y_pred2_matrix = ZeroPadding2D(padding=((0,76),(0,79)))(y_pred2_matrix) # (None, 80, 80,1)

y_merged = Concatenate(axis=-1)([y_pred1, y_pred2_matrix]) # (None, 80, 80, 3)

y_pred2的4个元素可以被索引为
y_merged[None,:4,0,2]

无法对其进行重塑。也许你可以接受一些线性投影?或者你想要一个可训练的非线性投影——例如解码器网络?这取决于你的特点和你想要实现什么。您可以将conv2D层展平为
(无,80*80*2)
。您还可以广播密集层的输出,以匹配conv2D层的维度。@MateenUlhaq
(无,4)
(无,80,80,2)
是我的模型中两个预测头的输出,我想将它们连接起来,因此,一个预测头的损失函数可以使用另一个预测头的
y_pred
。所以我在想也许我可以把
(None,4)
改成
(None,80,80,1)
,在
(None,80,80,1)
中填充
(None,4)
中的4个元素和零。但我不知道怎么做,也不知道是否有更好的解决方案。@MichaelJanz正如我前面解释的,这两个张量是我的模型中两个预测头的输出,我希望连接的张量是我的最终模型输出。你能帮我广播密集层的输出吗,或者你有更好的解决方案吗?你打算如何处理连接的数据?有很多合理的方法可以做到这一点,但有些表示法更容易训练,无法重塑它。也许你可以接受一些线性投影?或者你想要一个可训练的非线性投影——例如解码器网络?这取决于你的特点和你想要实现什么。您可以将conv2D层展平为
(无,80*80*2)
。您还可以广播密集层的输出,以匹配conv2D层的维度。@MateenUlhaq
(无,4)
(无,80,80,2)
是我的模型中两个预测头的输出,我想将它们连接起来,因此,一个预测头的损失函数可以使用另一个预测头的
y_pred
。所以我在想也许我可以把
(None,4)
改成
(None,80,80,1)
,在
(None,80,80,1)
中填充
(None,4)
中的4个元素和零。但我不知道怎么做,也不知道是否有更好的解决方案。@MichaelJanz正如我前面解释的,这两个张量是我的模型中两个预测头的输出,我希望连接的张量是我的最终模型输出。你能帮我广播密集层的输出吗,或者你有更好的解决方案吗