简体   繁体   English

连接不同形状的 keras 层输出

[英]Concatenate differently shaped keras layer outputs

The keras model is like this: keras model是这样的:


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 and y_pred2 are the results I want the model to learn to predict. y_pred1y_pred2是我希望 model 学习预测的结果。

But the loss function fcn1 for the y_pred1 branch need y_pred2 prediction results, so I have to concatenate the results of the two branches to get y_merged , so that fcn1 will have access to y_pred2 .但是y_pred1分支的 loss function fcn1需要y_pred2预测结果,所以我必须将两个分支的结果连接起来得到y_merged ,这样fcn1才能访问y_pred2

The problem is, I want to use the Concatenate layer to concatenate the y_pred1 (None, 4) output with the y_pred2 (None, 80, 80, 2) output, but I don't know how to do that.问题是,我想使用Concatenate层将y_pred1 (None, 4) output 与y_pred2 (None, 80, 80, 2) output 连接起来,但我不知道该怎么做。

How can I reshape the (None, 4) to (None, 80, 80, 1) ?如何将(None, 4)重塑为(None, 80, 80, 1) For example, by filling the (None, 80, 80, 1) with the 4 elements in y_pred2 and zeros.例如,通过用y_pred2中的 4 个元素和零填充(None, 80, 80, 1)

Is there any better solutions than using the Concatenate layer?有没有比使用Concatenate层更好的解决方案?

Maybe this extracted piece of code could help you:也许这段提取的代码可以帮助你:

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])

When you want to broadcast a value, first think about what exactly you want to broadcast.当你想广播一个值时,首先要考虑你到底要广播什么。 In this example, condi_input has shape(None,1) and helped me as a condition for my encoder-decoder lstm network.在此示例中, condi_input 具有shape(None,1)并帮助我作为编码器-解码器 lstm 网络的条件。 To match all dimensionalities, of the encoder states of the lstm, first I had to use tf.expand_dims() to expand the condition value from a shape like [[1]] to [[[1]]] .为了匹配 lstm 的编码器状态的所有维度,首先我必须使用tf.expand_dims()将条件值从[[1]]之类的形状扩展到[[[1]]]

This is what you need to do first.这是您首先需要做的。 If you have a prediction as a softmax from the dense layers, you might want to use tf.argmax() first, so you only have one value, which is way easier to broadcast.如果你有一个来自密集层的 softmax 预测,你可能想先使用tf.argmax() ,所以你只有一个值,这更容易广播。 However, its also possible with 4 but keep in mind, that the dimensions need to match.但是,它也可以使用 4,但请记住,尺寸需要匹配。 You cannot broadcast shape(None,4) to shape(None,6) , but to shape(None,8) since 8 is devidable through 4.您不能将shape(None,4)广播到shape(None,6) ,而是广播到shape(None,8)因为 8 可以通过 4 进行划分。

Then you you can use tf.broadcast() to broadcast your value into the desired shape.然后您可以使用tf.broadcast()将您的值广播到所需的形状。 Then you have two shapes, you can concatenate together.然后你有两个形状,你可以连接在一起。 hope this helps you out.希望这可以帮助你。

Figured it out, the code is like this:想通了,代码是这样的:

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)

The 4 elements of y_pred2 can be indexed as y_merged[None, :4, 0, 2] y_pred2 的 4 个元素可以索引为y_merged[None, :4, 0, 2]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM