繁体   English   中英

Pytorch 中基于磁带的 autograd 是什么?

[英]What is tape-based autograd in Pytorch?

我了解autograd用于暗示自动微分。 但究竟什么是tape-based autogradPytorch ,为什么有一些肯定或否定它这么多的讨论。

例如:

这个

在pytorch中,没有传统意义上的胶带

我们本身并没有真正构建梯度磁带。 但是图表。

但不是这个

Autograd 现在是用于自动微分的核心 Torch 包。 它使用基于磁带的系统进行自动区分。

为了进一步参考,请将其与Tensorflow GradientTape进行Tensorflow

有不同类型的自动区分,例如forward-modereverse-modehybrids 更多解释)。 Pytorch 中tape-based Pytorch简单地指的是反向模式自动微分的使用, source 反向模式自动差异只是一种用于有效计算梯度的技术,它恰好被反向传播源使用


现在,在PyTorch 中,Autograd 是自动微分的核心 Torch 包。 它使用基于tape-based系统进行自动区分 在前进阶段, autograd磁带会记住它执行的所有操作,而在后退阶段,它将重放这些操作

TensorFlow 中也是如此,为了自动区分,它还需要记住在前向传递过程中以什么顺序发生了什么操作。 然后,在向后传递期间,TensorFlow 以相反的顺序遍历此操作列表以计算梯度 现在,TensorFlow 提供了tf.GradientTape API 用于自动微分; 也就是说,计算关于某些输入的计算梯度,通常是tf.Variables TensorFlow 将在tf.GradientTape上下文中执行的相关操作记录磁带上 TensorFlow 然后使用该磁带来计算使用反向模式微分记录计算的梯度。

所以,从高层的角度来看,两者都在做同样的操作。 然而,在自定义训练循环期间, forward传递和loss计算在TensorFlow中更加明确,因为它使用tf.GradientTape API 范围,而在PyTorch ,这些操作是隐式的,但它需要在更新时暂时将required_grad标志设置为False训练参数(权重和偏差)。 为此,它明确使用了torch.no_grad API。 换句话说,TensorFlow 的tf.GradientTape()类似于 PyTorch 的loss.backward() 以下是上述语句的代码中的简单形式。

# TensorFlow 
[w, b] = tf_model.trainable_variables
for epoch in range(epochs):
  with tf.GradientTape() as tape:
    # forward passing and loss calculations 
    # within explicit tape scope 
    predictions = tf_model(x)
    loss = squared_error(predictions, y)

  # compute gradients (grad)
  w_grad, b_grad = tape.gradient(loss, tf_model.trainable_variables)

  # update training variables 
  w.assign(w - w_grad * learning_rate)
  b.assign(b - b_grad * learning_rate)


# PyTorch 
[w, b] = torch_model.parameters()
for epoch in range(epochs):
  # forward pass and loss calculation 
  # implicit tape-based AD 
  y_pred = torch_model(inputs)
  loss = squared_error(y_pred, labels)

  # compute gradients (grad)
  loss.backward()
  
  # update training variables / parameters  
  with torch.no_grad():
    w -= w.grad * learning_rate
    b -= b.grad * learning_rate
    w.grad.zero_()
    b.grad.zero_()

仅供参考,在上面,可训练变量( wb )在两个框架中都是手动更新的,但我们通常使用优化器(例如adam )来完成这项工作。

# TensorFlow 
# ....
# update training variables 
optimizer.apply_gradients(zip([w_grad, b_grad], model.trainable_weights))

# PyTorch
# ....
# update training variables / parameters
optimizer.step()
optimizer.zero_grad()

我怀疑这来自于在自动微分的上下文中“磁带”这个词两种不同用法。

当人们说不是基于磁带的时,他们的意思是它使用运算符重载而不是 [基于磁带的] 源转换来自动区分。

[运算符重载] 依赖于语言重新定义函数和运算符含义的能力。 所有原语都被重载,以便它们额外执行跟踪操作:原语及其输入被记录到“磁带”上,以确保这些中间变量保持活动状态。 在函数执行结束时,该磁带包含程序中所有数值运算的线性轨迹。 可以通过反向走这条带子来计算导数。 [...]
OO 是 PyTorch、Autograd 和 Chainer [37] 使用的技术。

...

基于磁带的框架,例如用于 Fortran 和 C 的 ADIFOR [8] 和 Tapenade [20] 使用全局堆栈,也称为“磁带” 2以确保中间变量保持活动状态。 原始(原始)函数被扩充,以便在前向传递期间将中间变量写入磁带,而伴随程序将在向后传递期间从磁带中读取中间变量。 最近,在机器学习框架 Tangent [38] 中为 Python 实现了基于磁带的 ST。

...

2 ST 中使用的磁带仅存储中间变量,而 OO 中的磁带是程序跟踪,也存储执行的原语。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM