You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Keras中获得稳定的验证准确率与验证损失值?

MLP文本分类训练不稳定问题的修复方案

你的问题主要来自代码里的几个关键逻辑错误和训练参数设置不当,以下是具体排查和修复方案:

1. 修正clear_session()调用时机

当前代码在创建模型后才调用clear_session(),这会直接销毁已构建的模型,后续训练的是Keras自动重建的临时模型,逻辑完全错误。正确做法是在创建模型前调用,确保彻底清空之前的会话和模型残留:

# 先清空会话,再创建模型
clear_session()
model = Sequential()
# ... 后续模型构建代码

2. 统一标签编码逻辑

测试集标签不能重新执行fit_transform,必须复用训练集的编码器映射,否则会出现标签编码不一致(比如正负类映射颠倒):

Encoder = LabelEncoder()
# 仅在训练集上拟合编码器
Train_Y2 = Encoder.fit_transform(Train_Y2)
# 测试集直接用训练集的编码器转换
Test_Y2 = Encoder.transform(Test_Y2)

3. 固定随机种子消除结果随机性

神经网络权重初始化、优化器内部运算都带有随机性,固定全局种子才能让每次训练结果一致:

import random
import numpy as np
import tensorflow as tf

# 固定所有随机源的种子
random.seed(42)
np.random.seed(42)
tf.random.set_seed(42)

4. 移除硬编码的输入维度

手动写input_dim=1148极易导致输入维度不匹配,直接从TF-IDF特征矩阵获取真实维度:

# 从训练集特征矩阵获取输入维度
input_dim = arr_Train_X2_Tfidf.shape[1]
model.add(Dense(100, input_dim=input_dim, activation='relu'))

5. 降低学习率稳定训练

你设置的Adam学习率0.01是默认值的10倍,过大的学习率会导致训练过程剧烈震荡,验证指标波动甚至持续恶化。调整为默认的0.001:

opt = Adam(learning_rate=0.001)

6. 解决验证集参数冲突

model.fit()中同时设置validation_split=0.2和validation_data会触发冲突,Keras会优先使用validation_data。建议仅用训练集的20%做验证,测试集留到训练完成后再评估(避免过拟合到测试集):

# 仅保留validation_split,用训练集的20%做验证
history = model.fit(arr_Train_X2_Tfidf, Train_Y2, epochs=100,verbose=1, 
                    validation_split=0.2, batch_size=32, callbacks=[es])
# 训练完成后单独评估测试集
test_loss, test_acc = model.evaluate(arr_Test_X2_Tfidf, Test_Y2)

7. 替换激活函数缓解梯度消失

隐藏层用sigmoid容易出现梯度消失问题,换成relu能提升训练稳定性和收敛速度:

model.add(Dense(100, input_dim=input_dim, activation='relu'))

完整修正代码

import random
import numpy as np
import tensorflow as tf
from sklearn import model_selection
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import TfidfVectorizer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping
from keras.backend import clear_session

# 固定全局随机种子
random.seed(42)
np.random.seed(42)
tf.random.set_seed(42)

# 分割训练/测试集(80:20)
Train_X2, Test_X2, Train_Y2, Test_Y2 = model_selection.train_test_split(
    dataset['review'], dataset['sentiment'], test_size=0.2, random_state=1
)

# 标签编码:训练集拟合,测试集复用
Encoder = LabelEncoder()
Train_Y2 = Encoder.fit_transform(Train_Y2)
Test_Y2 = Encoder.transform(Test_Y2)

# TF-IDF特征提取
Tfidf_vect2 = TfidfVectorizer(max_features=None)
Tfidf_vect2.fit(dataset['review'])
Train_X2_Tfidf = Tfidf_vect2.transform(Train_X2)
Test_X2_Tfidf = Tfidf_vect2.transform(Test_X2)

# 转换为稠密数组适配Keras输入
arr_Train_X2_Tfidf = Train_X2_Tfidf.toarray()
arr_Test_X2_Tfidf = Test_X2_Tfidf.toarray()

# 清空会话后构建模型
clear_session()
input_dim = arr_Train_X2_Tfidf.shape[1]
model = Sequential()
model.add(Dense(100, input_dim=input_dim, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

# 编译模型:使用默认学习率
opt = Adam(learning_rate=0.001)
model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
model.summary()

# 早停策略:保留最优权重
es = EarlyStopping(monitor="val_loss", mode='min', patience=10, restore_best_weights=True)

# 训练模型
history = model.fit(
    arr_Train_X2_Tfidf, Train_Y2,
    epochs=100, verbose=1,
    validation_split=0.2,
    batch_size=32,
    callbacks=[es]
)

# 评估测试集
test_loss, test_acc = model.evaluate(arr_Test_X2_Tfidf, Test_Y2, verbose=0)
print(f"\n测试集结果:准确率={test_acc:.4f},损失={test_loss:.4f}")

额外优化建议

  • 隐藏层后添加Dropout(0.2)层,缓解过拟合:model.add(tf.keras.layers.Dropout(0.2))
  • 设置TfidfVectorizer(max_features=5000)减少特征维度,提升训练效率
  • 绘制训练曲线观察收敛情况:
import matplotlib.pyplot as plt

plt.plot(history.history['accuracy'], label='训练准确率')
plt.plot(history.history['val_accuracy'], label='验证准确率')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

plt.plot(history.history['loss'], label='训练损失')
plt.plot(history.history['val_loss'], label='验证损失')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

内容的提问来源于stack exchange,提问作者andryan86

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:13:36