pytorch 属性错误:"NoneType"对象没有属性"zero_"

htrmnn0y  于 2023-01-20  发布在  其他
关注(0)|答案(2)|浏览(298)

如果展开表达式,则grad子对象变为“无”。不确定原因?有人能给予一些线索吗?如果展开w.grand.zero_(),则抛出错误“AttributeError:“NoneType”对象没有属性“zero_”
谢谢,格涅沙

import torch

x = torch.randint(size = (1,2), high = 10)
w = torch.Tensor([16,-14])
b = 36

y = w * x + b

epoch = 20
learning_rate = 0.01

w1 = torch.rand(size= (1,2), requires_grad= True)
b1 = torch.ones(size = [1], requires_grad= True)

for i in range(epoch):
    y1 = w1 * x + b1

    loss = torch.sum((y1-y)**2)

    loss.backward()

    with torch.no_grad():
        #w1 = w1 - learning_rate * w1.grad  //Not Working : w1.grad becomes "None" not sure how ;(
        #b1 = b1 - learning_rate * b1.grad  

        w1 -= (learning_rate * w1.grad)  // Working code.
        b1 -= (learning_rate * b1.grad)

        w1.grad.zero_()
        b1.grad.zero_()

    print("B ", b1)  
    print("W ", w1)
ee7vknir

ee7vknir1#

问题是,在您的工作代码中,您正在修改具有grad属性的现有变量,而在non-working的情况下,您正在创建一个新变量。
创建新的w1/b1变量时,它没有渐变属性,因为您没有对它调用backward(),而是对“原始”变量调用。
首先,让我们来看看是否真的是这样:

print(id(w1)) # Some id returned here
w1 = w1 - learning_rate * w1.grad

# In case below w1 address doesn't change
# w1 -= learning_rate * w1.grad 

print(id(w1)) # Another id here

现在,你可以原地复制它,而不刹车,但这样做是没有意义的,你的工作案例要清楚得多,但为了后代的利益:

w1.copy_(w1 - learning_rate * w1.grad)
z18hc3ub

z18hc3ub2#

您提供的代码使用梯度下降更新参数w和B,在第一行中,w.grad是损失函数相对于参数w的梯度,lr是学习速率,一个标量值,用于确定梯度方向上的步长。
第二行B = b-b·grad * lr以相同的方式更新参数b,即减去损失相对于b的梯度乘以学习速率。
但是,第二行不正确,应该是b -= b.grad * lr,而不是b = b - b.grad * lr
使用B = b-b.grad * lr将导致参数b被重新指定为新值,但原始b不会被更新,因此,b的值将为None。
另一方面,使用B -= b.grad * lr将在原处更新b的值,因此原始b将被更新,其值将不是None。

相关问题