首页 文章

Keras LSTM输入输出形状不同

提问于
浏览
0

在我的二元多标记序列分类问题中,我在每个输入句子中有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)

如果我错过了任何信息,请告诉我,谢谢 .

1 回答

  • 0

    模型的 Lstm 层获取3D序列并生成3D输出 . TimeDistributed 层同样如此 . 如果您希望lstm返回2D张量,则参数 return_sequences 应为true . 现在您不必使用 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'))
    

    编辑:

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

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

    这里 TimeDistributed 包装器为每个时间切片(总共10个密集层)创建一个密集层(密集(200)) . 因此,对于每个时间维度,您将获得具有形状的输出(batch_size,200),并且最终输出张量将具有(batch_size,10,200)的形状 . 但是你说你想要2D输出 . 所以 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'))
    

相关问题