Zexian Li

Pytorch Debug小记

2020-10-21 · 2 min read
Pytorch

THCUNN/BCECriterion.cu:42: Assertion `input >= 0. && input <= 1.` failed.

直接原因:torch.nn.BSEloss()函数输入值不在0-1的范围内
根本原因:网络参数运算过程中出现NAN数值破坏最终结果
bug定位过程:
初始化模型后,第一个epoch即有一定几率报错,排查数据后,将学习率设置为1e-10时仍可偶尔复现该错误,故排除模型训飞(反向传播时偶有极大梯度,在部分层处发生梯度爆炸);
猜测是模型初始化问题,舍弃框架原有初始化方式,改用kaiming_normal方法,错误仍产生,排除初始化参数时造成的NAN;
模型最后一层为Sigmoid,原则上会限制输入在0-1范围内,故得知NAN发生在模型运行中,才发生了Sigmoid(tensor(NAN))==NAN的错误;
猜测是LayerNorm连续遇到不同类型数据,通过线性放缩将模型带飞,将batch_size从2改到16,问题消失。
补充思路:
使用binary_cross_entropy_with_logits函数替代Sigmoid+BSEloss()函数;
使用torch.clamp(0,1)将数据限制在特定范围内(不靠谱);
使用x = torch.where(torch.isnan(x), torch.zeros_like(x), x)将数据限制在特定范围内(不靠谱);
补充知识:
Pytorch的torch.nn.BSEloss()函数在求梯度时进行截断操作,最多仅能传递-100的梯度;

Bad decisions make good stories.