【发布时间】:2020-07-28 05:27:56
【问题描述】:
我第一次玩 pytorch,我注意到在训练我的神经网络时,大约四分之一左右的损失会左转趋向无穷大,然后不久就变成了 nan。我已经看到了一些关于 nan-ing 的其他问题,但那里的建议似乎本质上是为了进行规范化;但是我下面的网的第一层是这样的规范化,我仍然看到这个问题!完整的网络是 a bit convoluted,但我已经进行了一些调试以尝试生成一个非常小的、易于理解的网络,它仍然显示相同的问题。
代码如下;它由 16 个输入 0-1 组成,它们通过批量标准化,然后通过全连接层传递到单个输出。我希望它学习始终输出 1 的函数,因此我将 1 的平方误差作为损失。
import torch as t
import torch.nn as tn
import torch.optim as to
if __name__ == '__main__':
board = t.rand([1,1,1,16])
net = tn.Sequential \
( tn.BatchNorm2d(1)
, tn.Conv2d(1, 1, [1,16])
)
optimizer = to.SGD(net.parameters(), lr=0.1)
for i in range(10):
net.zero_grad()
nn_outputs = net.forward(board)
loss = t.sum((nn_outputs - 1)**2)
print(i, nn_outputs, loss)
loss.backward()
optimizer.step()
如果你运行几次,最终你会看到如下所示的运行:
0 tensor([[[[-0.7594]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(3.0953, grad_fn=<SumBackward0>)
1 tensor([[[[4.0954]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(9.5812, grad_fn=<SumBackward0>)
2 tensor([[[[5.5210]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(20.4391, grad_fn=<SumBackward0>)
3 tensor([[[[-3.4042]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(19.3966, grad_fn=<SumBackward0>)
4 tensor([[[[823.6523]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(676756.7500, grad_fn=<SumBackward0>)
5 tensor([[[[3.5471e+08]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(1.2582e+17, grad_fn=<SumBackward0>)
6 tensor([[[[2.8560e+25]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(inf, grad_fn=<SumBackward0>)
7 tensor([[[[inf]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(inf, grad_fn=<SumBackward0>)
8 tensor([[[[nan]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(nan, grad_fn=<SumBackward0>)
9 tensor([[[[nan]]]], grad_fn=<MkldnnConvolutionBackward>) tensor(nan, grad_fn=<SumBackward0>)
为什么我的损失归 nan 了,我该怎么办?
【问题讨论】:
-
你试过不规范化运行吗?你确定它的 bn 吗?
-
@BedirYilmaz 是的,如果没有批量标准化,这会可靠地产生接近零的损失。不过,我承认我没有测试没有全连接层会发生什么,哈哈!
标签: python neural-network pytorch batch-normalization