理解PyTorch中的反向传播

2024-04-18 04:28:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在探索Pytork,不理解以下示例的输出:

# Initialize x, y and z to values 4, -3 and 5
x = torch.tensor(4., requires_grad = True)
y = torch.tensor(-3., requires_grad = True)
z = torch.tensor(5., requires_grad = True)

# Set q to sum of x and y, set f to product of q with z
q = x + y
f = q * z

# Compute the derivatives
f.backward()

# Print the gradients
print("Gradient of x is: " + str(x.grad))
print("Gradient of y is: " + str(y.grad))
print("Gradient of z is: " + str(z.grad))

输出

Gradient of x is: tensor(5.)
Gradient of y is: tensor(5.)
Gradient of z is: tensor(1.)

我毫不怀疑我的困惑源于一个小小的误解。有人能逐步解释吗


Tags: andofthetotrue示例istorch
3条回答

我可以提供一些关于反向传播方面的见解

当操作需要梯度计算的张量(requires_grad=True)时,PyTorch跟踪反向传播的操作,并构建一个计算图即席

让我们看一下您的示例:

q = x + y 
f = q * z

其对应的计算图可表示为:

  x      -\
              -> x + y = q    \
  y      -/                    -> q * z = f
                                 /
  z                / 

其中xyz称为叶张量。反向传播包括计算xyy的梯度,它们分别对应于:dL/dxdL/dydL/dz。其中L是基于图形输出f的标量值。执行的每个操作都需要实现一个反向函数(这是所有数学上可微的PyTorch内置函数的情况)。对于每个操作,该函数有效地用于计算输出w.r.t.输入的梯度

向后传球将如下所示:

dL/dx <   \    
  x     -\  \ 
            \ dq/dx 
             \  \ < - dL/dq  -\
              -> x + y = q   \  \
             /  /               \ df/dq
            / dq/dy              \  \ < - dL/df  -
  y     -/  /                   -> q * z = f
dL/dy <   /                   /  /
                                / df/dz
  z               -/  /
dL/dz <             /

第一个运算符的"d(outputs)/d(inputs)"项是:dq/dx = 1dq/dy = 1。对于第二个运算符,它们是df/dq = zdf/dz = q

反向传播归结为应用链规则:dL/dx = dL/dq * dq/dx = dL/df * df/dq * dq/dx。直观地说,我们分解dL/dx的方式与反向传播的实际方式相反,反向传播需要自下而上进行导航

没有形状方面的考虑,我们从^{开始。实际上dL/df的形状是f(参见下面链接的另一个答案)。这导致dL/dx = 1 * z * 1 = z。同样地,对于{}和{},我们有{}和{}。你观察到的结果是什么


我就相关主题给出了一些答案:

你只需要了解什么是运算,什么是偏导数,你应该用它们来计算,例如:

x = torch.tensor(1., requires_grad = True)
q = x*x
q.backward()

print("Gradient of x is: " + str(x.grad))

将给你2,因为x*x的导数是2*x

如果我们以您的示例为x,我们有:

q = x + y
f = q * z

可修改为:

f = (x+y)*z = x*z+y*z

如果我们在x的函数中取f的偏导数,我们只得到z

在这个结果中,你必须考虑所有其他变量是常数,并应用你已经知道的导数规则。

但请记住,Pytork执行以获得这些结果的过程不是符号或数字微分,而是自动微分,这是一种有效获得梯度的计算方法

仔细看看:

https://www.cs.toronto.edu/~rgrosse/courses/csc321_2018/slides/lec10.pdf

我希望您理解,当您执行f.backward()时,您在x.grad中得到的是dfdx

就你而言 。 因此,简单地说(通过初步计算)

如果您输入x、y和z的值,这就解释了输出

但是,这并不是真正的“反向传播”算法。这只是偏导数(这是你在问题中问的全部问题)

编辑: 如果你想知道它背后的反向传播机制,请参阅@Ivan的答案

相关问题 更多 >