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

PyTorch LSTM二分类文本分类模型训练无提升问题求助

二分类LSTM模型无法有效学习的可能原因及解决建议
  • 类别不平衡问题
    损失稳定在0.7左右(接近-ln(0.5)≈0.693)且只预测0类,最常见的原因是训练集里0类样本占比极高。模型会通过偏向多数类来最小化损失,此时即使随机预测多数类也能得到“看似合理”的损失,但完全没有学习到有效特征。
    解决:统计训练集中两类样本的数量,若存在不平衡,可采用过采样少数类、欠采样多数类,或使用带权重的损失函数(比如BCELoss(weight=class_weights),class_weights根据类别占比计算)。

  • 模型输出与损失函数不匹配
    你的代码存在关键矛盾:二分类场景下,若使用BCELoss,模型最后一层应输出1个神经元(对应样本属于正类的概率),但如果num_classes设为2,fc层会输出2维向量,再经过sigmoid后每个维度都是0-1的概率,这和BCELoss的预期输入不匹配(BCELoss要求输入和目标形状一致,且目标是单维度的0/1标签)。
    同时,手动加sigmoid再用BCELoss的数值稳定性不如直接用BCEWithLogitsLoss(该损失函数内部计算sigmoid,避免梯度消失)。
    解决:

    • 若坚持用sigmoid+BCELoss:将num_classes改为1,fc层输出设为1维,同时确保标签labels是float类型且形状为(batch_size, 1)或(batch_size,)。
    • 更推荐的方式:去掉模型中的torch.sigmoid(out),改用BCEWithLogitsLoss作为损失函数,同样将num_classes设为1。
    • 若想用2维输出,应使用CrossEntropyLoss,此时模型最后一层不需要激活函数,标签labels应为long类型的类别索引(0或1)。
  • 序列最后时间步输出的有效性问题
    代码中取out[:, -1]作为LSTM的输出喂给全连接层,但如果输入序列经过padding(padding_idx=0),最后一个位置很可能是填充的0 token,对应的embedding是全0向量,LSTM在该位置的输出不包含有效语义信息,导致模型无法学习到有用特征。
    解决:

    • 改用LSTM的隐藏状态输出:out, (h_n, c_n),取h_n[-1](最后一层的隐藏状态)作为全连接层的输入,LSTM的隐藏状态是对整个序列的编码,比最后一个时间步的输出更可靠。
    • 记录每个序列的有效长度,取有效长度对应的最后一个时间步的输出,而非固定取最后一个位置。
  • 数据预处理与输入有效性问题
    检查以下几点:

    • 确认输入序列sequences不是全0向量(比如tokenization错误,所有文本都被映射为0),可随机打印几个样本的序列值验证。
    • 确认标签labels的类型是float(BCELoss要求目标是浮点型),若为long类型会导致损失计算异常。
    • 检查词汇表大小vocabulary_size是否正确,若设置过小,会导致大量token被映射为未知token(通常是0或其他特殊值),影响embedding的有效性。
  • 学习率与初始化问题
    虽你调整过学习率,但仍需确认:

    • 学习率是否过高或过低:过高会导致损失震荡,过低则模型学习缓慢甚至停滞,可尝试1e-4到1e-3的范围测试。
    • 是否使用预训练词向量:随机初始化的embedding在小数据集上可能难以收敛,若有合适的预训练词向量(如Word2Vec、GloVe),可加载到embedding层,冻结或微调该层。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:25:19