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)

輸入定義兩個符號變量來代替數值,輸出是一個0維的numpy.ndarray數組。

 

矩陣相加

把輸入類型換一下就行了,矩陣如果維數不同,會遵循NumPy的廣播規則。

import theano.tensor as T
from theano import function
x = T.dmatrix('x')
y = T.dmatrix('y')
z = x + y
f = function([x, y], z)

 

定義一個公式如:a ** 2 + b ** 2 + 2 * a* b

這裏每個變量都需要單獨申明。

import theano
a = theano.tensor.vector()
b = theano.tensor.vector()
out = a ** 2 + b ** 2 + 2 * a * b
f = theano.function([a,b],out)
print f([0, 1],[1,2])
>>> 
[ 1. 9.]

 

支持多輸出

import theano.tensor as T
from theano import function
a, b = T.dmatrices('a', 'b')
diff = a - b
abs_diff = abs(diff)
diff_squared = diff**2
f = function([a, b], [diff, abs_diff,diff_squared])
print f([[1, 1], [1, 1]], [[0, 1], [2,3]])
>>> 
[array([[ 1.,  0.],
      [-1., -2.]]), array([[ 1.,  0.],
      [ 1.,  2.]]), array([[ 1.,  0.],
      [ 1.,  4.]])]

 

設置默認參數

和標準Python一樣,缺省參數必須在非缺省之後,也可以定義缺省變量名。

import theano.tensor as T
from theano import function
from theano import Param
x, y = T.dscalars('x', 'y')
z = x + y
f = function([x, Param(y, default=1,name='by_name')],z)
print f(33)
print f(33, 2)
print f(33,by_name=3)
>>> 
34.0
35.0
36.0

 

共享變量

爲了在GPU上更好的性能,引入共享變量,以累加器爲例。

import theano.tensor as T
from theano import function
from theano import shared
state = shared(0)
inc = T.iscalar('inc')
accumulator = function([inc], state,updates=[(state, state+inc)])
print state.get_value()
accumulator(1)
print state.get_value()
accumulator(300)
print state.get_value()
state.set_value(-1)
print accumulator(3)
print state.get_value()
>>> 
0
1
301
-1
2

state的值在調用函數之後才刷新。而且可以定義多個函數共用同一個共享變量,例如這個減法器。

decrementor = function([inc], state,updates=[(state, state-inc)])
print decrementor(2)
print state.get_value()
>>> 
2
0

如果在某個函數中,共用了這個共享變量,但是又不想變動它的值,那麼可以使用given參數替代這個變量。而舊的state不發生變化。

fn_of_state = state * 2 + inc
foo = T.scalar(dtype=state.dtype)
skip_shared = function([inc, foo],fn_of_state,
                           givens=[(state,foo)])
print skip_shared(1, 3)
print state.get_value()
>>> 
7
0

 

產生隨機數

和C中的srand()一樣,都是僞隨機數。

from theano import function
from theano.tensor.shared_randomstreamsimport RandomStreams
srng = RandomStreams(seed=234)#種子
rv_u = srng.uniform((2,2))#均勻分佈
rv_n = srng.normal((2,2))#正態分佈
f = function([], rv_u)#每次調用,每次都會更新
g = function([], rv_n,no_default_updates=True)#如果以後一直用這組隨機數,就不再更新
nearly_zeros = function([], rv_u + rv_u- 2 * rv_u)
print nearly_zeros()#函數每次執行只獲得一個隨機數,即使表達式裏面有3個隨機數

種子流:上述2個隨機變量,可以全局設定同一個種子,也可以是分別設定。

#分別設置,使用.rng.set_value()函數
rng_val =rv_u.rng.get_value(borrow=True) # Get the rng for rv_u
rng_val.seed(89234) # seeds thegenerator
rv_u.rng.set_value(rng_val,borrow=True)
#全局設置,使用.seed()函數
srng.seed(902340)

函數間共享流

state_after_v0 =rv_u.rng.get_value().get_state()#保存調用前的state
nearly_zeros()       # this affects rv_u's generator
v1 = f()#第一個調用,之後state會變化
rng = rv_u.rng.get_value(borrow=True)
rng.set_state(state_after_v0)#爲其state還原
rv_u.rng.set_value(rng, borrow=True)
v2 = f()             # v2 != v1輸出更新後state對應的隨機數
v3 = f()             # v3 == v1再次更新又還原成原來的state了

 

在2張Theano圖間複製狀態

import theano
import numpy
import theano.tensor as T
from theano.sandbox.rng_mrg importMRG_RandomStreams
from theano.tensor.shared_randomstreamsimport RandomStreams
 
class Graph():
   def __init__(self, seed=123):
       self.rng = RandomStreams(seed)
       self.y = self.rng.uniform(size=(1,))
 
g1 = Graph(seed=123)
f1 = theano.function([], g1.y)
 
g2 = Graph(seed=987)
f2 = theano.function([], g2.y)
 
print 'By default, the two functionsare out of sync.'
print 'f1() returns ', f1()
print 'f2() returns ', f2()
#輸出不同的隨機值
def copy_random_state(g1, g2):
   if isinstance(g1.rng, MRG_RandomStreams):
#類型判斷:其第一個參數爲對象,第二個爲類型名或類型名的一個列表。其返回值爲布爾型。
       g2.rng.rstate = g1.rng.rstate
   for (su1, su2) in zip(g1.rng.state_updates, g2.rng.state_updates):#打包
       su2[0].set_value(su1[0].get_value())#賦值
 
print 'We now copy the state of thetheano random number generators.'
copy_random_state(g1, g2)
print 'f1() returns ', f1()
print 'f2() returns ', f2()
#輸出相同的隨機值
>>> 
By default, the two functions are outof sync.
f1() returns  [ 0.72803009]
f2() returns  [ 0.55056769]
We now copy the state of the theanorandom number generators.
f1() returns  [ 0.59044123]
f2() returns  [ 0.59044123]


歡迎參與討論並關注本博客微博以及知乎個人主頁後續內容繼續更新哦~

轉載請您尊重作者的勞動,完整保留上述文字以及文章鏈接,謝謝您的支持!

發佈了54 篇原創文章 · 獲贊 86 · 訪問量 47萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章