PyTorch行为识别模型无法训练损失不下降,同结构Keras模型可正常运行
问题核心成因
你代码里最致命的问题是在forward函数中动态创建AvgPool1d层,这会导致梯度无法正常反向传播到前面的卷积层,相当于前面的参数根本不会更新,自然损失不下降、准确率不上升。其他次要问题也会加剧不收敛的情况。
具体问题与对应解决方法
1. 动态创建池化层问题
你在
forward方法中每次前向传播时都重新实例化nn.AvgPool1d并赋值给self.layer_9,该层不会被注册到模型的计算图中,反向传播时梯度无法回传至浅层卷积层。
解决:把动态池化换成全局自适应平均池化,在__init__中定义固定层:# 在__init__里加这行,删掉原来的layer9注释和forward里动态创建的代码 self.global_avg_pool = nn.AdaptiveAvgPool1d(1)forward里对应的位置改成:
x = self.global_avg_pool(x)2. 学习率设置不合理
Adam优化器默认推荐学习率是
1e-3,你初始用的0.1过高,哪怕你下调过,如果还是远高于1e-3的话,会导致参数一直在最优区间附近震荡,无法收敛。
解决:直接把优化器学习率设为1e-3,如果还是震荡再降到3e-4或1e-4:optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)3. 没有切换模型的train/eval模式
PyTorch的Dropout层在训练和验证阶段行为不同,你训练时没有显式启用train模式,验证时也没有关闭Dropout,会导致结果不准、训练不稳定。
解决:训练循环开始前加model.train(),每次epoch结束计算准确率、损失前加model.eval(),计算完成后再加model.train()切回训练模式。4. 工具方法依赖全局变量
你在
calculate_accuracy、calculate_loss方法中直接调用全局变量model,而不是self,如果全局变量名变动会直接出错,修改成调用自身即可:# 把model.forward改成self.forward output = self.forward(X.float())5. 预处理一致性问题
确认你PyTorch版本的数据预处理和Keras版本完全一致:输入是否做了逐通道的均值方差归一化、标签是否是从0开始的连续整数(6分类要求标签范围是05,不是16)。
验证方法
修改完成后,先取10~20个样本反复训练10个epoch,如果损失能降到接近0、准确率接近100%,说明模型已经可以正常训练,再换成全量数据集跑即可。
内容的提问来源于stack exchange,提问作者Prakyath Kantharaju

