В основном, когда вы создаете новый тензор, например torch.nn.Parameter()
или torch.tensor()
, вы создаете листовой узел тензор.
И когда вы делаете что-то вроде c=a+1
, c
будет промежуточным узлом . Вы можете print(c.is_leaf)
проверить, является ли тензор листовым узлом или нет. Pytorch не будет вычислять градиент промежуточного узла по умолчанию.
В вашем фрагменте кода a
, b
, d
- это тензор конечных узлов, а c
- промежуточный узел. c.grad
будет None
, так как pytorch не вычисляет градиент для промежуточного узла. a
изолируется от графика, когда вы звоните loss.backword()
. Вот почему a.grad
также None
.
Если вы измените код на этот
a = torch.nn.Parameter(torch.randn(1, requires_grad=True, dtype=torch.float, device=device))
b = torch.nn.Parameter(torch.randn(1, requires_grad=True, dtype=torch.float, device=device))
c = a + 1
d = c
for epoch in range(n_epochs):
yhat = d + b * x_train_tensor
error = y_train_tensor - yhat
loss = (error ** 2).mean()
loss.backward()
print(a.grad) # Not None
print(b.grad) # Not None
print(c.grad) # None
print(d.grad) # None
Вы обнаружите, что a
и b
имеют градиенты, но c.grad
и d.grad
равны None, потому что онипромежуточный узел.