在Keras中合并前向lstm和后向lstm

在Keras中合并前向lstm和后向lstm,keras,lstm,Keras,Lstm,我想在Keras中合并前向LSTM和后向LSTM。后向LSTM的输入阵列不同于前向LSTM的输入阵列。因此,我不能使用keras.layers.bidirective 正向输入为(10,4)。 反向输入为(12,4),在输入模型之前反向输入。我想在LSTM之后再次将其反转,并将其与前进合并 简化模型如下所示 from lambdawithmask import Lambda as MaskLambda def reverse_func(x, mask=None): return tf.

我想在Keras中合并前向LSTM和后向LSTM。后向LSTM的输入阵列不同于前向LSTM的输入阵列。因此,我不能使用keras.layers.bidirective

正向输入为(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”Op的“values”的列表中的张量具有不完全匹配的类型[bool,float32]


有人能帮我吗?我在Python3.5.2中用Keras(2.0.5)编码,后端是tensorflow(1.2.1)。

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

from keras.models import Model   
前两个模型可以是连续的,没有问题,但连接必须是常规模型。在连接时,我也使用函数方法(创建层,然后传递输入):

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

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

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

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

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\u dim
在LSTM层中是否有用。它在Lambda层中是必需的,但我从不在其他任何地方使用它。形状是您在图层中放置的“单位”数量的自然结果。奇怪的是,你没有指定单位的数量


PS2:您希望如何将两个不同大小的序列连接起来?

正如上面的回答所述,在多输入/输出模型的情况下,使用函数API为您提供了很大的灵活性。您只需将
go_backward
参数设置为
True
,即可反转
LSTM
层对输入向量的遍历

我在下面定义了
smart\u 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')

我更新了我的答案,看看是否有帮助。请随意评论和提问,显示出现错误的行和错误消息。我们是来帮忙的。我用了Lambda层和keras后端,我得到了它。谢谢。-你会考虑把它标记为一个有效的答案吗?
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')