首页 > 解决方案 > 与密集层相比,RNN 和 LSTM 的准确率较低

问题描述

https://colab.research.google.com/drive/16np3KgLfxnjWdxRexyB77sXHMSrhbaoG?usp=sharing是我的代码实验室的链接。

图表:

长短期记忆体

lstm 图

循环神经网络

rnn图

稠密

密集图

所有进口:

import tensorflow as tf
from tensorflow.keras.preprocessing import sequence
from tensorflow.keras.layers import Dense, Embedding, SimpleRNN, LSTM, Activation, Dropout
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.metrics import Accuracy
from tensorflow.keras import optimizers
from tensorflow.keras.models import Sequential
from tensorflow.keras.datasets import reuters
from tensorflow.keras import models, Input

我想我没有遗漏任何输入数据,它是矢量化的。输出,标签使用 keras 中包含的 one_hot 编码实现进行编码...

maxFeatures = 8982
(train_data, train_labels), (test_data,test_labels) = reuters.load_data(num_words = maxFeatures, skip_top=0) 
import numpy as np
def vectorize_sequences(sequences, dimension=maxFeatures):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
    results[i,sequence] = 1.
return results

x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

from tensorflow.keras.utils import to_categorical

y_train = to_categorical(train_labels)
y_test = to_categorical(test_labels)

数据形状:

训练数据形状:(8982, 8982) 和训练标签形状:(8982, 46)

测试数据形状:(2246, 8982) 和测试标签形状:(2246, 46)

使用 LSTM 或 Simple RNN 时,我无法获得超过 35% 的 val_accuracy。我尝试更改变量,添加不同的激活层,并添加 dropout 以防它过度拟合。我不认为它是不合适的。使用不同的激活层确实改变了 1-2%。

modelRNN = Sequential()
modelRNN.add(Input(shape=(maxFeatures,)))

modelRNN.add(Embedding(maxFeatures,64))
modelRNN.add(LSTM(64))
modelRNN.add(Dropout(0.2))
modelRNN.add(Dense(46, activation="softmax"))


modelRNN.compile(
  optimizer='adam',
  loss='categorical_crossentropy',
  metrics=['accuracy'],
)

historyRNN = modelRNN.fit(x_train, y_train,
  epochs=10,
  batch_size=256,
  validation_split=0.2
  )

RNN 模型的结果: 结果 RNN

对测试数据使用评估方法确实给了我不同的准确率百分比,但接近 35%。

modelRNN.evaluate(x_test,y_test)

71/71 [==============================] - 9s 122ms/step - loss: 2.4143 - accuracy: 0.3620
[2.4142708778381348, 0.36197686195373535]

现在来看有趣的部分:使用密集层可以让我的 val_accuracy 超过 75%。评估模型再次给了我超过 75% 的收益。

model = models.Sequential()
model.add(Dense(64, activation='relu', input_shape=(maxFeatures,)))
model.add(Dense(64, activation='relu'))
model.add(Dense(46, activation='softmax'))

model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])

拟合后的结果: 密集拟合结果

我认为这与数据有关,但我不确定是什么。

它也可能与我正在使用的优化器有关。我已经尝试了 rmsprop 和 adam,结果几乎相同。所以也许这是我默认留下的其他一些变量。

在所有情况下,我都使用 softmax 作为最后一层,这样我就可以获得每个标签的概率。可能是激活层问题?例如在嵌入中,但用我知道的测试它并没有改变结果。

标签: pythontensorflowkerasdeep-learninglstm

解决方案


您正在向嵌入层提供一个热向量。您应该改为提供整数索引。不要打电话vectorize_sequence()。创建一个标记字典并对序列进行标记。例如,如果您有一个序列“我的序列我的序列” - 您应该将 [0, 1, 0, 1] 馈送到网络,而不是 [[1, 0, 0, 0], [0, 1, 0, 0] ,[1, 0, 0, 0], [0, 1, 0, 0]]。


推荐阅读