close

2.5 計算圖

前兩小節對tensor進行了詳細介紹,知道了tensorpytorch的核心資料結構,各類資料均以tensor來表示,並且tensor類中有許多屬性與求導/梯度有關,接下來我們將深入學習pytorch的自動求導模組——autograd。在autograd正式開始之前,需要瞭解一個重要概念——計算圖(Computational Graphs)。

在學習自動求導系統之前,需要瞭解計算圖的概念。計算圖(Computational Graphs)是一種描述運算的語言,它由節點(Node)和邊(Edge)構成。

節點表示資料,如標量,向量,矩陣,張量等;

表示運算,如加、減、乘、除、卷積、relu等;

記錄所有節點和邊的資訊,可以方便地完成自動求導,假設有這麼一個計算:

y = (x+ w) * (w+1)

將每一步細化為:

a = x + w

b = w + 1

y = a * b

得到計算圖如下:

<<AI人工智慧 PyTorch自學>> 2.5 計算圖

有了計算圖,我們可以嘗試進行forward,帶入x,w的輸入資料,就得到結果y

同樣的,如果需要獲取各參數的導數,也可以方便地獲得。

計算圖求導

假設我們要算yw的導數,在計算圖中要怎麼做呢?

先來看wy之間的關係,w會通過左邊這條路走到y,也會通過右邊這條路走到y,因此梯度也是一樣的,會經過這兩條路回饋回來。

所以yw的偏導有兩條路徑,可以寫成以下形式, ∂y/∂w = ∂y/∂a ∂a/∂w + ∂y/∂b ∂b/∂w,然後可以通過計算圖依次求出。

如圖所示:

<<AI人工智慧 PyTorch自學>> 2.5 計算圖

這樣我們得到 yw的導數是5,我們可以拿紙和筆推一下,是否是一樣的。

我們發現,所有的偏微分計算所需要用到的資料都是基於wx的,這裡,wx就稱為葉子結點

葉子結點是最基礎結點,其資料不是由運算生成的,因此是整個計算圖的基石,是不可輕易修改的。而最終計算得到的y就是根節點,就像一棵樹一樣,葉子在上面,根在下面。

葉子結點

葉子結點是最基礎的結點,其資料不是由運算生成的,因此是整個計算圖的基石,是不可輕易修改的。而最終計算得到的y就是根節點,就像一棵樹一樣,葉子在上面,根在下面。

<<AI人工智慧 PyTorch自學>> 2.5 計算圖

張量有一個屬性是is_leaf, 就是用來指示一個張量是否為葉子結點的屬性。

我們通過代碼,實現以上運算,並查看該計算圖的葉子結點和梯度。

import torch

 

w = torch.tensor([1.], requires_grad=True)

x = torch.tensor([2.], requires_grad=True)

 

a = torch.add(w, x)

b = torch.add(w, 1)     # retain_grad()

y = torch.mul(a, b)

 

y.backward()

print(w.grad)

 

# 查看葉子結點

print("is_leaf:\n", w.is_leaf, x.is_leaf, a.is_leaf, b.is_leaf, y.is_leaf)

# 查看梯度

print("gradient:\n", w.grad, x.grad, a.grad, b.grad, y.grad)

# 查看 grad_fn

print("grad_fn:\n", w.grad_fn, x.grad_fn, a.grad_fn, b.grad_fn, y.grad_fn)

Copy

tensor([5.]) is_leaf: True True False False False gradient: tensor([5.]) tensor([2.]) None None None grad_fn: None None

我們發現y就不是葉子結點了,因為它是由結點w和結點x通過乘法運算得到的。

補充知識點1非葉子結點在梯度反向傳播結束後釋放

只有葉子節點的梯度得到保留,中間變數的梯度預設不保留;在pytorch中,非葉子結點的梯度在反向傳播結束之後就會被釋放掉,如果需要保留的話可以對該結點設置retain_grad()

補充知識點2grad_fn是用來記錄創建張量時所用到的運算,在鏈式求導法則中會使用到。

思考一下yw求導的過程,我們知道只要記錄下計算圖中的結點(資料)和邊(運算),就可以通過鏈式法則輕易的求取梯度。

所以在pytorch中,自動微分的關鍵就是記錄資料和該結點的運算。回想一下張量的結構當中其實就記錄了這兩個重要的東西。

在張量中,資料對應著data,結點的運算對應著grad_fn,大家現在應該明白為什麼結點的運算叫grad_fn而不叫fn了吧,因為這個運算是在求梯度的時候使用的。

<<AI人工智慧 PyTorch自學>> 2.5 計算圖

靜態圖與動態圖

以上就是計算圖的簡單介紹。計算圖根據計算圖的搭建方式可以劃分為靜態圖和動態圖。

pytorch是典型的動態圖,TensorFlow是靜態圖(TF 2.x 也支援動態圖模式)。

動態圖和靜態圖的搭建方式有何不同,如何判斷和區分?

第一種判斷:這就要看運算,是在計算圖搭建之後,還是兩者同步進行

先搭建計算圖,再運算,這就是靜態圖機制。

而在運算的同時去搭建計算圖,這就是動態圖機制。

第二種判斷:也可以通過判斷運算過程中計算圖是否可變動來區分靜態圖與動態圖。

在運算過程中,計算圖可變動的是動態圖;計算圖不可變,是靜止的,就是靜態圖。

下麵來看兩個示意圖。

<<AI人工智慧 PyTorch自學>> 2.5 計算圖

静态图.gif

1pytorch的靜態圖示意,圖2TensorFlow的靜態圖示意。

動態圖優點:

  1. 易理解:程式按照編寫命令的順序進行執行
  2. 靈活性:可依據模型運算結果來決定計算圖

靜態圖優點:

  1. 高效性:優化計算圖,提高運算效率(但在gpu時代,這一點對於初學者而言可忽略不計)

缺點:

  1. 晦澀性:需要學習 seesion, placeholder等概念,調試困難

以上是關於計算圖概念的介紹,下一小節將詳細剖析autograd機制及其常用的功能函數,請注意,下一節內容也非常豐富,可能需要多次閱讀以充分理解。

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 HCHUNGW 的頭像
    HCHUNGW

    HCHUNGW的部落格

    HCHUNGW 發表在 痞客邦 留言(0) 人氣()