pytorch autograd

1.Variable三要素:

data,是一个Tensor

grad,保存data的梯度,是个Variable

grad_fn,还不懂

Variable的构造函数需要传入tensor,同时有两个可选参数:

  • requires_grad (bool):是否需要对该variable进行求导
  • volatile (bool):意为”挥发“,设置为True,则构建在该variable之上的图都不会求导,专为推理阶段设计
  • 变量的requires_grad属性默认为False,如果某一个节点requires_grad被设置为True,那么所有依赖它的节点requires_grad都是True。这其实很好理解,对于,x.requires_grad = True,当需要计算时,根据链式法则,,自然也需要求,所以y.requires_grad会被自动标为True.
  • volatile=True是另外一个很重要的标识,它能够将所有依赖于它的节点全部都设为volatile=True,其优先级比requires_grad=True高。volatile=True的节点不会求导,即使requires_grad=True,也无法进行反向传播。对于不需要反向传播的情景(如inference,即测试推理时),该参数可实现一定程度的速度提升,并节省约一半显存,因其不需要分配空间计算梯度。

  • 在反向传播过程中非叶子节点的导数计算完之后即被清空。若想查看这些变量的梯度,有两种方法:

    • 使用autograd.grad函数
    • 使用hook 
# 第一种方法:使用grad获取中间变量的梯度
x = V(t.ones(3), requires_grad=True)
w = V(t.rand(3), requires_grad=True)
y = x * w
z = y.sum()
# z对y的梯度,隐式调用backward()
t.autograd.grad(z, y)
# 第二种方法:使用hook
# hook是一个函数,输入是梯度,不应该有返回值
def variable_hook(grad):
    print('y的梯度: \r\n',grad)

x = V(t.ones(3), requires_grad=True)
w = V(t.rand(3), requires_grad=True)
y = x * w
# 注册hook
hook_handle = y.register_hook(variable_hook)
z = y.sum()
z.backward()

# 除非你每次都要用hook,否则用完之后记得移除hook
hook_handle.remove()

2.计算图

算子:+,-,*,\等运算方式

变量:分为叶子节点、根节点;叶子节点是用户自己创建的,根节点是计算目标,比如y=f(x),x是叶子节点,y是根节点,利用链式法则很容易求得各个叶子节点的梯度。

你可能感兴趣的:(pytorch)