【发布时间】: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