繁体   English   中英

Keras LSTM 不同的输入输出形状

[英]Keras LSTM different input output shape

在我的二进制多标签序列分类问题中,每个输入句子有 22 个时间步长。 现在我已经为每个时间步添加了 200 个维度的词嵌入,所以我当前的输入形状是(*number of input sentence*,22,200) 我的输出形状将是(*number of input sentence*,4)eg.[1,0,0,1]

我的第一个问题是,如何构建 Keras LSTM 模型以接受 3D 输入和输出 2D 结果。 以下代码输出错误:

ValueError: Error when checking target: expected dense_41 to have 3 dimensions, but got array with shape (7339, 4)

我的第二个问题是,当我添加TimeDistributed层时,我是否应该将 Dense 层的数量设置为输入中的特征数量,在我的例子中,即200

.

X_train, X_test, y_train, y_test = train_test_split(padded_docs2, new_y, test_size=0.33, random_state=42)

start = datetime.datetime.now()
print(start)

# define the model
model = Sequential()
e = Embedding(input_dim=vocab_size2, input_length=22, output_dim=200, weights=[embedding_matrix2], trainable=False)
model.add(e)
model.add(LSTM(128, input_shape=(X_train.shape[1],200),dropout=0.2, recurrent_dropout=0.1, return_sequences=True))
model.add(TimeDistributed(Dense(200)))

model.add(Dense(y_train.shape[1],activation='sigmoid'))

# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
# summarize the model
print(model.summary())

# fit the model
model.fit(X_train, y_train, epochs=300, verbose=0)

end = datetime.datetime.now()
print(end)
print('Time taken to build the model: ', end-start)

如果我遗漏了任何信息,请告诉我,谢谢。

您模型的Lstm层获取 3D 序列并生成 3D 输出。 TimeDistributed层也是如此。 如果您希望 lstm 返回 2D 张量,则参数return_sequences应该为 false。 现在您不必使用TimeDistributed Wrapper。 使用此设置,您的模型将是

model = Sequential()
e = Embedding(input_dim=vocab_size2, input_length=22, output_dim=200, weights=[embedding_matrix2], trainable=False)
model.add(e)
model.add(LSTM(128, input_shape=(X_train.shape[1],200),dropout=0.2, recurrent_dropout=0.1, return_sequences=False))
model.add(Dense(200))

model.add(Dense(y_train.shape[1],activation='sigmoid'))

###Edit: TimeDistributed将给定层应用于输入的每个时间切片。例如,在您的情况下,时间维度为X_train.shape[1] 让我们假设X_train.shape[1] == 10并考虑以下行。

model.add(TimeDistributed(Dense(200)))

这里TimeDistributed包装器为每个时间切片(总共 10 个密集层)创建一个密集层(Dense(200))。 因此,对于每个时间维度,您将获得形状为 (batch_size, 200) 的输出,最终输出张量的形状为 (batch_size, 10, 200)。 但是你说你想要二维输出。 所以TimeDistributed无法从 3D 输入中获取 2D。 另一种情况是,如果您删除TimeDistributed包装器并仅使用密集的,就像这样。 model.add(Dense(200)) 然后密集层首先将输入压平为形状 (batch_size * 10, 200) 并计算全连接层的点积。 在点积之后,密集层将输出重塑为与输入具有相同的形状。 在您的情况下 (batch_size, 10, 200) 它仍然是 3D 张量。
但是,如果您不想更改 lstm 层,则可以将TimeDistributed层替换为另一个 lstm 层,并将return_sequences设置为 false。 现在你的模型看起来像这样。

model = Sequential()
e = Embedding(input_dim=vocab_size2, input_length=22, output_dim=200, weights=[embedding_matrix2], trainable=False)
model.add(e)
model.add(LSTM(128, input_shape=(X_train.shape[1],200),dropout=0.2, recurrent_dropout=0.1, return_sequences=True))
model.add(LSTM(200, input_shape=(X_train.shape[1],200),dropout=0.2, recurrent_dropout=0.1, return_sequences=False))

model.add(Dense(y_train.shape[1],activation='sigmoid'))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM