【问题标题】:Repetitive word predictions in RNNRNN 中的重复词预测
【发布时间】:2022-10-05 00:10:32
【问题描述】:

你好亲爱的社区,

我正在训练一个 Seq2Seq 模型来根据图表生成一个问题。 train 和 val loss 都在收敛,但生成的问题(在训练集或测试集上)是无意义的,并且主要包含重复的标记。我尝试了各种超参数并仔细检查了输入和输出张量。

我觉得奇怪的是输出out(见下文)开始包含一些我认为异常高的值。这开始发生在第一个时代的一半左右:

Out:  tensor([[  0.2016, 103.7198,  90.4739,  ...,   0.9419,   0.4810,  -0.2869]]

我的猜测是渐变消失/爆炸,我以为我已经通过渐变裁剪处理了,但现在我不确定:

for p in model_params:
        p.register_hook(lambda grad: torch.clamp(
            grad, -clip_value, clip_value))

下面是训练曲线(10K 个样本,batch size=128,lr=0.065,lr_decay=0.99,dropout=0.25)

编码器(一个 GNN,学习输入图的节点嵌入,由大约 3-4 个节点和边组成。通过汇集节点嵌入并将它们作为初始隐藏状态提供给解码器,获得单个图嵌入):

class QuestionGraphGNN(torch.nn.Module):
    def __init__(self,
                 in_channels,
                 hidden_channels,
                 out_channels,
                 dropout,
                 aggr='mean'):
        super(QuestionGraphGNN, self).__init__()
        nn1 = torch.nn.Sequential(
            torch.nn.Linear(in_channels, hidden_channels),
            torch.nn.ReLU(),
            torch.nn.Linear(hidden_channels, in_channels * hidden_channels))
        self.conv = NNConv(in_channels, hidden_channels, nn1, aggr=aggr)
        self.lin = nn.Linear(hidden_channels, out_channels)
        self.dropout = dropout

    def forward(self, x, edge_index, edge_attr):
        x = self.conv(x, edge_index, edge_attr)
        x = F.leaky_relu(x)
        x = F.dropout(x, p=self.dropout)
        x = self.lin(x)
        return x

*解码器(上面的 out 向量打印在 forward() 函数中):

class DecoderRNN(nn.Module):
    def __init__(self,
                 embedding_size,
                 output_size,
                 dropout):
        super(DecoderRNN, self).__init__()
        self.output_size = output_size
        self.dropout = dropout

        self.embedding = nn.Embedding(output_size, embedding_size)
        self.gru1 = nn.GRU(embedding_size, embedding_size)
        self.gru2 = nn.GRU(embedding_size, embedding_size)
        self.gru3 = nn.GRU(embedding_size, embedding_size)
        self.out = nn.Linear(embedding_size, output_size)
        self.logsoftmax = nn.LogSoftmax(dim=1)

    def forward(self, inp, hidden):
        output = self.embedding(inp).view(1, 1, -1)
        output = F.leaky_relu(output)

        output = F.dropout(output, p=self.dropout)
        output, hidden = self.gru1(output, hidden)

        output = F.dropout(output, p=self.dropout)
        output, hidden = self.gru2(output, hidden)
        output, hidden = self.gru3(output, hidden)

        out = self.out(output[0])
        print("Out: ", out)
        output = self.logsoftmax(out)
        return output, hidden

我正在使用 PyTorchs NLLLoss()。 优化器是 SGD。 我在后向和优化步骤之前调用optimizer.zero_grad(),并切换训练/评估模式以进行训练、评估和测试。

您对此有何看法?

非常感谢!

【问题讨论】:

    标签: python pytorch nlp recurrent-neural-network gnn


    【解决方案1】:

    您的代码看起来不错,并且鉴于您发布的训练/验证曲线,它看起来运行良好。

    你是如何生成文本样本的?您是否只是将模型预测的概率最高的单词附加到输入序列的末尾,然后再次调用?这种称为贪婪采样的采样技术可能会导致您描述的行为。也许另一种采样技术会有所帮助(请参阅光束搜索https://medium.com/geekculture/beam-search-decoding-for-text-generation-in-python-9184699f0120)?

    【讨论】:

      猜你喜欢
      • 2018-06-20
      • 1970-01-01
      • 1970-01-01
      • 2014-08-19
      • 1970-01-01
      • 2017-05-16
      • 2017-01-01
      • 2023-03-28
      • 1970-01-01
      相关资源
      最近更新 更多