[英]What is tape-based autograd in Pytorch?
有不同类型的自动区分,例如forward-mode
、 reverse-mode
、 hybrids
; ( 更多解释)。 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_()
仅供参考,在上面,可训练变量( w
, b
)在两个框架中都是手动更新的,但我们通常使用优化器(例如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()
我怀疑这来自于在自动微分的上下文中“磁带”这个词的两种不同用法。
当人们说pytorch不是基于磁带的时,他们的意思是它使用运算符重载而不是 [基于磁带的] 源转换来自动区分。
[运算符重载] 依赖于语言重新定义函数和运算符含义的能力。 所有原语都被重载,以便它们额外执行跟踪操作:原语及其输入被记录到“磁带”上,以确保这些中间变量保持活动状态。 在函数执行结束时,该磁带包含程序中所有数值运算的线性轨迹。 可以通过反向走这条带子来计算导数。 [...]
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.