Keras LSTM文本情感分类模型加载后预测结果不一致的问题及解决
LSTM情感检测模型保存后预测结果反转的解决方案
我看你遇到的这个问题特别典型——训练好的LSTM情感模型当场预测完全符合预期,存成h5文件重新加载后,相同文本的预测结果直接反转,正常情感全被判定成仇恨情感。好在你已经找对了解决方向,我来把背后的逻辑和标准实践理清楚:
问题根源:Tokenizer的错误复用
问题核心出在Tokenizer的处理逻辑上:
你训练时用tokenizer.fit_on_texts(X_train)让Tokenizer学习了训练集所有词汇的编码规则,这个规则是和你的LSTM模型绑定的——模型就是基于这套编码来学习文本特征的。但加载模型后的预测代码里,你又对测试文本执行了tokenizer.fit_on_texts(texts),这相当于重新训练了一个全新的Tokenizer,它只基于这4个短句生成编码,和训练时的编码规则完全不匹配!
举个例子:训练时"hope"可能被编码成[5],但重新fit后它可能被编码成[1],模型拿到完全陌生的输入序列,自然输出了错误甚至反转的预测结果。
正确解决方案:保存并复用训练时的Tokenizer
解决的关键就是把训练时用的Tokenizer保存下来,预测时直接加载复用,绝对不能重新fit。具体步骤如下:
1. 训练完成后保存Tokenizer
用pickle序列化保存Tokenizer是最常用的方式:
import pickle # 训练流程结束后,保存训练好的tokenizer with open('ModelsDL/tokenizer.pickle', 'wb') as handle: pickle.dump(tokenizer, handle, protocol=pickle.HIGHEST_PROTOCOL)
2. 加载模型和Tokenizer进行预测
from tensorflow.keras.models import load_model import pickle from tensorflow.keras.preprocessing.sequence import pad_sequences # 加载保存的模型和Tokenizer model = load_model("ModelsDL/LSTM.h5") with open('ModelsDL/tokenizer.pickle', 'rb') as handle: tokenizer = pickle.load(handle) texts = ["hope", "feel relax", "feel energy", "peaceful day"] # 直接用加载好的Tokenizer转序列,不要调用fit_on_texts! test_samples_token = tokenizer.texts_to_sequences(texts) test_samples_tokens_pad = pad_sequences(test_samples_token, maxlen=max_len) print(model.predict(x=test_samples_tokens_pad))
额外注意事项
- 除了Tokenizer,训练时的
max_len、max_words这些超参数也要和预测时完全一致,建议把这些参数也保存到配置文件(比如JSON)里,避免手动输入出错。 - 你训练时设置了
EarlyStopping(restore_best_weights=False),这个其实不太合理,建议改成True,这样模型会保留验证集上表现最好的权重,避免过拟合导致的泛化能力下降。
内容的提问来源于stack exchange,提问作者EMRE BİNNAZ
相关产品推荐
相关产品推荐

