【问题标题】:PyTorch LSTM has nan for MSELossPyTorch LSTM 为 MSELoss 提供了 nan
【发布时间】:2020-06-14 01:06:57
【问题描述】:

我的模型是:

class BaselineModel(nn.Module):
    def __init__(self, feature_dim=5, hidden_size=5, num_layers=2, batch_size=32):
        super(BaselineModel, self).__init__()
        self.num_layers = num_layers
        self.hidden_size = hidden_size

        self.lstm = nn.LSTM(input_size=feature_dim,
                            hidden_size=hidden_size, num_layers=num_layers)

    def forward(self, x, hidden):
        lstm_out, hidden = self.lstm(x, hidden)
        return lstm_out, hidden

    def init_hidden(self, batch_size):
        hidden = Variable(next(self.parameters()).data.new(
            self.num_layers, batch_size, self.hidden_size))
        cell = Variable(next(self.parameters()).data.new(
            self.num_layers, batch_size, self.hidden_size))
        return (hidden, cell)

培训如下:

train_loader = torch.utils.data.DataLoader(
    train_set, batch_size=BATCH_SIZE, shuffle=True, **params)

model = BaselineModel(batch_size=BATCH_SIZE)
optimizer = optim.Adam(model.parameters(), lr=0.01, weight_decay=0.0001)
loss_fn = torch.nn.MSELoss(reduction='sum')

for epoch in range(250):

    # hidden = (torch.zeros(2, 13, 5),
    #           torch.zeros(2, 13, 5))
    # model.hidden = hidden
    for i, data in enumerate(train_loader):
        hidden = model.init_hidden(13)
        inputs = data[0]
        outputs = data[1]

        print('inputs',  inputs.size())
        # print('outputs', outputs.size())

        # optimizer.zero_grad()
        model.zero_grad()

        # print('inputs', inputs)
        pred, hidden = model(inputs, hidden)

        loss = loss_fn(pred, outputs)

        loss.backward()
        torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
        optimizer.step()

        print('Epoch: ', epoch, '\ti: ', i, '\tLoss: ', loss)

我已经设置了渐变剪裁,这似乎是推荐的解决方案。但即使在第一步之后,我得到:

Epoch: 0 i: 0 Loss: tensor(nan, grad_fn=)

【问题讨论】:

  • 为什么在 for 迭代中重复隐藏初始化。还有data[0]data[1] 是什么?
  • 这些是我的输入/输出张量
  • 我在每次迭代时都进行初始化,因为我的输入/输出是批量数据
  • 形状和示例张量是什么? Wx + b 在 RNN 香肠中以状态方式链接,因此了解 x 很重要 =)
  • 形状无关紧要,因为前向和反向传播通过,它是内容,层相乘的张量内的值是多少? print('data') =)

标签: python pytorch lstm gradient-descent


【解决方案1】:

我怀疑您的问题与您的输出/data[1] 有关(如果您显示您的 train_set 示例会有所帮助)。运行以下代码不会给出 nan,但我在调用 loss_fn(pred, outputs) 之前手动强制输出形状:

class BaselineModel(nn.Module):
    def __init__(self, feature_dim=5, hidden_size=5, num_layers=2, batch_size=32):
        super(BaselineModel, self).__init__()
        self.num_layers = num_layers
        self.hidden_size = hidden_size

        self.lstm = nn.LSTM(input_size=feature_dim,
                            hidden_size=hidden_size, num_layers=num_layers)

    def forward(self, x, hidden):
        lstm_out, hidden = self.lstm(x, hidden)
        return lstm_out, hidden

    def init_hidden(self, batch_size):
        hidden = Variable(next(self.parameters()).data.new(
            self.num_layers, batch_size, self.hidden_size))
        cell = Variable(next(self.parameters()).data.new(
            self.num_layers, batch_size, self.hidden_size))
        return (hidden, cell)

model = BaselineModel(batch_size=32)
optimizer = optim.Adam(model.parameters(), lr=0.01, weight_decay=0.0001)
loss_fn = torch.nn.MSELoss(reduction='sum')

hidden = model.init_hidden(10)
model.zero_grad()
pred, hidden = model(torch.randn(2,10,5), hidden)
pred.size() #torch.Size([2, 10, 5])
outputs = torch.zeros(2,10,5)

loss = loss_fn(pred, outputs)
loss

loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
optimizer.step()
print(loss)

请注意,产生 nan 值的一个常见原因可能与您的学习阶段的数值稳定性有关,但通常在您看到分歧发生之前,您已经有了第一步的值,这显然不是这里的情况。

【讨论】:

    猜你喜欢
    • 2018-12-10
    • 1970-01-01
    • 2020-08-21
    • 2017-12-14
    • 2019-09-28
    • 2018-09-03
    • 2018-06-21
    • 2023-04-07
    相关资源
    最近更新 更多