了解 PyTorch 中的反向传播

Cai*_*inG 5 python backpropagation neural-network deep-learning pytorch

我正在探索 PyTorch,但我不明白以下示例的输出:

# 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))
Run Code Online (Sandbox Code Playgroud)

输出

Gradient of x is: tensor(5.)
Gradient of y is: tensor(5.)
Gradient of z is: tensor(1.)
Run Code Online (Sandbox Code Playgroud)

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

Iva*_*van 6

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

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

让我们看看你的例子:

q = x + y 
f = q * z
Run Code Online (Sandbox Code Playgroud)

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

  x   -------\
              -> x + y = q ------\
  y   -------/                    -> q * z = f
                                 /
  z   --------------------------/ 
Run Code Online (Sandbox Code Playgroud)

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

向后传递将如下所示:

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 <--------------------------/
Run Code Online (Sandbox Code Playgroud)

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

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

不考虑形状,我们从 开始dL/df = 1。实际上dL/df具有以下形状f(请参阅下面链接的我的其他答案)。这导致dL/dx = 1 * z * 1 = z. 类似地,对于yz,我们有dL/dy = zdL/dz = q = x + y。这是您观察到的结果。


我对相关主题给出的一些答案:


Aya*_*Das 4

我希望你明白,当你这样做时f.backward(),你得到的x.graddfdx

在你的情况下 。所以,简单地(通过初步计算)

如果输入 x、y 和 z 的值,就会解释输出。

但是,这并不是真正的“反向传播”算法。这只是偏导数(这就是您在问题中提出的所有问题)。

编辑:如果您想了解其背后的反向传播机制,请参阅@Ivan 的答案。