【问题标题】:Merge a forward lstm and a backward lstm in Keras在 Keras 中合并前向 lstm 和后向 lstm
【发布时间】:2023-03-25 21:57:01
【问题描述】:

我想在 Keras 中合并一个前向 LSTM 和一个后向 LSTM。后向 LSTM 的输入数组与前向 LSTM 的输入数组不同。因此,我不能使用 keras.layers.Bidirectional。

前向输入是 (10, 4)。 后向输入是 (12, 4) 并且在放入模型之前被反转。我想在 LSTM 之后再次反转它并与正向合并。

简化模型如下。

from lambdawithmask import Lambda as MaskLambda

def reverse_func(x, mask=None):
    return tf.reverse(x, [False, True, False])

forward = Sequential()
backward = Sequential()
model = Sequential()

forward.add(LSTM(input_shape = (10, 4), output_dim = 4, return_sequences = True))
backward.add(LSTM(input_shape = (12, 4), output_dim = 4, return_sequences = True))
backward.add(MaskLambda(function=reverse_func, mask_function=reverse_func))
model.add(Merge([forward, backward], mode = "concat", concat_axis = 1))

当我运行它时,错误消息是: 传递给“ConcatV2”操作的“值”的列表中的张量具有不完全匹配的类型 [bool, float32]。

谁能帮助我?我在 Python 3.5.2 中使用 Keras (2.0.5) 编写代码,后端是 tensorflow (1.2.1)。

【问题讨论】:

  • 我更新了我的答案,看看是否有帮助。随意评论和提问,显示错误出现的行和错误消息。我们随时为您提供帮助。

标签: keras lstm


【解决方案1】:

首先,如果您有两个不同的输入,则不能使用顺序模型。您必须使用函数式 API 模型:

from keras.models import Model   

前两个模型可以是sequential的,没问题,但是junction必须是正则模型。在连接时,我也使用函数式方法(创建层,然后传递输入):

junction = Concatenate(axis=1)([forward.output,backward.output])

为什么轴=1?您只能连接具有相同形状的事物。由于您有 10 和 12,因此它们不兼容,除非您使用这个确切的轴进行合并,这是第二个轴,考虑到您有 (BatchSize, TimeSteps, Units)

要创建最终模型,请使用Model,指定输入和输出:

model = Model([forward.input,backward.input], junction)

在要反转的模型中,只需使用Lambda 层。 MaskLambda 不仅仅是您想要的功能。我还建议你使用 tensorflow 函数的 keras 后端:

import keras.backend as K

#instead of the MaskLambda:
backward.add(Lambda(lambda x: K.reverse(x,axes=[1]), output_shape=(12,?))

这里,? 是你的 LSTM 层所拥有的单位数量。见最后PS。


PS:我不确定output_dim 在 LSTM 层中是否有用。它在 Lambda 层中是必需的,但我从不在其他任何地方使用它。形状是您放置在图层中的“单位”数量的自然结果。奇怪的是,您没有指定单位数量。

PS2:您究竟想如何连接两个不同大小的序列?

【讨论】:

  • 我改用了 Lambda 层和 keras 后端,我明白了。谢谢。
  • :) -- 您会考虑将其标记为有效答案吗?
【解决方案2】:

如上述答案所述,在多输入/输出模型的情况下,使用功能 API 可为您提供很大的灵活性。您可以简单地将go_backwards 参数设置为True 以反转LSTM 层对输入向量的遍历。

我在下面定义了smart_merge 函数,它将前向和后向 LSTM 层合并在一起,同时处理单个遍历情况。

from keras.models import Model
from keras.layers import Input, merge

def smart_merge(vectors, **kwargs):
        return vectors[0] if len(vectors)==1 else merge(vectors, **kwargs)      

input1 = Input(shape=(10,4), dtype='int32')
input2 = Input(shape=(12,4), dtype='int32')

LtoR_LSTM = LSTM(56, return_sequences=False)
LtoR_LSTM_vector = LtoR_LSTM(input1)
RtoL_LSTM = LSTM(56, return_sequences=False, go_backwards=True)
RtoL_LSTM_vector = RtoL_LSTM(input2)

BidireLSTM_vector = [LtoR_LSTM_vector]
BidireLSTM_vector.append(RtoL_LSTM_vector)
BidireLSTM_vector= smart_merge(BidireLSTM_vector, mode='concat')

【讨论】:

    猜你喜欢
    • 2018-06-04
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多