簡體   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