Keras LSTM不同的输入输出形状

时间:2018-12-07 04:44:46

标签: python keras lstm

在我的二进制多标签序列分类问题中,每个输入句子中都有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层时,是否应该将密集层的数量设置为输入中要素的数量(在我的情况下为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)

请让我知道是否错过任何信息,谢谢。

1 个答案:

答案 0 :(得分:1)

您模型的const comment = [ {"name": "name1", "date": "00-00-0000", "body": "comment here1"}, {"name": "name2", "date": "00-00-0000", "body": "comment here2"}, {"name": "name3", "date": "00-00-0000", "body": "comment here3"} ]; comment.forEach(({ name, date, body }) => { const html = "<div class='commentBox'><div class='leftPanelImg'><img src='images/Reviews/Comment%20pic.jpg'></div><div class='rightPanel'><span>"+name+"</span><div class='date'>"+.date+"</div><p>"+body+"</p></div><div class='clear'></div></div>" $('#container').append(html); }); 层获得3D序列并产生3D输出。 Lstm层也是如此。如果要lstm返回2D张量,则参数TimeDistributed应该为true。现在,您不必使用return_sequences包装器。通过此设置,您的模型将是

TimeDistributed

编辑:

TimeDistributed将给定层应用于输入的每个时间片。例如,您的时间维为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')) 。让我们假设X_train.shape[1]并考虑以下行。

X_train.shape[1] == 10

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

return_sequences