【问题标题】:Can you explain why this code produce gradient as None?你能解释一下为什么这段代码产生的渐变为 None 吗?
【发布时间】:2021-09-15 22:05:54
【问题描述】:

我想用 pytorch 的自动梯度系统获得参数梯度。但是,我的代码无法进行渐变。 我认为当我使用函数时 autograd 会失败,但是当我不使用很多自定义函数时它会太长。我应该如何更改此代码? 我的具体代码如下。谢谢

import torch as T
import numpy as np

n_qubits=6
device=T.device('cuda:0' if T.cuda.is_available() else 'cpu')
m=3
s=np.zeros((2**m,1))
s[0]=1
M=np.kron(np.identity(2**(n_qubits-m)),np.matmul(s,np.transpose(s)))
M=T.tensor(M,dtype=T.cfloat).to(device)

def RX(theta,q):
    return T.kron(T.eye(2**int(q),dtype=T.cfloat).to(device),
                  T.kron(T.matrix_exp(-0.5*theta*T.complex(T.zeros(2,2),
                   T.tensor(np.array([[0,1],[1,0]]),dtype=T.float)).to(device)),
                     T.eye(2**(n_qubits-int(q)-1),dtype=T.cfloat).to(device))).to(device)
def f(theta,ro_train):
    return T.trace(T.real(T.mm(M,T.mm(RX(theta,0),T.mm(ro_train,RX(-theta,0)))))).to(device)

theta=T.tensor(1,dtype=T.float,requires_grad=True).to(device)
ro_train=T.tensor(np.identity(2**n_qubits),dtype=T.cfloat).to(device)
f(theta,ro_train).backward(gradient=theta)
print(theta.grad)

输出

UserWarning:正在访问不是叶张量的张量的 .grad 属性。在 autograd.backward() 期间不会填充其 .grad 属性。如果您确实想要非叶张量的梯度,请在非叶张量上使用 .retain_grad() 。如果您错误地访问了非叶张量,请确保您访问的是叶张量。有关更多信息,请参阅 github.com/pytorch/pytorch/pull/30531。 打印(theta.grad)

预期 0

【问题讨论】:

  • 我运行了您的代码,但无法重现错误。我得到了“张量(-0.0002)”。您使用的是什么版本的 pytorch。我对最新的“稳定”版本有很多问题。我推荐使用版本 1.7.1+cu101
  • 我正在使用 1.8.0.dev20210119 并在 jupyter notebook 上工作,window10。它对我不起作用
  • 我更新为 1.7.1+cu101,但它会产生如下错误:具有 CUDA 功能的 NVIDIA GeForce RTX 3080 sm_86 与当前的 PyTorch 安装不兼容。当前的 PyTorch 安装支持 CUDA 功能 sm_37 sm_50 sm_60 sm_61 sm_70 sm_75 compute_37。如果您想将 NVIDIA GeForce RTX 3080 GPU 与 PyTorch 一起使用,请查看pytorch.org/get-started/locallywarnings.warn(incompatible_device_warn.format(device_name, capability, " ".join(arch_list), device_name)) 处的说明

标签: pytorch autograd


【解决方案1】:

我设法重现了您的错误并得到了以下输出。

UserWarning: The .grad attribute of a Tensor that is not a leaf Tensor is being accessed.

这意味着您正在尝试获取计算图中不是叶子的变量的梯度。由于 theta 是 theta=T.tensor(1,dtype=T.float,requires_grad=True).to(device) 行中 .to(device) 操作的结果,它是一个中间变量而不是叶子。要强制 pytorch 计算非叶变量的梯度,您必须调用它们的 .retain_grad()。 只需在我提到的行之后添加theta.retain_grad()。 您可以在 pytorch 论坛的this post 中阅读更多相关信息

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    相关资源
    最近更新 更多