Pytorch autograd.backward理解

通常在训练的时候, 最后的loss是一个标量, 无脑使用loss.backward()进行反向传播计算梯度即可. 但是碰到有些代码中出现了多个loss, 比如这样的代码:

torch.autograd.backward([loss0, loss1], [torch.ones_like(loss0), torch.ones_like(loss1)])

当loss是一个标量值的时候

此时反向传播求梯度比较好理解, 假设

>>> w = torch.tensor([[1.0, 2.0]], requires_grad=True)	# 可以看做模型中的某个参数 dim=1x2
>>> x  = torch.tensor([[1.0], [1.0]])					# 可以看做模型的训练数据 dim=2x1
>>> loss = torch.mm(w, x)															
>>> loss.backward()								# 也可以执行torch.autograd.backward(loss), 同样的效果
tensor([[3.]], grad_fn=<MmBackward>)
>>> w.grad										# 查看 w的梯度
tensor([1.0, 1.0])				

l o s s = w 0 ∗ x 0 + w 1 ∗ x 1 ∂ l o s s ∂ w = [ x 0 , x 1 ] loss = w_0*x_0 + w_1*x_1 \\ \frac{\partial{loss}}{\partial{w}} = [x_0, x_1] loss=w0x0+w1x1wloss=[x0,x1]

当loss是一个向量的时候

比如

>>> w = torch.tensor([[1.0, 2.0]], requires_grad=True)			# 可以看做模型中的某个参数 dim=1x2
>>> x  = torch.tensor([[1.0, 1.0], [2.0, 2.0]])							# 可以看做模型的训练数据 dim=2x2
>>> loss = torch.mm(w, x)			
>>> loss
tensor([[5., 5.]], grad_fn=<MmBackward>)																				
>>> loss.backward()								# 此时会报错
...
RuntimeError: grad can be implicitly created only for scalar outputs

报错的意思是 只有标量才能隐式的计算梯度(言下之意是向量需要显示的计算); 那么所谓"显示", 应该就是本文开头 torch.autograd.backward( , )中第二个参数的作用了吧.

# 在本例中呢, 就是以下代码
loss.backward(torch.ones_like(loss))
# 同torch.autograd.backward(loss, torch.ones_like(loss))
  • 求和变成标量再求梯度? 先不管这个"显示参数", 如果我把两个loss加起来, 变成一个标量, 应该就可以了隐式的计算梯度了吧.
>>> loss_sum = loss.sum()
>>> loss_sum
tensor(10., grad_fn=<SumBackward0>)
>>> loss_sum.backward(retain_graph=True)			# 设置retain_graph=True, 方便后续实验
>>> w.grad
tensor([[2., 4.]])
  • 给定grad_tensor? 继续实验, 如果给定"显示参数"呢? 就是查看torch.autograd.backward说明里面的第二个参数: “grad_tensor”. 可以看出和 "求和变成标量再求梯度"效果是一样的.
>>> w.grad *= 0			#先 将梯度清零
>>> loss.backward(torch.ones_like(loss))
>>> w.grad
tensor([[2., 4.]])
  • 分别对每个loss单独求梯度? 既然loss是一个向量, 那么我向量中的每一个元素都是标量, 我可以分别求梯度.
>>> w.grad *= 0			# 先 将梯度清零
>>> loss0, loss1 = loss[0]			
>>> loss0.backward(retain_graph=True)		# 此时必须retain_graph=True, 不然无法继续叠加
>>> loss1.backward(retain_graph=True)
tensor([[2., 4.]])

综上可以看出, 对于向量或者矩阵执行backward操作的时候, 类似与将其进行了"加权求和", 然后对结果进行反向传播. 例子中指定的grad_tensor的元素值全为1, 也可为0或者其他值.

本文参考了Pytorch autograd,backward详解

torch.autograd.variable函数是PyTorch的一个函数。它用于将输入数据封装成可求导的变量(Variable)。这个函数可以接受一个tensor作为输入,并将其封装成一个Variable对象。Variable对象是PyTorch的一个重要类,它不仅包含了数据本身,还包含了关于数据的梯度信息以及计算图的信息。通过使用Variable对象,我们可以方便地进行自动求导和构建计算图。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [解决torch.autograd.backward的参数问题](https://download.csdn.net/download/weixin_38595243/14859443)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【Pytorchautograd.Variable类详解 & tensor.backward()进行反向传播梯度计算过程](https://blog.csdn.net/DUDUDUTU/article/details/125600317)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [『PyTorch』第五弹_深入理解autograd_上:Variable属性方法](https://blog.csdn.net/weixin_33825683/article/details/86443410)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值