PyTorch: RuntimeError: элемент 0 кортежа переменных является изменчивым

Я тренирую модель на основе LSTM в PyTorch 0.3.1.

Моя проблема в том, что после увеличения скорости обучения я всегда получаю RuntimeError высказывание: element 0 of variables tuple is volatile.

Это происходит не в начале, а после некоторого обучения, например, в эпоху 3, 4, 5.. и т.д.

При поиске этой ошибки я нашел этот вопрос в Stackoverflow, предлагающий использовать zero_grad(). Но это уже использовалось, когда произошла ошибка.

Итак, мои вопросы:

  • Что означает, что элемент переменной является изменчивым?
  • И каковы возможные причины того, что элемент переменных становится «изменчивым»?
  • Есть ли способ проверить, какая переменная содержит изменчивый элемент, чтобы я мог отследить проблему?

Заранее большое спасибо за любую помощь!

Вот код шага обучения, который я использую:

for epoch in range(num_epochs):
    states = (Var(torch.zeros(num_layers, batch_size, hidden_size)), 
              Var(torch.zeros(num_layers, batch_size, hidden_size)))
    new_batch = True
    step = 0
    epoch_loss = []
    print('Epoch: ', epoch+1)
    for i in range(0, token_ids.size(1) - seq_length, seq_length):
        #print(i)
        input_sequence = Var(token_ids[:,i:i+seq_length])
        target_sequence = Var(token_ids[:,(i+1):(i+1)+seq_length])
        entity_target_sequence = Var(entety_targets[:,(i+1):(i+1)+seq_length]).contiguous()

        if int(input_sequence )== 0:
            states = (Var(torch.zeros(num_layers, batch_size, hidden_size)), 
                      Var(torch.zeros(num_layers, batch_size, hidden_size)))
            print('New Document')
        model.zero_grad()
        states = detach(states)
        out, states, z = model(input_sequence, states)

        if new_batch:
            loss = loss_func(out, target_sequence.view(-1)) + bce_loss(z, entity_target_sequence)
            new_batch = False
        else:
            loss += loss_func(out, target_sequence.view(-1)) + bce_loss(z, entity_target_sequence)
        if (i+1) % wbatch_size == 0:
            step += 1 // seq_length
            if step % 10 == 0:
                epoch_loss.append((loss.data[0]/wbatch_size))
                print ('Epoch [%d/%d], Step[%d/%d], Loss: %.3f' % (epoch+1, num_epochs, step, num_wbatches, (loss.data[0]/wbatch_size)))
                sys.stdout.flush()

            loss.backward(retain_graph=True)
            torch.nn.utils.clip_grad_norm(model.parameters(), 0.5)
            optimizer.step()
            new_batch = True

(Я не упомянул саму модель, чтобы избежать стены кода и сохранить читабельность, но если это поможет решить проблему, я, конечно, могу добавить код.)

Проследить:

Traceback (most recent call last):
  File "ent_lm.py", line 223, in <module>
    loss.backward(retain_graph=True)
  File "/usr/local/lib/python3.6/site-packages/torch/autograd/variable.py", line 167, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph, retain_variables)
  File "/usr/local/lib/python3.6/site-packages/torch/autograd/__init__.py", line 99, in backward
    variables, grad_variables, retain_graph)

person MBT    schedule 28.02.2018    source источник


Ответы (1)


Код, который вы предоставили, выглядит нормально.

Ошибка может возникнуть во время одной из следующих двух функций.

states = detach(states)
out, states, z = model(input_sequence, states)

Я думаю, что отчасти причина может заключаться в том, что вам требуется «сохранить график», но вы продолжаете сбрасывать график, когда отсоединяете состояния или делаете что-то еще в своей модели.

person Steven    schedule 28.02.2018
comment
Спасибо за ваш ответ! Есть ли способ отследить это? Это означает любой способ проверить, какая из переменных вызывает это в какой позиции. У вас есть какой-нибудь ресурс, где я могу прочитать о том, что на самом деле означает, что элемент кортежа переменных является изменчивым? - person MBT; 28.02.2018
comment
Подробнее о volatile можно прочитать здесь: pytorch.org/ docs/master/ Я бы проверил это, сначала удалив continue_graph=True, так как вы не используете модель дважды, поэтому вам не нужно сохранять старые градиенты и двигаться дальше. - person Steven; 28.02.2018