PyTorch GRU文本分类训练损失不下降且验证准确率无变化问题
问题排查与解决方案
- 首先是优化器参数设置错误,你当前设置的
weight_decay=0.9数值过大:常规的权重衰减系数取值通常在1e-5 ~ 1e-3区间,0.9的权重衰减会在每一步参数更新时强制将参数值压缩至接近0,仅需几轮训练模型参数就会失去拟合能力,梯度近乎消失,最终导致训练和验证损失都不再变化,模型输出塌缩为固定值。 - 其次是全连接层设计缺陷:你的分类头用两层
nn.Linear堆叠但没有添加非线性激活函数(比如nn.ReLU),两层线性层等价于单层线性变换,模型表达能力严重不足,无法学习到文本特征和标签之间的复杂映射关系,很容易直接拟合数据集中占比最高的类别。
修正后的分类头代码示例:
self.fc = nn.Sequential( nn.Linear(in_features=model_param.hidden_dim, out_features=128), nn.ReLU(), nn.Dropout(0.3), nn.Linear(in_features=128, out_features=model_param.output_dim) )
- 序列特征提取方式不合理:当前仅取GRU输出的最后一个时间步特征作为整句表示,对于长文本来说,前面的上下文信息会被RNN的遗忘门过滤,特征损失严重。可以改为取所有时间步特征的平均池化/最大池化结果,或者将池化结果与最后一步特征拼接后输入分类头,提升特征利用率。
- 优化器与学习率适配问题:纯SGD优化器对学习率的敏感度很高,如果学习率设置不合理(过高或过低)都会导致训练异常。可以更换为Adam优化器,自适应学习率机制对文本分类任务的适配性更好,收敛速度也更快。
- 预训练 embedding 冻结限制:如果你的预训练词向量和当前任务的领域匹配度较低,冻结embedding层会直接限制模型的特征学习上限,可以先冻结embedding层训练5-10轮,再放开embedding层的参数更新权限整体微调,通常能提升模型效果。
- 类别不均衡适配:针对当前数据集单标签占比83%的情况,可以在交叉熵损失中传入类别权重参数,降低多数类的损失权重,避免模型倾向于预测多数类获得高准确率:
loss_func = nn.CrossEntropyLoss(weight=class_weights.to(device))
其中class_weights可以根据每个类别的样本占比计算得到。
- 数据加载校验建议:可以先跑小批量样本验证数据流程是否正常,比如输出几个样本的文本id、对应标签、模型预测结果,排查是否存在标签映射错误、文本id索引错乱等数据层面的问题。
内容的提问来源于stack exchange,提问作者MilkcatGod
相关产品推荐
相关产品推荐

