嵌入层输出nan

时间:2019-09-18 06:59:52

标签: deep-learning pytorch transformer seq2seq

我正在尝试学习seq2seq模型。 嵌入层位于编码器中,有时经过一些迭代后会输出nan值。 我无法确定原因。 我该如何解决? 问题是下面代码中的forward函数中的第一个emb_layer。


class TransformerEncoder(nn.Module):
    def __init__(self, vocab_size, hidden_size=1024, num_layers=6, dropout=0.2, input_pad=1, batch_first=False, embedder=None, init_weight=0.1):
        super(TransformerEncoder, self).__init__()
        self.input_pad = input_pad
        self.vocab_size = vocab_size
        self.num_layers = num_layers
        self.embedder = embedder

        if embedder is not None:
            self.emb_layer = embedder
        else:
            self.emb_layer = nn.Embedding(vocab_size, hidden_size, padding_idx=1)

        self.positional_encoder = PositionalEncoder()
        self.transformer_layers = nn.ModuleList()
        for _ in range(num_layers):
            self.transformer_layers.append(
                    TransformerEncoderBlock(num_heads=8, embedding_dim=1024, dropout=dropout))

    def set_mask(self, inputs):
        self.input_mask = (inputs == self.input_pad).unsqueeze(1)

    def forward(self, inputs):
        x = self.emb_layer(inputs)
        x = self.positional_encoder(x)

3 个答案:

答案 0 :(得分:0)

看起来有些权重变得微不足道。可能的原因之一是,在某些迭代中,图层输出为+ -inf。如果向前输出为+ -inf,则向后输出为+ -inf,并且当inf-inf = none时,权重将变为none,并且在随后的所有迭代中均不输出。

您可以仅通过跟踪emb_layer中的inf输出来进行检查。

如果这是原因,请尝试避免使用可能返回inf值的函数。

答案 1 :(得分:0)

与我所遵循的教程相比,我的数据库是如此之小,并且我的嵌入对于获得可用数据的方式来说很大,因此NaN最终会通过网络传播。使我的嵌入网络更小(矩阵中的因子/列数更少)可以为我解决NaN问题。

答案 2 :(得分:0)

通常是输入比权重更容易变成 nan(要么太高要么太低)。也许这些开始是不正确的,并在一些梯度之后恶化。您可以通过简单的条件检查运行张量或 np.array 来识别这些输入,例如:

print("Inp value too high") if len(bert_embeddings[bert_embeddings>1000]) > 1 else None

初学者的一个常见错误是使用 torch.empty 而不是 torch.zeros。随着时间的推移,这总是会导致 Nan。

如果您的所有输入都很好,那么就是梯度消失或爆炸的问题。看几次迭代后问题是否恶化。探索通常可以解决这些类型问题的不同激活或裁剪梯度。如果您使用的是最新的优化器,通常无需担心调整学习率。