在我的二进制多标签序列分类问题中,每个输入句子中都有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)
请让我知道是否错过任何信息,谢谢。
答案 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