如何在 Keras 中组合两个具有不同输入大小的 LSTM 层?
How to combine two LSTM layers with different input sizes in Keras?
我有两种类型的输入序列,其中 input1
包含 50 个值,input2
包含 25 个值。我尝试使用函数式 API 中的 LSTM 模型组合这两种序列类型。然而,由于我的两个输入序列的长度不同,我想知道我目前所做的是否是正确的方法。我的代码如下:
input1 = Input(shape=(50,1))
x1 = LSTM(100)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(50)(input2)
x = concatenate([x1,x2])
x = Dense(200)(x)
output = Dense(1, activation='sigmoid')(x)
model = Model(inputs=[input1,input2], outputs=output)
更具体地说,我想知道如何组合两个具有不同输入长度(在我的例子中为 50 和 25)的 LSTM 层。如果需要,我很乐意提供更多详细信息。
实际上,在 NLP 等具有不同序列长度的任务中,您的问题很正常。在您的评论中,您使用 return_sequences=False
丢弃了所有先前的输出,这在我们的实践中并不常见,并且通常会导致性能低下的模型。
注:神经网络架构设计没有终极解决方案
以下是我的建议。
方法一(无需自定义图层)
您可以在两个 LSTM 中使用相同的潜在维度并将它们在二维中堆叠起来并将它们视为一个大的隐藏层张量。
input1 = Input(shape=(50,1))
x1 = LSTM(100, return_sequences=True)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(100, return_sequences=True)(input2)
x = concatenate([x1,x2], axis=1)
# output dimension = (None, 75, 100)
如果你不想拥有相同的潜在维度,其他人所做的是再添加一个我们通常称之为映射层的部分,它由堆叠的密集层组成。这种方法有更多变量,这意味着模型更难训练。
input1 = Input(shape=(50,1))
x1 = LSTM(100, return_sequences=True)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(50, return_sequences=True)(input2)
# normally we have more than 1 hidden layer
Map_x1 = Dense(75)(x1)
Map_x2 = Dense(75)(x2)
x = concatenate([Map_x1 ,Map_x2 ], axis=1)
# output dimension = (None, 75, 75)
或展平输出(两者)
input1 = Input(shape=(50,1))
x1 = LSTM(100, return_sequences=True)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(50, return_sequences=True)(input2)
# normally we have more than 1 hidden layer
flat_x1 = Flatten()(x1)
flat_x2 = Flatten()(x2)
x = concatenate([flat_x1 ,flat_x2 ], axis=1)
# output (None, 2650)
方法二(需要自定义图层)
创建您的自定义层并使用产生注意力向量的注意力机制并将该注意力向量用作您的 LSTM 输出张量的表示。其他人所做的并获得更好的性能是使用 LSTM 的最后隐藏状态(你只在你的模型中使用)和注意力向量作为表示。
注意:根据研究,不同类型的attention给出的性能几乎相同,所以我推荐"Scaled Dot-Product Attention",因为它计算速度更快。
input1 = Input(shape=(50,1))
x1 = LSTM(100, return_sequences=True)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(50, return_sequences=True)(input2)
rep_x1 = custom_layer()(x1)
rep_x2 = custom_layer()(x2)
x = concatenate([rep_x1 ,rep_x2], axis=1)
# output (None, (length rep_x1+length rep_x2))
我有两种类型的输入序列,其中 input1
包含 50 个值,input2
包含 25 个值。我尝试使用函数式 API 中的 LSTM 模型组合这两种序列类型。然而,由于我的两个输入序列的长度不同,我想知道我目前所做的是否是正确的方法。我的代码如下:
input1 = Input(shape=(50,1))
x1 = LSTM(100)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(50)(input2)
x = concatenate([x1,x2])
x = Dense(200)(x)
output = Dense(1, activation='sigmoid')(x)
model = Model(inputs=[input1,input2], outputs=output)
更具体地说,我想知道如何组合两个具有不同输入长度(在我的例子中为 50 和 25)的 LSTM 层。如果需要,我很乐意提供更多详细信息。
实际上,在 NLP 等具有不同序列长度的任务中,您的问题很正常。在您的评论中,您使用 return_sequences=False
丢弃了所有先前的输出,这在我们的实践中并不常见,并且通常会导致性能低下的模型。
注:神经网络架构设计没有终极解决方案
以下是我的建议。
方法一(无需自定义图层)
您可以在两个 LSTM 中使用相同的潜在维度并将它们在二维中堆叠起来并将它们视为一个大的隐藏层张量。
input1 = Input(shape=(50,1))
x1 = LSTM(100, return_sequences=True)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(100, return_sequences=True)(input2)
x = concatenate([x1,x2], axis=1)
# output dimension = (None, 75, 100)
如果你不想拥有相同的潜在维度,其他人所做的是再添加一个我们通常称之为映射层的部分,它由堆叠的密集层组成。这种方法有更多变量,这意味着模型更难训练。
input1 = Input(shape=(50,1))
x1 = LSTM(100, return_sequences=True)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(50, return_sequences=True)(input2)
# normally we have more than 1 hidden layer
Map_x1 = Dense(75)(x1)
Map_x2 = Dense(75)(x2)
x = concatenate([Map_x1 ,Map_x2 ], axis=1)
# output dimension = (None, 75, 75)
或展平输出(两者)
input1 = Input(shape=(50,1))
x1 = LSTM(100, return_sequences=True)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(50, return_sequences=True)(input2)
# normally we have more than 1 hidden layer
flat_x1 = Flatten()(x1)
flat_x2 = Flatten()(x2)
x = concatenate([flat_x1 ,flat_x2 ], axis=1)
# output (None, 2650)
方法二(需要自定义图层)
创建您的自定义层并使用产生注意力向量的注意力机制并将该注意力向量用作您的 LSTM 输出张量的表示。其他人所做的并获得更好的性能是使用 LSTM 的最后隐藏状态(你只在你的模型中使用)和注意力向量作为表示。
注意:根据研究,不同类型的attention给出的性能几乎相同,所以我推荐"Scaled Dot-Product Attention",因为它计算速度更快。
input1 = Input(shape=(50,1))
x1 = LSTM(100, return_sequences=True)(input1)
input2 = Input(shape=(25,1))
x2 = LSTM(50, return_sequences=True)(input2)
rep_x1 = custom_layer()(x1)
rep_x2 = custom_layer()(x2)
x = concatenate([rep_x1 ,rep_x2], axis=1)
# output (None, (length rep_x1+length rep_x2))