model.parameters () не создает итерацию тензоров - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь использовать torch.nn.utils.clip_grad_norm_ (), для которого требуется итерация Tensors. См. Ниже

for epoch in progress_bar(range(num_epochs)): 
    lstm.train()
    outputs = lstm(trainX.to(device))
    optimizer.zero_grad()
    torch.nn.utils.clip_grad_norm_(lstm.parameters(), 1)

Мои ошибки кода с:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-168-4cd34e6fd44d> in <module>
     28     lstm.train()
     29     outputs = lstm(trainX.to(device))
---> 30     torch.nn.utils.clip_grad_norm_(lstm.parameters(), 1)
     31 
     32 

/opt/conda/lib/python3.6/site-packages/torch/nn/utils/clip_grad.py in clip_grad_norm_(parameters, max_norm, norm_type)
     28         total_norm = max(p.grad.detach().abs().max() for p in parameters)
     29     else:
---> 30         total_norm = torch.norm(torch.stack([torch.norm(p.grad.detach(), norm_type) for p in parameters]), norm_type)
     31     clip_coef = max_norm / (total_norm + 1e-6)
     32     if clip_coef < 1:

RuntimeError: stack expects a non-empty TensorList

Если я использую lstm.parameters (), я получаю список параметров вместо списка тензоров:

<class 'torch.nn.parameter.Parameter'> torch.Size([2048, 1])
<class 'torch.nn.parameter.Parameter'> torch.Size([2048, 512])
<class 'torch.nn.parameter.Parameter'> torch.Size([2048])
<class 'torch.nn.parameter.Parameter'> torch.Size([2048])
<class 'torch.nn.parameter.Parameter'> torch.Size([2048, 512])
<class 'torch.nn.parameter.Parameter'> torch.Size([2048, 512])
<class 'torch.nn.parameter.Parameter'> torch.Size([2048])
<class 'torch.nn.parameter.Parameter'> torch.Size([2048])
<class 'torch.nn.parameter.Parameter'> torch.Size([1, 512])
<class 'torch.nn.parameter.Parameter'> torch.Size([1])

Глядя на первый параметр, это список тензоров:

<class 'torch.Tensor'> torch.Size([1])
<class 'torch.Tensor'> torch.Size([1])
<class 'torch.Tensor'> torch.Size([1])
<class 'torch.Tensor'> torch.Size([1])
<class 'torch.Tensor'> torch.Size([1])
<class 'torch.Tensor'> torch.Size([1])
.
.
.

Кто-нибудь знает, что здесь происходит?

1 Ответ

0 голосов
/ 19 июня 2020

PyTorch s clip_grad_norm, как следует из названия, работает с градиентами. Вы должны вычислить loss из output, использовать loss.backward() и затем выполнить градиентную обрезку.

Кроме того, вы должны использовать optimizer.step() после этой операции.

Примерно так:

for epoch in progress_bar(range(num_epochs)): 
    lstm.train()
    for batch in dataloader:
        optimizer.zero_grad()
        outputs = lstm(trainX.to(device))
        loss = my_loss(outputs, targets)
        loss.backward()
        torch.nn.utils.clip_grad_norm_(lstm.parameters(), 1)
        optimizer.step()

У вас не вычислено parameter.grad (это значение None), и это причина вашей ошибки.

...