【问题标题】:Concatenate differently shaped keras layer outputs连接不同形状的 keras 层输出
【发布时间】:2020-08-13 05:50:21
【问题描述】:

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

但是y_pred1分支的损失函数fcn1需要y_pred2的预测结果,所以我要把两个分支的结果串联起来得到y_merged,这样fcn1就可以访问@ 987654329@.

问题是,我想使用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 层更好的解决方案?

【问题讨论】:

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

标签: python keras keras-layer


【解决方案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_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() 将您的值广播到所需的形状。然后你有两个形状,你可以连接在一起。 希望这对您有所帮助。

【讨论】:

    【解决方案2】:

    想通了,代码是这样的:

    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]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      • 2021-06-05
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      相关资源
      最近更新 更多