连接不同形状的keras层输出

时间:2020-08-13 05:50:21

标签: python keras keras-layer

keras模型如下:

images = tf.zeros(shape=[10, 256, 256, 3])

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) y_pred1是我希望模型学习预测的结果。

但是y_pred2分支的损失函数fcn1需要y_pred1预测结果,因此我必须将两个分支的结果连接起来才能得到y_pred2,这样y_merged将有权访问fcn1

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

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

是否有比使用y_pred2层更好的解决方案?

2 个答案:

答案 0 :(得分:0)

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

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_input具有shape(None,1)并作为我的编码器-解码器lstm网络的条件帮助了我。为了匹配lstm编码器状态的所有维度,首先我必须使用tf.expand_dims()将条件值从[[1]]这样的形状扩展为[[[1]]]

这是您首先需要做的。如果您根据密集层的预测得出softmax值,则可能要先使用tf.argmax(),这样就只有一个值,这更易于广播。但是,请记住,尺寸为4也是可以匹配的。您无法将shape(None,4)广播到shape(None,6),而是广播到shape(None,8),因为8可以通过4进行划分。

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

答案 1 :(得分:0)

弄清楚了,代码是这样的:

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]