es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

RuntimeError: el elemento 0 de los tensores no requiere de gradiente y no tiene una función de gradiente para la regresión lineal con descenso de gradiente usando torch.

Estoy intentando implementar un descenso de gradiente simple para una regresión lineal con PyTorch, como se muestra en este ejemplo en la documentación:

import torch
from torch.autograd import Variable

learning_rate = 0.01
y = 5
x = torch.tensor([3., 0., 1.])
w = torch.tensor([2., 3., 9.], requires_grad=True)
b = torch.tensor(1., requires_grad=True)

for z in range(100):
    y_pred = b + torch.sum(w * x)
    loss = (y_pred - y).pow(2)
    loss = Variable(loss, requires_grad=True)
    # loss.requires_grad = True
    loss.backward()

with torch.no_grad():
    w = w - learning_rate * w.grad
    b = b - learning_rate * b.grad

    w.grad = None
    b.grad = None

Cuando ejecuto el código, obtengo el error RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn.

He leído aquí y aquí que podría solucionarse utilizando:
* loss = Variable(loss, requires_grad=True) lo cual resulta en TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'.
* O loss.requires_grad = True lo cual resulta en RuntimeError: you can only change requires_grad flags of leaf variables.

¿Cómo puedo solucionar esto?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí es que w y b están definidos con requires_grad=True, pero x e y no lo están. Por lo tanto, cuando se llama a loss.backward(), trata de calcular gradientes con respecto a x e y, aunque no son variables hoja. Para solucionar esto, x e y también deben definirse como requires_grad=True:

    import torch
    from torch.autograd import Variable
    
    learning_rate = 0.01
    y = torch.tensor([5.], requires_grad=True)
    x = torch.tensor([3., 0., 1.], requires_grad=True)
    w = torch.tensor([2., 3., 9.], requires_grad=True)
    b = torch.tensor(1., requires_grad=True)
    
    for z in range(100):
        y_pred = b + torch.sum(w * x)
        loss = (y_pred - y).pow(2)
    
        loss.backward()
    
        with torch.no_grad():
            w -= learning_rate * w.grad
            b -= learning_rate * b.grad
            x.grad.zero_()
            y.grad.zero_()
            w.grad.zero_()
            b.grad.zero_()
    

    Ahora loss se calcula con gradientes habilitados para todas las variables y loss.backward() puede calcular gradientes con respecto a todas las variables. Note que también necesitamos reiniciar los gradientes de todas las variables en cada iteración con x.grad.zero_() y llamadas similares, ya que PyTorch acumula los gradientes de forma predeterminada.

Comments are closed.