pytorch - 为什么在定义 ReLU autograd 函数时需要克隆 grad_output 并将其分配给 grad_input?
问题描述
我正在浏览 pytorch 教程的 autograd 部分。我有两个问题:
- 为什么我们需要克隆
grad_output
并在反向传播期间将其分配给grad_input
其他简单的分配? - 的目的是
grad_input[input < 0] = 0
什么?这是否意味着当输入小于零时我们不更新梯度?
这是代码:
class MyReLU(torch.autograd.Function):
@staticmethod
def forward(ctx, input):
"""
In the forward pass we receive a Tensor containing the input and return
a Tensor containing the output. ctx is a context object that can be used
to stash information for backward computation. You can cache arbitrary
objects for use in the backward pass using the ctx.save_for_backward method.
"""
ctx.save_for_backward(input)
return input.clamp(min=0)
@staticmethod
def backward(ctx, grad_output):
"""
In the backward pass we receive a Tensor containing the gradient of the loss
with respect to the output, and we need to compute the gradient of the loss
with respect to the input.
"""
input, = ctx.saved_tensors
grad_input = grad_output.clone()
grad_input[input < 0] = 0
return grad_input
提前非常感谢。
解决方案
为什么我们需要克隆 grad_output 并将其分配给 grad_input 而不是在反向传播期间进行简单分配?
tensor.clone()
创建一个模仿原始张量requires_grad
场的张量副本。clone
是一种复制张量的方法,同时仍将副本保留为它来自的计算图的一部分。
因此,grad_input
是与 相同的计算图的一部分,grad_output
如果我们计算 的梯度grad_output
,那么也会对 进行相同的操作grad_input
。
由于我们在 中进行了更改grad_input
,因此我们首先将其克隆。
'grad_input [input < 0] = 0'的目的是什么?这是否意味着当输入小于零时我们不更新梯度?
这是根据 ReLU 函数的定义完成的。ReLU 函数是f(x)=max(0,x)
. 这意味着如果x<=0
那么f(x)=0
,否则f(x)=x
。在第一种情况下,当 时,关于x<0
的导数是。所以,我们执行. 在第二种情况下,它是,所以我们只需传递to (就像一扇敞开的门)。f(x)
x
f'(x)=0
grad_input[input < 0] = 0
f'(x)=1
grad_output
grad_input
推荐阅读
- apache-spark - 为什么 Spark 部署不需要安装 Scala?
- arrays - 程序中的 C 内存泄漏
- nand2tetris - 内存芯片实现中的无限循环问题 (Nand2Tetris)
- r - 跨地图标准化色标
- laravel - 419 | 退出时页面已过期 Laravel 8 Jetstream
- python - Excel 到 Python 字典,用于使用 Openpyxl 进行过滤
- c# - 将一维数组添加到多维数组c#
- c - 播种 srand() 一次 rand() 每次都给出几乎相同的结果
- java - JDA Discord 向消息添加反应
- android - Xamarin UI 测试在单击 app.PressMenu 后选择菜单选项