7.2.1 起手式 —— 代數(shù)
譯者:Python 文檔協(xié)作翻譯小組凡橱,原文:Baby Steps - Algebra。
本文以 CC BY-NC-SA 4.0 協(xié)議發(fā)布譬胎,轉載請保留作者署名和文章出處宫静。
Python 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們柿究,完全公益性質。交流群:467338606黄选。
兩個標量相加
為了讓我們開始使用Theano并獲得我們正在使用的感覺蝇摸,讓我們做一個簡單的函數(shù):將兩個數(shù)字加在一起。這里是你怎么做:
>>> import numpy
>>> 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)
現(xiàn)在我們已經創(chuàng)建了我們的函數(shù)办陷,我們可以使用它:
>>> f(2, 3)
array(5.0)
>>> numpy.allclose(f(16.3, 12.1), 28.4)
True
讓我們分成幾個步驟貌夕。第一步是定義兩個符號(變量),表示要相加的數(shù)量民镜。注意啡专,從現(xiàn)在起,我們將使用術語變量來表示“符號”(換句話說制圈,x们童、y、z都是變量對象)鲸鹦。函數(shù)f的輸出是零維度的numpy.ndarray
慧库。
如果你正在跟著輸入解釋器,你可能已經注意到執(zhí)行function
指令有一點點延遲馋嗜。在幕后齐板,f正在被編譯成C代碼。
步驟1
>>> x = T.dscalar('x')
>>> y = T.dscalar('y')
在Theano中,所有的符號必須具有類型甘磨。特別地橡羞,T.dscalar
是我們分配給“0維數(shù)組(雙精度浮點數(shù)(d
)的標量
)”的類型。它是Theano的Type類型济舆。
dscalar
不是類卿泽。因此佩番,x或y都不是dscalar
的實例促绵。它們是TensorVariable
的實例。然而稻励,x和y的type
字段賦值為theano的dscalar
類型椎瘟,正如你在下面看到的:
>>> type(x)
<class 'theano.tensor.var.TensorVariable'>
>>> x.type
TensorType(float64, scalar)
>>> T.dscalar
TensorType(float64, scalar)
>>> x.type is T.dscalar
True
通過使用字符串參數(shù)調用T.dscalar
覆致,你將創(chuàng)建一個給定名稱的變量,表示一個浮點數(shù)標量肺蔚。如果你不提供參數(shù)煌妈,符號將不會命名。名稱不是必需的宣羊,但它們可以幫助調試璧诵。
一會兒會更多地說到Theano的內部結構。你也可以通過查看Graph Structures了解更多仇冯。
步驟2
第二步是將x和y組合到它們的和z中:
>>> z = x + y
z是另一個變量之宿,表示x和y相加。你可以使用pp函數(shù)精確打印與z相關的計算苛坚。
>>> from theano import pp
>>> print(pp(z))
(x + y)
步驟3
最后一步是創(chuàng)建一個以x和y作為輸入并將z作為輸出的函數(shù):
>>> f = function([x, y], z)
function
的第一個參數(shù)是一個變量列表比被,它們將作為函數(shù)的輸入。第二個參數(shù)是單個變量或一個變量的列表泼舱。不管哪一種情況等缀,第二個參數(shù)是當我們應用函數(shù)時我們想要看到它的輸出。f可以像普通的Python函數(shù)一樣使用娇昙。
注意
作為一個捷徑尺迂,你可以跳過第3步,只需使用變量的eval
方法冒掌。eval()
方法不像function()
一樣靈活噪裕,但它可以完成我們在本教程中介紹的所有內容。它有額外的好處股毫,不需要你導入function()
州疾。下面是eval()
的工作原理:
>>> import numpy
>>> import theano.tensor as T
>>> x = T.dscalar('x')
>>> y = T.dscalar('y')
>>> z = x + y
>>> numpy.allclose(z.eval({x : 16.3, y : 12.1}), 28.4)
True
我們傳遞給eval()
一個字典,將theano的符號變量映射到值來替換它們皇拣,然后它返回表達式的數(shù)值严蓖。
eval()
在第一次調用變量時會變慢 - 需要調用function()
來編譯后臺表達式薄嫡。在同一變量上對eval()
的后續(xù)調用將很快,因為變量緩存編譯的函數(shù)颗胡。
兩個矩陣相加
你可能已經猜到如何做到這一點毫深。實際上,與上一個示例的唯一變化是毒姨,你需要使用矩陣類型實例化x和y:
>>> x = T.dmatrix('x')
>>> y = T.dmatrix('y')
>>> z = x + y
>>> f = function([x, y], z)
dmatrix
是雙精度矩陣的類型哑蔫。然后我們可以在二維數(shù)組上使用我們的新函數(shù):
>>> f([[1, 2], [3, 4]], [[10, 20], [30, 40]])
array([[ 11., 22.],
[ 33., 44.]])
變量是NumPy數(shù)組。我們也可以直接使用NumPy數(shù)組作為輸入:
>>> 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, btensor5
-
16-bit integers:
wscalar, wvector, wmatrix, wrow, wcol, wtensor3, wtensor4, wtensor5
-
32-bit integers:
iscalar, ivector, imatrix, irow, icol, itensor3, itensor4, itensor5
-
64-bit integers:
lscalar, lvector, lmatrix, lrow, lcol, ltensor3, ltensor4, ltensor5
-
float:
fscalar, fvector, fmatrix, frow, fcol, ftensor3, ftensor4, ftensor5
-
double:
dscalar, dvector, dmatrix, drow, dcol, dtensor3, dtensor4, dtensor5
-
complex:
cscalar, cvector, cmatrix, crow, ccol, ctensor3, ctensor4, ctensor5
前面的列表并不詳盡腥沽,并且可以在這里找到與NumPy數(shù)組兼容的所有類型的指南:tensor creation。
注意
你作為用戶必須選擇你的程序將使用32位還是64位整數(shù)(i
前綴還是l
前綴)和浮點數(shù)(f
前綴還是d
前綴)(不是系統(tǒng)架構來選擇 )鸠蚪。
練習
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]))
[ 0\. 2\. 1026.]
修改并執(zhí)行此代碼以計算此表達式:a ** 2 + b ** 2 + 2 * a * b今阳。