來自:http://deeplearning.net/software/theano/tutorial/adding.html
Baby Steps - Algebra
一、兩個標量相加
在學習theano的開始,首先來感受下它是如何工作的,讓我們先來定義一個簡單的相加函數:
>>> import theano.tensor as T >>> from theano import function >>> x = T.dscalar('x') >>> y = T.dscalar('y') >>> z = x + y >>> f = function([x, y], z)
現在,我們可以使用之前創建好的函數,然后使用了:
>>> f(2, 3) array(5.0) >>> f(16.3, 12.1) array(28.4)
這里是將上面部分進行分步介紹。首先定義兩個符號 (變量)來表示你想要相加的數。注意到從現在開始,我們將會使用變量(Variable)來表示“符號”(換句話說,也就是 x, y, z 都是變量對象)。函數 f 的輸出就是一個有着0維的 numpy.ndarray 。
如果你想要輸入一個整數,你可能會發現在執行function的時候有輕微的延時。這是因為需要將函數 f 編譯成c 代碼。
第一步
>>> x = T.dscalar('x') >>> y = T.dscalar('y')
在theano中,所有的符號都必須手動輸入。具體來說,T.dscalar 就是我們分配給“doubles類型(d)的0維數組(scalar)”類型。這是一個theano類型 Type.
dscalar 不是一個類,所以 x 和 y 都不是 dscalar的實例。他們是 TensorVariable的實例 。正如下面看到的:
>>> type(x) <class 'theano.tensor.basic.TensorVariable'> >>> x.type TensorType(float64, scalar) >>> T.dscalar TensorType(float64, scalar) >>> x.type is T.dscalar True
通過一個字符串參數來調用 T.dscalar ,可以創建一個變量來表示一個給定名字下的一個浮點標量。如果你不提供參數,該符號將會是未命名的(unnamed)。雖然名字是不是必須的,可是卻有助於調試。
更多的可以看看theano的內部結構。同樣可以看看 Graph Structures.
第二步
第二步就是結合 x 與y 到它們的和z中
>>> z = x + y
z 是另一個變量用來表示 x 與 y的和. 你可以使用 pp 函數來友好的打印出與z 關聯的計算結果。
>>> from theano import pp >>> print pp(z) (x + y)
第三步
最后一步就是創建一個函數,將x 與 y 作為輸入,然后通過z 作為輸出:
>>> f = function([x, y], z)
function 的第一個參數是變量的列表,用來作為輸入提供給函數。第二個參數是一個單一的變量或者一個變量列表。在其他情況下,第二個變參數就是我們想要的輸出。然后f 就可以被和普通的python函數一樣使用了。
note:作為一個快捷方式,你可以跳過第三步,值使用一個變量的eval() 方法。 eval() 方法沒有 function() 這么靈活,不過卻能做教程中的任何事情。這是你不需要inport function() 的額外的福利. 下面就是 eval() 工作的過程:
>>> import theano.tensor as T >>> x = T.dscalar('x') >>> y = T.dscalar('y') >>> z = x + y >>> z.eval({x : 16.3, y : 12.1}) array(28.4)
我們給 eval()傳遞一個詞典,將符號theano變量映射成值從而來取代它們,然后對表達式返回數值。
eval() 在第一次調用的時候可能會比較慢,因為它需要調用 function() 來計算場景后面的表達式。之后對 eval() 以同樣的變量上的調用將會很快,因為變量已經將編譯后的函數進行緩存了。
二、兩個矩陣相加
你可能已經猜到如何來做了確實,這里與之前唯一的區別在於你需要實例化x 與y ,然后使用矩陣類型:
>>> x = T.dmatrix('x') >>> y = T.dmatrix('y') >>> z = x + y >>> f = function([x, y], z)
dmatrix 是doubles類型的矩陣,然后我們就能在2D數組上使用新的函數了:
>>> f([[1, 2], [3, 4]], [[10, 20], [30, 40]]) array([[ 11., 22.], [ 33., 44.]])
該變量是一個 NumPy 數組。我們同樣可以直接使用NumPy 數組作為輸入:
>>> import numpy >>> f(numpy.array([[1, 2], [3, 4]]), numpy.array([[10, 20], [30, 40]])) array([[ 11., 22.], [ 33., 44.]])
計算矩陣加標量、矩陣加向量、向量加標量都是可以的。這些能夠得以實現得歸功於broadcasting.
下面的類型都是可用的:
- byte: bscalar, bvector, bmatrix, brow, bcol, btensor3, btensor4
- 16-bit integers: wscalar, wvector, wmatrix, wrow, wcol, wtensor3, wtensor4
- 32-bit integers: iscalar, ivector, imatrix, irow, icol, itensor3, itensor4
- 64-bit integers: lscalar, lvector, lmatrix, lrow, lcol, ltensor3, ltensor4
- float: fscalar, fvector, fmatrix, frow, fcol, ftensor3, ftensor4
- double: dscalar, dvector, dmatrix, drow, dcol, dtensor3, dtensor4
- complex: cscalar, cvector, cmatrix, crow, ccol, ctensor3, ctensor4
上面的列表不夠詳盡,針對使用Numpy數組來兼容所有類型的更詳細文檔可以看: tensor creation.
note:你,用戶(不是系統架構者)不得不選擇你的程序為32- 或者 64-bit 的整數 (i 前綴 vs. l 前綴) 和浮點數 (f 前綴 vs. d 前綴).
三、練習
import theano a = theano.tensor.vector() # declare variable out = a + a ** 10 # build symbolic expression f = theano.function([a], out) # compile function print f([0, 1, 2]) # prints `array([0, 2, 1026])`
修改並計算這個表達式的結果: a ** 2 + b ** 2 + 2 * a * b.
下面就是答案:
#!/usr/bin/env python # Theano tutorial # Solution to Exercise in section 'Baby Steps - Algebra' from __future__ import print_function import theano a = theano.tensor.vector() # declare variable b = theano.tensor.vector() # declare variable out = a ** 2 + b ** 2 + 2 * a * b # build symbolic expression f = theano.function([a, b], out) # compile function print(f([1, 2], [4, 5])) # prints [ 25. 49.]
參考資料:
[1] 官網:http://deeplearning.net/software/theano/tutorial/adding.html