PyTorch nn.Linear layer output nan 在格式良好的输入和权重上

Posted

技术标签:

【中文标题】PyTorch nn.Linear layer output nan 在格式良好的输入和权重上【英文标题】:PyTorch nn.Linear layer output nan on well formed input and weights 【发布时间】:2018-07-11 13:14:34 【问题描述】:

(错误的回购:https://github.com/zihualiu/pytorch_linear_bug)

我最近在 Pytorch 中遇到了一个奇怪的错误,希望您能帮助我。在我的一个网络中,我有一个完全连接的层,表示为 net.fc_h1。然而,在训练期间,我意识到这一层在激活之前会输出 NaN。所以我把它放在 pdb 中,希望它能给我带来一些东西。以下是日志:

# in network declaration:
def forward(self, obs):
    z1 = self.fc_h1(obs)
    if np.isnan(np.sum(z1.data.numpy())):
        pdb.set_trace()
    h1 = F.tanh(z1)
    ...

NaN 确实被捕获了,但是我在 pdb 中意识到,如果你再次运行该操作,结果会很明显:​​

(Pdb) z1.sum()
Variable containing:
nan
[torch.FloatTensor of size 1]

(Pdb) self.fc_h1(obs).sum()
Variable containing:
771.5120
[torch.FloatTensor of size 1]

当我检查我的输入或权重是否包含 NaN 时,我得到以下信息: (pdb) self.fc_h1.weight.max() 变量包含: 0.2482 [torch.FloatTensor 大小为 1]

(Pdb) self.fc_h1.weight.mean()
Variable containing:
1.00000e-03 *
  1.7761
[torch.FloatTensor of size 1]

(Pdb) self.fc_h1.weight.min()
Variable containing:
-0.2504
[torch.FloatTensor of size 1]

(Pdb) obs.max()
Variable containing:
 6.9884
[torch.FloatTensor of size 1]

(Pdb) obs.min()
Variable containing:
-6.7855
[torch.FloatTensor of size 1]

(Pdb) obs.mean()
Variable containing:
1.00000e-02 *
 -1.5033
[torch.FloatTensor of size 1] 
(Pdb) self.fc_h1.bias.max()
Variable containing:
 0.2482
[torch.FloatTensor of size 1]

(Pdb) self.fc_h1.bias.mean()
Variable containing:
1.00000e-03 *
  3.9104
[torch.FloatTensor of size 1]

(Pdb) self.fc_h1.bias.min()
Variable containing:
-0.2466
[torch.FloatTensor of size 1]

似乎输入、权重和偏差都处于良好状态。如果一切都很好,关于线性层如何产生 NaN 的任何见解?

编辑:更多怪异 所以我尝试再次运行前向传递,有趣的是,多次前向传递给了我不同的结果:

(Pdb) self.fc_h1(obs)
Variable containing:
 2.2321e-01 -6.2586e-01 -1.9004e-01  ...  -4.2521e-01  8.6175e-01  8.6866e-01
-7.2699e-02  7.8234e-01 -5.8862e-01  ...   2.4041e-01 -1.7577e-01  6.9928e-01
-7.2699e-02  7.8234e-01 -5.8862e-01  ...   2.4041e-01 -1.7577e-01  6.9928e-01
                ...                   ⋱                   ...
-6.4686e-02 -1.5819e+00  5.7410e-01  ...  -6.4127e-01  5.2837e-01 -1.3166e+00
 3.9214e-01  2.8727e-01 -5.5699e-01  ...  -8.3164e-01 -5.1795e-01 -3.7637e-01
-9.6061e-01  1.4780e-01  5.3614e-02  ...  -1.5042e+00  6.0759e-02 -3.6862e-01
[torch.FloatTensor of size 4096x170]

(Pdb) self.fc_h1(obs)
Variable containing:
 2.2321e-01 -6.2586e-01 -1.9004e-01  ...  -4.2521e-01  8.6175e-01  8.6866e-01
-7.2699e-02  7.8234e-01 -5.8862e-01  ...   2.4041e-01 -1.7577e-01  6.9928e-01
-7.2699e-02  7.8234e-01 -5.8862e-01  ...   2.4041e-01 -1.7577e-01  6.9928e-01
                ...                   ⋱                   ...
        nan         nan         nan  ...          nan  5.2837e-01 -1.3166e+00
        nan         nan         nan  ...          nan -5.1795e-01 -3.7637e-01
        nan         nan         nan  ...          nan  6.0759e-02 -3.6862e-01
[torch.FloatTensor of size 4096x170]

我也没有使用 GPU,只使用 CPU。

【问题讨论】:

第一个代码 sn-p 中的h1 是什么?编辑:我的意思是在if np.isnan(np.sum(h1.data.numpy())): 行中,这似乎是在h1 首次定义之前。 @nnnmmm 抱歉打错了,应该是 z1 真的很奇怪。你能把它简化为一个最小的独立示例供我们运行吗? @nnnmmm,我试过......我试图通过提取张量和网络 state_dict 来创建一个非常小的示例。这是回购:github.com/zihualiu/pytorch_linear_bug 所以我尝试从源代码、conda 和 pip 安装 pytorch。他们都没有工作。但是,当我刚刚换到不同的工作站时,该错误似乎消失了。所以我认为这可能只是我的一些环境设置的问题。不过感谢您的建议! 【参考方案1】:

对我来说,我是从 RNN 名称分类示例中复制代码。我添加了优化器和标准模式,而示例是手动执行操作并手动更新权重。我不小心向优化器添加了动量值,这就是导致我的问题的原因。将动量设置为默认值0 修复了它。

【讨论】:

以上是关于PyTorch nn.Linear layer output nan 在格式良好的输入和权重上的主要内容,如果未能解决你的问题,请参考以下文章

pytorch简单框架

PyTorch 使用心得

pytorch 笔记:torch.nn.Linear() VS torch.nn.function.linear()

pytorch 是不是在 nn.Linear 中自动应用 softmax

pytorch之求梯度和nn.Linear的理解

pytorch nn.Linear()详解