Keras LSTM 准确率停留在 50%

数据挖掘 喀拉斯 lstm 准确性
2022-03-08 13:26:42

我正在尝试训练 LSTM 对IMDb 评论数据集进行情绪分析。

作为词嵌入层的输入,我将每条评论转换为索引列表(对应于词汇集中的词索引)。我想将文本转换为单热/计数矩阵,但最终会得到巨大的稀疏矩阵(我应该担心这个吗?)。

以下是我创建网络架构的方式:

model = Sequential()
model.add(Embedding(
    input_dim=vocab_size,
    output_dim=word_embed_vector_size,
    input_length=sentence_len_max)
         )
model.add(LSTM(units=1))
model.add(Dense(1, activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy', 'binary_accuracy'])
model.summary()

以下是模型摘要:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_2 (Embedding)      (None, 1422, 4)           201764    
_________________________________________________________________
lstm_2 (LSTM)                (None, 1)                 24        
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 2         
=================================================================
Total params: 201,790
Trainable params: 201,790
Non-trainable params: 0
___________________________

现在,当我尝试训练模型时,我发现准确率停留在 50%

losses = model.fit(
    x                = term_idx_train,
    y                = y_train,
    epochs           = epochs,
    batch_size       = batch_size,
    validation_split = 0.01
)

这是时代的输出:

Epoch 1/10
25000/25000 [==============================] - 1148s 46ms/step - loss: 7.9712 - acc: 0.5000 - binary_accuracy: 0.5000
Epoch 2/10
25000/25000 [==============================] - 1156s 46ms/step - loss: 7.9712 - acc: 0.5000 - binary_accuracy: 0.5000
Epoch 3/10
25000/25000 [==============================] - 1149s 46ms/step - loss: 7.9712 - acc: 0.5000 - binary_accuracy: 0.5000
Epoch 4/10
25000/25000 [==============================] - 1110s 44ms/step - loss: 7.9712 - acc: 0.5000 - binary_accuracy: 0.5000
Epoch 5/10
16800/25000 [===================>..........] - ETA: 6:10 - loss: 7.9816 - acc: 0.4993 - binary_accuracy: 0.4993

将激活函数更改为 asigmoid并将 LSTM 块更改为 32 无济于事(1 epoch):

Train on 24750 samples, validate on 250 samples
Epoch 1/1
24750/24750 [==============================] - 1186s 48ms/step - loss: 0.6932 - acc: 0.5022 - binary_accuracy: 0.5022 - val_loss: 0.6951 - val_acc: 0.0000e+00 - val_binary_accuracy: 0.0000e+00

Epoch 00001: val_loss improved from inf to 0.69513, saving model to sentiment_model

看看 LSTM 的预测,我看到:

count   25000.000000
mean    0.499023
std 0.000013
min 0.499010
25% 0.499010
50% 0.499010
75% 0.499010
max 0.499443

知道为什么要这样做吗?以及我该如何解决这个问题?

4个回答

activation = 'softmax'应该用于多类分类,而'sigmoid'应该用于二元分类。

可以参考:http ://dataaspirant.com/2017/03/07/difference-between-softmax-function-and-sigmoid-function/

如果更改激活函数没有帮助,我会寻找替代解决方案。

可能是您在代码中出现的一个简单错误(可能是在提取数据集时),我们在您的代码示例中看不到。您表现出的持续损失确实是一种非常奇怪的行为。

反正...

如果没有像word2vec这样的预训练嵌入和如此简单的架构,您正在尝试一些真正雄心勃勃的东西。

我建议您查看我的 github 存储,其中(如果您真的对不使用预训练嵌入感兴趣)有一个示例,该示例从随机嵌入开始,并87.72%在使用 CNN 在测试集上进行训练时对其进行调整。您可以轻松地将其转换为 LSTM。

使用 Softmax 作为最后一层的激活,你应该有 n 个神经元,其中 n 是类的数量。这是一个解释: https://developers.google.com/machine-learning/crash-course/multi-class-neural-networks/softmax 所以基本上:

model.add(Dense(n_classes, activation='softmax'))

如果您使用一种热编码:

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

事实证明,该问题与第一个 层output_dimEmbedding层有关,将其4增加到最高以16帮助起飞的准确度达到 96% 左右。

新问题是网络开始过拟合,添加Dropout层有助于减少这种情况。