pytorch autograd backward函数中 retain_graph参数的作用,简单例子分析,以及create_graph参数的作用...

本文介绍了retain_graph参数的作用,官方定义为若设为False,计算图中间变量计算完会被释放,默认值与create_graph相同。通过一个输入输出示例,分析了程序报错原因,指出需将retain_graph设为True保留中间参数,使两个loss的backward()不相互影响。

retain_graph参数的作用

官方定义:

retain_graph (bool, optional) – If False, the graph used to compute the grad will be freed. Note that in nearly all cases setting this option to True is not needed and often can be worked around in a much more efficient way. Defaults to the value of create_graph.

大意是如果设置为False,计算图中的中间变量在计算完后就会被释放。但是在平时的使用中这个参数默认都为False从而提高效率,和creat_graph的值一样。

具体看一个例子理解:

假设一个我们有一个输入x,y = x **2, z = y*4,然后我们有两个输出,一个output_1 = z.mean(),另一个output_2 = z.sum()。然后我们对两个output执行backward。

 1 import torch
 2 x = torch.randn((1,4),dtype=torch.float32,requires_grad=True)
 3 y = x ** 2
 4 z = y * 4
 5 print(x)
 6 print(y)
 7 print(z)
 8 loss1 = z.mean() 9 loss2 = z.sum() 10 print(loss1,loss2) 11 loss1.backward() # 这个代码执行正常,但是执行完中间变量都free了,所以下一个出现了问题 12 print(loss1,loss2) 13 loss2.backward() # 这时会引发错误

程序正常执行到第12行,所有的变量正常保存。但是在第13行报错:

RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time.

分析:计算节点数值保存了,但是计算图x-y-z结构被释放了,而计算loss2的backward仍然试图利用x-y-z的结构,因此会报错。

因此需要retain_graph参数为True去保留中间参数从而两个loss的backward()不会相互影响。正确的代码应当把第11行以及之后改成

1 # 假如你需要执行两次backward,先执行第一个的backward,再执行第二个backward
2 loss1.backward(retain_graph=True)# 这里参数表明保留backward后的中间参数。
3 loss2.backward() # 执行完这个后,所有中间变量都会被释放,以便下一次的循环
4  #如果是在训练网络optimizer.step() # 更新参数

create_graph参数比较简单,参考官方定义:
  • create_graph (booloptional) – If True, graph of the derivative will be constructed, allowing to compute higher order derivative products. Defaults to False.

附参考学习的链接如下,并对作者表示感谢:retain_graph参数的作用.

 

转载于:https://www.cnblogs.com/luckyscarlett/p/10555632.html

<think>我们有一个张量y,它是通过点积运算得到的:y=torch.dot(x,x)。现在,我们需要通过调用backward()方法来计算y的梯度,并访问x的梯度(x.grad)。步骤如下:1.确保张量x的requires_grad属性为True,这样PyTorch才会跟踪在其上的计算以便计算梯度。2.计算y,例如:y=torch.dot(x,x)。3.调用y.backward(),这将会计算y关于x的梯度,并将梯度累积到x.grad中。4.访问x.grad,即可得到梯度值。注意:在反向传播之前,x.grad可能为None。调用backward()之后,x.grad将包含一个与x形状相同的张量,存储着梯度值。回顾:对于y=x·x(即y=sum(x_i^2)),梯度是2*x。下面是一个具体的代码示例。</think> ### 在 PyTorch 中计算梯度并访问梯度值的方法 在 PyTorch 中计算张量的梯度并访问梯度值需要遵循以下步骤: #### 1. 启用梯度跟踪 要使张量能够计算梯度,必须设置 `requires_grad=True`: ```python import torch # 创建需要计算梯度的张量 x = torch.tensor([2.0, 3.0, 4.0], requires_grad=True) ``` #### 2. 执行前向计算 定义计算图,包括点积运算: ```python # 点积计算(相当于 ∑xᵢ²) y = torch.dot(x, x) # 输出:tensor(29., grad_fn=<DotBackward0>) ``` 此时 `y` 包含反向传播所需的梯度函数信息[^1]。 #### 3. 反向传播计算梯度 调用 `.backward()` 方法计算梯度: ```python y.backward() # 执行反向传播 ``` #### 4. 访问梯度值 通过 `.grad` 属性访问 `x` 的梯度: ```python print(x.grad) # 输出:tensor([4., 6., 8.]) ``` #### 数学原理 点积 $y = \mathbf{x} \cdot \mathbf{x}$ 的梯度计算表达式: $$ \frac{\partial y}{\partial \mathbf{x}} = 2\mathbf{x} $$ 因此当 $x = [2.0, 3.0, 4.0]$ 时: $$ \nabla_{\mathbf{x}} y = 2 \times [2.0, 3.0, 4.0] = [4.0, 6.0, 8.0] $$ #### 注意事项 1. **梯度累积**:多次运行 `.backward()` 会导致梯度累积 ```python x.grad.zero_() # 清空梯度 ``` 2. **非标量输出**:当输出不是标量时需要传入梯度参数 ```python # 如果输出是多维张量 output.backward(torch.ones_like(output)) ``` 3. **梯度上下文管理** ```python with torch.no_grad(): # 临时禁用梯度计算 # 在此区域内不会计算梯度 ``` [^1]: 梯度追踪需要启用 `requires_grad=True` 并正确执行前向计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值