最近在复现一个图像分类的模型,用PyTorch写的时候,训练到第3个epoch左右loss就突然变成NaN了,学习率已经调到1e-4还是这样。同样的网络结构和数据,我用TensorFlow(Keras)跑就完全正常,loss稳稳下降。检查过输入数据没有NaN,也试过加梯度裁剪,但还是会炸。想问问大家,PyTorch里有没有什么默认行为(比如损失函数、初始化)和TF不一样,容易导致这种问题?是不是我哪里的写法有坑?求指点。
楼主
26天前
PyTorch训练时loss突然变NaN,换TensorFlow就没问题,是我哪里写错了吗?
请 登录 后发表回复
全部回复
共 3 条
2楼
21天前
我之前也踩过这个坑,PyTorch的CrossEntropyLoss默认会对logits做log_softmax,但如果你自己网络里又加了softmax,那梯度就容易炸。另外检查下有没有用默认的ReLU初始化,TF的Keras对he初始化处理更友好,PyTorch里nn.Linear默认是kaiming_uniform,但某些层组合下还是会不稳。可以试试把loss打印出来看是第几个batch开始出NaN的,多半是某层输出突然爆了。
3楼
21天前
PyTorch这边跨框架复现踩坑太常见了。你可以重点查两个地方:一是损失函数,比如用CrossEntropyLoss时如果输入没做log_softmax,PyTorch的F.nll_loss在某些边界值上会直接爆NaN,TF的categorical_crossentropy默认from_logits=False处理不一样。二是优化器,Adam的eps默认1e-8,TF是1e-7,梯度小的时候PyTorch更容易数值不稳。另外看看有没有在AMP下跑,混合精度里loss scaling没配好也会第三四个epoch才炸。
4楼
20天前
我之前也踩过这个坑,PyTorch和TF在默认初始化上确实有差异,比如Conv层和Linear层的权重初始化方式不一样,TF的Glorot初始化有时更稳一些。你可以先试试手动把权重初始化成xavier或kaiming,再配合梯度裁剪看看。另外检查下有没有在loss里用了log或sqrt,PyTorch对0值更敏感,加个eps可能就解决了。还有个小细节,TF默认会做梯度聚合的数值稳定处理,PyTorch没有,所以偶尔炸一下挺正常的。