¿Cómo puedo optimizar los pesos de la capa de entrada utilizando backward en esta red neuronal simple en PyTorch cuando .grad es None?
Definí la siguiente red neuronal simple:
import torch
import torch.nn as nn
X = torch.tensor(([1, 2]), dtype=torch.float)
y = torch.tensor([1.])
learning_rate = 0.001
class Neural_Network(nn.Module):
def __init__(self, ):
super(Neural_Network, self).__init__()
self.W1 = torch.nn.Parameter(torch.tensor(([1, 0], [2, 3]), dtype=torch.float, requires_grad=True))
self.W2 = torch.nn.Parameter(torch.tensor(([2], [1]), dtype=torch.float, requires_grad=True))
def forward(self, X):
self.xW1 = torch.matmul(X, self.W1)
self.h = torch.tensor([torch.tanh(self.xW1[0]), torch.tanh(self.xW1[1])])
return torch.sigmoid(torch.matmul(self.h, self.W2))
net = Neural_Network()
for z in range(60):
loss = (y - net(X))**2
optim = torch.optim.SGD(net.parameters(), lr=learning_rate, momentum=0.9)
loss = criterion(net(X), y)
loss.backward()
optim.step()
Puedo ejecutarlo y print(net.W1) print(net.W2)
imprime
Parameter containing:
tensor([[1., 0.],
[2., 3.]], requires_grad=True)
Parameter containing:
tensor([[2.0078],
[1.0078]], requires_grad=True)
Así que mi problema es que parece que W1
no se está actualizando.
Cuando llamo a print(net.W1.grad)
obtengo None
en cada iteración, lo cual me confunde mucho.
- Intenté definir la función en una línea así:
loss = (y - torch.sigmoid(math.tanh(x[0] * W_1[0][0] + x[1] * W_1[1][0]) * W_2[0] + math.tanh(x[0] * W_1[0][1] + x[1] * W_1[1][1]) * W_2[1])) ** 2
pero no ayudó en nada.
- Seguro que podría codificar la derivada y todo, pero parece doloroso y pensé que
backward()
se puede usar en este caso.
¿Cómo puedo optimizar W1
usando backward()
?
davy.ai
Para optimizar
W1
conbackward()
, necesitas modificar el código en dos lugares:Agrega
optim.zero_grad()
dentro del bucle antes deloss.backward()
para limpiar los gradientes de cada parámetro antes de calcular los gradientes para el lote actual de datos.Aquí está el código modificado:
Ahora, cuando ejecutes
print(net.W1.grad)
después del entrenamiento, deberías ver los gradientes actualizados.