我尝试开发一个简单的模型来解决多分类问题。我在 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
我试过改变层数、它们的大小、批量大小、时期数,调整矢量化测试数据的词汇量大小,但似乎没有任何改进评估。
训练和测试精度之间的差异表明您的模型过度拟合训练数据。当模型变得过于专注于识别训练数据中的模式时,就会发生过度拟合,从而对其在看不见的数据上的性能产生负面影响。以下是一些减少过度拟合和提高模型评估性能的策略:
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)))
model.add(layers.Dropout(0.5))
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 等工具来自动执行超参数搜索过程。
尝试结合这些技术来减少过度拟合并提高模型的评估性能。请记住,在欠拟合和过拟合之间取得平衡至关重要。