当 .grad 为 None 时,如何使用 pytorch 中的这个简单神经网络向后优化输入层的权重
how do I optmize the weights of the input layer using backward for this simple neural network in pytorch when .grad is None
我定义了以下简单的神经网络:
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()
我可以 运行 并且 print(net.W1) print(net.W2)
打印
Parameter containing:
tensor([[1., 0.],
[2., 3.]], requires_grad=True)
Parameter containing:
tensor([[2.0078],
[1.0078]], requires_grad=True)
所以我的问题是 W1
似乎没有更新。
当我调用 print(net.W1.grad)
时,每次迭代都会得到 None
,这让我很困惑。
我试图将函数定义为一行,如下所示:
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
,但没有任何帮助。
当然我可以对导数和所有内容进行硬编码,但这看起来很痛苦,但我虽然可以在这种情况下使用 .backward()
。
如何使用 backward()
优化 W1
?
我怀疑是下面一行:
self.h = torch.tensor([torch.tanh(self.xW1[0]), torch.tanh(self.xW1[1])])
是罪魁祸首。
新张量 self.h
不继承 self.xW1
的 requires_grad
属性,默认设置为 False
.
您可以调用 self.h = self.tanh(self.xW1)
,然后该操作将逐点应用于 self.xW1
的所有元素。
此外,我建议您使用 PyTorch hooks.
检查您的渐变
我定义了以下简单的神经网络:
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()
我可以 运行 并且 print(net.W1) print(net.W2)
打印
Parameter containing:
tensor([[1., 0.],
[2., 3.]], requires_grad=True)
Parameter containing:
tensor([[2.0078],
[1.0078]], requires_grad=True)
所以我的问题是 W1
似乎没有更新。
当我调用 print(net.W1.grad)
时,每次迭代都会得到 None
,这让我很困惑。
我试图将函数定义为一行,如下所示:
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
,但没有任何帮助。当然我可以对导数和所有内容进行硬编码,但这看起来很痛苦,但我虽然可以在这种情况下使用
.backward()
。
如何使用 backward()
优化 W1
?
我怀疑是下面一行:
self.h = torch.tensor([torch.tanh(self.xW1[0]), torch.tanh(self.xW1[1])])
是罪魁祸首。
新张量 self.h
不继承 self.xW1
的 requires_grad
属性,默认设置为 False
.
您可以调用 self.h = self.tanh(self.xW1)
,然后该操作将逐点应用于 self.xW1
的所有元素。
此外,我建议您使用 PyTorch hooks.
检查您的渐变