我的神经网络在测试数据上表现不佳,但在训练数据上的准确率非常高,这可能是什么原因?

问题描述 投票:0回答:1

我尝试开发一个简单的模型来解决多分类问题。我在 Kaggle 上找到了一个包含 25k+ 条推文的数据集,这些推文标有文本的情绪(正面、中性、负面)。我处理了数据并提出了一个简单的网络模型。该网络在训练数据上达到了 98-99% 左右的准确率,但在测试数据上达到了 60% 左右。性能之间存在这种差异的原因是什么,我该如何优化模型以获得更好的评估性能?

代码如下:

df = pd.read_csv('Tweets.csv');

df = df.drop(columns=['textID', 'selected_text'])

data = df['text']
labels = df['sentiment']

labels = np.unique(labels, return_inverse=True)
lookup = labels[0]
labels = labels[1]

data = np.array(data).astype(str)
tokenizer = keras_preprocessing.text.Tokenizer(num_words=10000)
tokenizer.fit_on_texts(data)
sequences = tokenizer.texts_to_sequences(data)
one_hot_results = tokenizer.texts_to_matrix(data, mode='binary')

all_tweets = one_hot_results[:20000]
all_labels = labels[:20000]

train_data = all_tweets[:10000]
test_data = all_tweets[10000:]


train_labels = all_labels[:10000]
test_labels = all_labels[10000:]


model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10000, )))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(3, activation='softmax'))
model.compile(optimizer='rmsprop', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(train_data, train_labels, batch_size=512, epochs=20, validation_split=0.3)

test_loss, test_acc = model.evaluate(test_data, test_labels)
print("test_acc:", test_acc)

这是我的控制台输出:

Epoch 19/20
14/14 [==============================] - 0s 14ms/step - loss: 0.0423 - accuracy: 0.9903 - val_loss: 1.9351 - val_accuracy: 0.6063
Epoch 20/20
14/14 [==============================] - 0s 14ms/step - loss: 0.0365 - accuracy: 0.9920 - val_loss: 2.0434 - val_accuracy: 0.6013
313/313 [==============================] - 1s 3ms/step - loss: 1.9856 - accuracy: 0.6086
test_acc: 0.6086000204086304

我试过改变层数、它们的大小、批量大小、时期数,调整矢量化测试数据的词汇量大小,但似乎没有任何改进评估。

python tensorflow machine-learning keras deep-learning
1个回答
0
投票

训练和测试精度之间的差异表明您的模型过度拟合训练数据。当模型变得过于专注于识别训练数据中的模式时,就会发生过度拟合,从而对其在看不见的数据上的性能产生负面影响。以下是一些减少过度拟合和提高模型评估性能的策略:

  • 正则化:向图层添加 L1 或 L2 正则化。正则化为损失函数添加了一个惩罚项,这会阻止过于复杂的模型并有助于防止过度拟合。
from keras import regularizers

model.add(layers.Dense(64, activation='relu', kernel_regularizer=regularizers.l2(0.001), input_shape=(10000,)))
model.add(layers.Dense(64, activation='relu', kernel_regularizer=regularizers.l2(0.001)))
  • Dropout:将dropout应用到你的层。 Dropout 是一种在训练过程中将一小部分输入单元随机设置为 0 的技术,这有助于防止过度拟合。
model.add(layers.Dropout(0.5))
  • Early Stopping:当验证损失停止改善时停止训练。这可以防止模型过度拟合训练数据。
from keras.callbacks import EarlyStopping

early_stopping = EarlyStopping(monitor='val_loss', patience=2)

model.fit(train_data, train_labels, batch_size=512, epochs=20, validation_split=0.3, callbacks=[early_stopping])

在这个例子中,如果验证损失连续 2 个时期没有改善,训练将停止。

使用预训练词嵌入:您可以使用预训练词嵌入,如 GloVe 或 Word2Vec,而不是使用单热编码词。这些嵌入捕获单词之间的语义关系,这有助于提高模型的性能。

Fine-tune hyperparameters:对最佳超参数进行系统搜索,例如层数、每层中的单元数、学习率和批量大小。您可以使用 Keras Tuner 或 Optuna 等工具来自动执行超参数搜索过程。

尝试结合这些技术来减少过度拟合并提高模型的评估性能。请记住,在欠拟合和过拟合之间取得平衡至关重要。

© www.soinside.com 2019 - 2024. All rights reserved.