连接不同形状的 keras 层输出
Concatenate differently shaped keras layer outputs
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)
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)
输出连接起来,但我不知道该怎么做。
如何将 (None, 4)
重塑为 (None, 80, 80, 1)
?例如,用 y_pred2
中的 4 个元素和零填充 (None, 80, 80, 1)
。
有没有比使用Concatenate
层更好的解决方案?
也许这段提取的代码可以帮助您:
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)
并帮助我作为我的 encoder-decoder lstm 网络的条件。为了匹配 lstm 编码器状态的所有维度,首先我必须使用 tf.expand_dims()
将条件值从 [[1]]
形状扩展到 [[[1]]]
.
这是您首先需要做的。如果你有来自密集层的 softmax 预测,你可能想先使用 tf.argmax()
,这样你只有一个值,这样更容易广播。但是,它也可能是 4,但请记住,尺寸需要匹配。您不能将 shape(None,4)
广播到 shape(None,6)
,但可以广播到 shape(None,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(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]
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)
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)
输出连接起来,但我不知道该怎么做。
如何将 (None, 4)
重塑为 (None, 80, 80, 1)
?例如,用 y_pred2
中的 4 个元素和零填充 (None, 80, 80, 1)
。
有没有比使用Concatenate
层更好的解决方案?
也许这段提取的代码可以帮助您:
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)
并帮助我作为我的 encoder-decoder lstm 网络的条件。为了匹配 lstm 编码器状态的所有维度,首先我必须使用 tf.expand_dims()
将条件值从 [[1]]
形状扩展到 [[[1]]]
.
这是您首先需要做的。如果你有来自密集层的 softmax 预测,你可能想先使用 tf.argmax()
,这样你只有一个值,这样更容易广播。但是,它也可能是 4,但请记住,尺寸需要匹配。您不能将 shape(None,4)
广播到 shape(None,6)
,但可以广播到 shape(None,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(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]