ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

PyTorch 3. autograd

2021-11-20 19:00:54  阅读:200  来源: 互联网

标签:hook autograd torch requires grad PyTorch True


PyTorch 3. autograd

autograd

  1. 动态图:运算与搭建同时进行
  2. 静态图:先搭建图,后运算
    计算图只能backward一次,若想再次使用则必须设置retain_graph=True
torch.autograd.grad(outputs,
					inputs,
					grad_outputs=None,
					retain_graph=None,
					create_graph=False)

功能:求取梯度
outputs:用于求导的张量,如loss
inputs: 需要梯度的张量
create_graph: 创建导数计算图,用于高阶求导
retain_graph: 保存计算图,反向传播需要缓存一些中间结果,反向传播之后,这些缓存就会被清空,可通过指定这个参数不清空缓存,用来多次反向传播。
grad_outputs:多梯度权重

例子

# 创建tensor的时候指定requires_grad
a = torch.randn(3,4,requires_grad=True)
# 或者
a = torch.randn(3,4).requires_grad_()
# 或者
a = torch.randn(3,4)
a.requires_grad=True

如果某一个tensor需要求导,那么与该tensor有直接关联的tensor的requires_grad会自动设置为True
叶子节点:由用户创建的variable属于叶子节点,对应的grad_fn是None

auto_grad具体操作

在PyTorch实现中,autograd会随着用户的操作,记录生成当前variable的所有操作,并由此建立一个有向无环图。用户每进行一次操作,相应的计算图就会发生改变。更低层的实现中,图中记录了操作Function,每一个变量在图中的位置可通过其grad_fn属性在图中的位置推测得到。在反向传播过程中,autograd沿着这个图从当前变量(根节点z)溯源,可以利用链式求导法则计算所有叶子节点的梯度。 每一个前向传播操作的函数都有与之对应的反向传播函数用来计算输入的各个variable的梯度,这些函数的函数名通常以Backward结尾。

推理环节

有时候,我们不希望autograd对tensor求导,认为求导需要缓存许多中间结构,增加额外的显存开销,那么我们可以关闭自动求导。对于不需要反向传播的情形(如测试推理),关闭自动求导可实现一定程度的速度提升,并节省约一半的显存。

tensor.data

如果我们想要修改tensor的数值,但是又不希望被autograd记录,那么可以对tensor.data进行操作

d = a.data.sigmoid_() #sigmoid_ 是一个inplace操作,会改变a自身的值

autograd.grad和hook

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

  1. 使用autograd.grad函数
  2. 使用hook
x = torch.ones(3, requires_grad=True)
w = torch.rand(3, requires_grad=True)
y = x * w
# y依赖于w,而w.requires_grad=True
z = y.sum()
z.backward()

计算完后,由于y是非叶子节点,所以y的梯度为空

  1. 第一种获取中间变量梯度的方法
torch.autograd.grad(z,y)
  1. 第二种获取中间变量梯度的方法
    使用hook,hook是一个函数,输入是梯度,不应该有返回值
def variable_hook(grad):
	print('y的梯度:',grad)

x = torch.ones(3, requires_grad=True)
w = torch.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()

扩展autograd

class Sigmoid(Function):
	
	@staticmethod
	def forward(ctx, x):
	output = 1/(1+t.exp(-x))
	ctx.save_for_backward(output)
	return output
	@staticmethod
	def backward(ctx, grad_output):
	output,_ = ctx,saved_tensors
	grad_x = output *(1-output)*grad_output
	return grad_x

标签:hook,autograd,torch,requires,grad,PyTorch,True
来源: https://blog.csdn.net/DCGJ666/article/details/121443226

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有