Python 添加到(“cuda:0”)后,Pyrotch渐变不起作用
我将给出一组上下文无关的代码。代码在添加“到(设备)”之前起作用 我明白了 检查,这是确认的,因为W1.grad出于某种原因为None 这会在清除梯度后循环。如果我删除所有的.to(设备),这就可以了。在我的GPU上运行这个程序时,我做错了什么Python 添加到(“cuda:0”)后,Pyrotch渐变不起作用,python,neural-network,pytorch,gradient,Python,Neural Network,Pytorch,Gradient,我将给出一组上下文无关的代码。代码在添加“到(设备)”之前起作用 我明白了 检查,这是确认的,因为W1.grad出于某种原因为None 这会在清除梯度后循环。如果我删除所有的.to(设备),这就可以了。在我的GPU上运行这个程序时,我做错了什么 谢谢您的时间。发生这种情况是因为.to返回一个新的非叶张量。在传输到所需设备后,您应该设置requires_grad。另外,变量接口自从pytorch 1.0之前就一直被弃用。它什么也不做(除了在这种情况下作为一种过于复杂的方式来设置requires\u
谢谢您的时间。发生这种情况是因为
.to
返回一个新的非叶张量。在传输到所需设备后,您应该设置requires_grad
。另外,变量
接口自从pytorch 1.0之前就一直被弃用。它什么也不做(除了在这种情况下作为一种过于复杂的方式来设置requires\u grad
)
考虑
W1 = Variable(torch.randn(embedding_dims, vocabulary_size).float(), requires_grad=True).to(device)
这里的问题是有两个不同的张量。分解它,我们可以重写你正在做的
W1a = Variable(torch.randn(embedding_dims, vocabulary_size).float(), requires_grad=True)
W1 = W1a.to(device)
请注意,W1a
需要一个梯度,但是W1
是从W1a
派生的,因此它不被视为叶张量,因此W1a
的.grad
属性将被更新,但W1
不会被更新。在代码中,您不再直接引用W1a
,因此无法访问渐变
相反,你可以这样做
W1 = torch.randn(embedding_dims, vocabulary_size).float().to(device)
W1.required_grad_(True)
将W1
传输到不同设备后,将其正确设置为叶张量
请注意,对于您的具体情况,我们也可以只使用
设备
,数据类型
,需要torch.randn
参数,只需这样做即可
W1 = torch.randn(embedding_dims, vocabulary_size, dtype=torch.float, device=device, requires_grad=True)
大多数初始化新张量的pytorch函数都支持这三个参数,这有助于避免您遇到的问题
回应OP在评论中的补充问题:
在文档中有没有我会遇到的好地方
AFAIK文档并没有专门解决这个问题。它是python中变量的工作方式和pytorch中自动加载机制的工作方式的结合
假设您对python中的变量有很好的理解,那么您可以自己通过第一次阅读,特别是
如果它们是由用户创建的,则它们将是叶张量这意味着它们不是操作的结果,因此grad_fn
为无
此外,还有哪些国家提供的文件
如果self
张量已经具有正确的torch.dtype
和torch.device
,则返回self
否则,返回的张量是带有所需的火炬.dtype
和火炬.device
的self
的副本
由于张量.to
返回一个副本,并且副本是一个操作,那么从文档中应该可以清楚地看到,原始代码中的W1
张量不是叶张量。这是因为.to
返回一个新的非叶张量。在传输到所需设备后,您应该设置requires_grad
。另外,变量
接口自从pytorch 1.0之前就一直被弃用。它什么也不做(除了在这种情况下作为一种过于复杂的方式来设置requires\u grad
)
考虑
W1 = Variable(torch.randn(embedding_dims, vocabulary_size).float(), requires_grad=True).to(device)
这里的问题是有两个不同的张量。分解它,我们可以重写你正在做的
W1a = Variable(torch.randn(embedding_dims, vocabulary_size).float(), requires_grad=True)
W1 = W1a.to(device)
请注意,W1a
需要一个梯度,但是W1
是从W1a
派生的,因此它不被视为叶张量,因此W1a
的.grad
属性将被更新,但W1
不会被更新。在代码中,您不再直接引用W1a
,因此无法访问渐变
相反,你可以这样做
W1 = torch.randn(embedding_dims, vocabulary_size).float().to(device)
W1.required_grad_(True)
将W1
传输到不同设备后,将其正确设置为叶张量
请注意,对于您的具体情况,我们也可以只使用设备
,数据类型
,需要torch.randn
参数,只需这样做即可
W1 = torch.randn(embedding_dims, vocabulary_size, dtype=torch.float, device=device, requires_grad=True)
大多数初始化新张量的pytorch函数都支持这三个参数,这有助于避免您遇到的问题
回应OP在评论中的补充问题:
在文档中有没有我会遇到的好地方
AFAIK文档并没有专门解决这个问题。它是python中变量的工作方式和pytorch中自动加载机制的工作方式的结合
假设您对python中的变量有很好的理解,那么您可以自己通过第一次阅读,特别是
如果它们是由用户创建的,则它们将是叶张量这意味着它们不是操作的结果,因此grad_fn
为无
此外,还有哪些国家提供的文件
如果self
张量已经具有正确的torch.dtype
和torch.device
,则返回self
否则,返回的张量是带有所需的火炬.dtype
和火炬.device
的self
的副本
由于Tensor.to
返回一个副本,并且副本是一个操作,因此从文档中应该可以清楚地看到,原始代码中的W1
张量不是叶张量。谢谢!在文档中有没有我会遇到的好地方?我看了,但我想我没有发现这么清楚的东西。也许我找的地方不对。感谢您的回答。@Jibril我为您的问题添加了额外的讨论。谢谢!有什么好去处吗