PyTorch命名实体识别模型保存后准确率骤降为零求助
模型保存加载后准确率骤降的排查方案
我用PyTorch构建了一个命名实体识别(NER)模型,训练40轮后验证准确率约90%,测试集准确率约87%,但保存模型重新加载后,准确率几乎为0。已设置PyTorch随机种子,问题仍存在。
1. BatchNorm层运行模式错误
模型的Sent_Layer_Stack_PostS包含nn.BatchNorm1d(num_features=3600),训练时模型处于train()模式,BatchNorm会实时更新均值和方差;但推理时必须切换到eval()模式,否则BatchNorm会继续计算当前批次的均值方差,导致数据分布严重偏移。
- 检查点:测试和预测函数中虽调用了
model.eval(),但需确认所有推理场景都保持该模式,避免中途意外切换回train()。
2. Embedding层初始化方式错误
模型初始化时直接使用私有属性_weight赋值Embedding权重,可能导致权重未被正确注册到state_dict,加载后Embedding层使用随机权重,直接输出无效结果:
# 错误写法 self.SpanEmbed = nn.Embedding(num_embeddings=len(char2idx),embedding_dim=EMBEDDING_DIM,_weight = torch.from_numpy(embed_matrix)).type(torch.float)
正确写法应通过公开接口赋值权重:
self.SpanEmbed = nn.Embedding(num_embeddings=len(char2idx), embedding_dim=EMBEDDING_DIM) self.SpanEmbed.weight.data = torch.from_numpy(embed_matrix).float() # 若需冻结权重,添加:self.SpanEmbed.weight.requires_grad = False
3. 训练与推理的输入预处理不一致
- 检查
pad_encode_text函数,确保训练和预测时的padding长度、字符到索引的映射char2idx完全一致,避免加载模型时char2idx未同步加载导致编码错误。 - 预测时用numpy拼接生成的
pred_input,需确认数据类型与训练时一致(模型forward中强制转torch.long,但输入本身类型错误会导致Embedding层输出异常)。
4. 模型保存/加载的设备不匹配
若训练用GPU、加载用CPU(或反之),需确保map_location设置正确:
- 测试函数中
torch.load未指定map_location,若训练时模型在GPU,加载时默认会加载到GPU,若当前环境无GPU会报错;跨设备加载时需手动指定:
checkpoint = torch.load(file_path, map_location=torch.device(device)) test_model.load_state_dict(checkpoint['model_state_dict']) test_model = test_model.to(device)
5. 准确率计算逻辑的误导性
当前get_accuracy函数要求样本所有标签完全预测正确才算准确,逻辑过于严苛:
comp_out = np.where(np.sum(np.equal(y_pred_arr,y_true_arr),axis=1)<y_true_arr.shape[1],0,1)
可临时修改为单标签匹配率排查模型输出是否完全随机:
def get_accuracy(y_pred,y_true): y_pred_arr = y_pred.cpu().numpy() y_true_arr = y_true.cpu().numpy() return np.mean(y_pred_arr == y_true_arr)
6. LSTM层状态处理异常
模型仅取LSTM最后一步的hidden state作为输出:
span_out_tot,(span_out,span_c_state_out) = self.Span_Layer_Stack_PreS(span_input.type(torch.long)) span_out = torch.hstack([span_out[0],span_out[1]])
虽LSTM在eval模式下默认不保留状态,但需确认推理时输入的batch size、序列长度与训练时一致,避免维度不匹配导致输出异常。
内容的提问来源于stack exchange,提问作者Tunde
相关产品推荐
相关产品推荐

