Theano 0.6 文檔[4] - 圖結構

本文爲Lancelod_Liu編譯, 轉載請保留此行.

This Article is translated and edited by Lancelod_Liu, keep this line if you share it.

原文: .

Graph Structures

Theano Graphs(圖)

如果你不知道底層的細節, 調試Theano代碼並不容易. 本章旨在教會你Theano內在工作原理的最基本的部分. 更多細節參考 Extending Theano.

寫Theano代碼的第一步就是使用符號變量寫出所有的數學關係, 使用 +,-, **,sum(),tanh()等類似的操作. 所有的這些都被稱作ops. 一個op 代表着一個基於某種類型輸入產生某種類型輸出的特定的計算步驟. 你可以把它看做一個function definition(函數定義).

Theano內部構造一個圖結構, 它由變量節點(variable nodes), 操作節點(op nodes)和應用節點(apply nodes)組成. 一個apply node代表着一個op 應用到一些variables上. 描述一個op表示的計算的定義和apply表示的對於一些實際數據的op的應用的差別是很重要的. 更多細節參考Variable,Op,Apply. 下面是一個圖的例子:

Code

x = T.dmatrix('x')
y = T.dmatrix('y')
z = x + y

Diagram

../_images/apply1.png

Apply (藍色), Variable (紅色), Op (綠色),and Type (紫色) 對象的交互關係.

這張圖的箭頭代表了Python對象指向的引用. 藍色方框是一個 Apply 節點. 紅色方框是 Variable 節點. 綠色圓圈是 Ops. 紫色方框是 Types.

這張圖可以從輸出方向開始倒置, 參考下面代碼:

x = T.dmatrix('x')
y = x * 2.

如果你輸入(y.owner), 輸出是<class 'theano.gof.graph.Apply'>, 即apply 節點連接到op和輸入來得到輸出. 你可以打印出用來得到y的op的name:

>>> y.owner.op.name
'Elemwise{mul,no_inplace}'

結果是一個elementwise的乘法. 這個乘法在輸入間生效:

>>> len(y.owner.inputs)
2
>>> y.owner.inputs[0]
x
>>> y.owner.inputs[1]
InplaceDimShuffle{x,x}.0

注意第二個輸入不是2. 這是因爲首先被 broadcasted 成一個和x的形狀相同的矩陣. 這通過op DimShuffle 實現:

>>> type(y.owner.inputs[1])
<class 'theano.tensor.basic.TensorVariable'>
>>> type(y.owner.inputs[1].owner)
<class 'theano.gof.graph.Apply'>
>>> y.owner.inputs[1].owner.op
<class 'theano.tensor.elemwise.DimShuffle object at 0x14675f0'>
>>> y.owner.inputs[1].owner.inputs
[2.0]

基於這個圖結構我們可以很容易理解自動梯度計算是怎麼工作的, 以及符號關係式如何爲性能和穩定性進行優化的.

Automatic Differentiation(自動差分)

有了圖結構, 計算差分就非常容易啦. tensor.grad() 需要做的唯一的一件事就是反朔整張圖, 通過所有的apply節點, 直到到達輸入. 對於每個apply 節點, 它的op 定義瞭如何計算節點輸出對應於其輸入的梯度. 注意到如果一個 op 沒有提供這個信息, 它就認爲梯度是未定義的了. 使用鏈式法則(chain rule), 這些梯度可以按順序整合來得到整張圖的輸入輸出的梯度.

以後繼續討論這個話題( differentiation ).

Optimizations(優化)

當編譯一個Theano函數的時候, 你傳遞給theano.function 的實際上式一個圖(graph)(從輸出變量你可以橫穿整張圖直到輸入變量). 這個圖結構展示瞭如何計算輸出, 它也提供了改進計算方式的可能性. Theano優化的方式是通過定義和替換圖中某些特定的模式, 從而可以更快/穩定地產生同樣的輸出. 優化同樣可以檢測出關鍵的子圖並保證同一個值不會計算兩次或重定義.

舉個栗子, Theano的一個優化就是替換 \frac{xy}{y}x.

更多信息參考processoptimizations.

Example(栗子)

符號變成設計到模式變化: 它會更加清晰. 考慮下面的栗子:

>>> import theano
>>> a = theano.tensor.vector("a")      # declare symbolic variable
>>> b = a + a ** 10                    # build symbolic expression
>>> f = theano.function([a], b)        # compile function
>>> print f([0, 1, 2])                 # prints `array([0,2,1026])`
Unoptimized graph Optimized graph
../_images/f_unoptimized2.png ../_images/f_optimized2.png
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章