Theano - 更多的例子
Logistic函數
import theano import theano.tensor as T x = T.dmatrix('x') s = 1 / (1 + T.exp(-x)) logistic = theano.function([x], s) logistic([[0, 1], [-1, -2]]) # s(x) = 1/(1+exp(-x)) = (1+tanh(x/2))/2 s2 = (1 + T.tanh(x / 2)) / 2 logistic2 = theano.function([x], s2) logistic2([[0, 1], [-1, -2]])同時執行多種計算任務
Theano支持多種輸出的函數。例如,我們可以同時計算兩個矩陣a,b相應元素之間的差、絕對差、平方差。當我們調用函數f是,返回三個變量:
import theano import theano.tensor as T a, b = T.dmatrices('a', 'b') diff = a - b abs_diff = abs(diff) diff_squared = diff ** 2 f = theano.function([a, b], [diff, abs_diff, diff_squared]) f([[1, 1], [1, 1]], [[0, 1], [2, 3]])為參數設置默認值
假設我們要定義一個實現兩個數字加法的函數。如果你僅僅提供一個數字,另一個數字假設(默認)為1,就可以這么做:
from theano import In, function import theano.tensor as T x, y = T.dscalars('x', 'y') z = x + y f = function([x, In(y, value=1)], z) f(33) f(33, 2)含有默認值的輸入必須位于不含默認值的輸入之后(和python的函數類似)。允許多個輸入含有默認值,這些參數可以通過位置設定,也可以通過名字進行設定。
x, y, w = T.dscalars('x', 'y', 'w') z = (x + y) * w f = function([x, In(y, value=1), In(w, value=2, name='w_by_name')], z) f(33) f(33, 2) f(33, 0, 1) f(33, w_by_name=1) f(33, w_by_name=1, y=0)In 不知道通過參數傳遞的局部變量x,y的名字。符號變量對象擁有名字(name)屬性(在上本例中通過dscalars進行設置),這也是我們構建函數function關鍵字參數的名字。通過In(y, value=1)這一機制實現。在In(w, value=2, name='w_by_name')中,我們重寫了符號變量的名字屬性。所有當我們通過f(x=33, y=0, w=1)的形式調用函數時,就會出錯。w應該改為w_by_name.
使用共享變量
我們也可以構建一個含有內狀態(internal state)的函數。例如,假設我們要構造一個累加函數(accumulator):初始狀態設置為0。接著,每次調用函數,狀態就會通過函數的參數自動增加。
# 首先,我們定義一個累加函數。它將自己的內狀態加上它的參數,然后返回舊狀態的值。 import theano import theano.tensor as T from theano import shared state = shared(0) inc = T.iscalar('inc') accumulator = function([inc], state, updates=[(state, state+inc)])# state的值可以通過.get_value()和.set_value()驚行獲取和修改 state.get_value() accumulator(1) state.get_value() accumulator(300) state.get_value()state.set_value(-1) accumulator(3) state.get_value()# 我們可以構造多個函數,使用相同共享變量,這些函數都可以更新狀態的值 decrementor = function([inc], state, updates=[(state, state-inc)]) decrementor(2) state.get_value()# 可能你會使用一個共享變量表達多個公式,但是你并不想使用共享變量的值。 # 這種情況下,你可以使用function中的givens參數。 fn_of_state = state * 2 + inc foo = T.scalar(dtype=state.dtype) # foo的類型必須和將要通過givens取代的共享變量的類型保持一致 skip_shared = function([inc, foo], fn_of_state, givens=[(state, foo)]) skip_shared(1, 3) # 我們正在使用3作為state,并非state.value state.get_value() # 舊的狀態(state)一直存在,但是我們使用它。復制函數(copying functions)
Theano中的函數可以被復制,被用于構造相似的函數(擁有不同的共享變量和更新),這可以通過function中的copy()實現。讓我們從以上定義的累加函數(accumulator)開始:
import theano import theano.tensor as T state = theano.shared(0) inc = T.iscalar('inc') accumulator = function([inc], state, updates=[(state, state+inc)]) # 我們可以像平常一樣增加它的狀態(state) accumulator(10) state.get_value() # 我們可以用copy()創建一個相似的累加器(accumulator),但是可以通過swap參數擁有自己的內狀態, # swap參數是將要交換的共享參數字典 new_state = theano.shared(0) new_accumulator = accumulator.copy(swap={state:new_state}) new_accumulator(100) new_state.get_value() state.get_value()# 現在我們創建一個復制,但是使用delete_updates參數移除更新,此時,默認為False # 此時,共享狀態將不會再更新。 null_accumulator = accumulator.copy(delete_updates=True) null_accumulator(9000) state.get_value()使用隨機數(Using Random Numbers)
簡潔的例子
from theano.tensor.shared_randomstreams import RandomStreams from theano import function srng = RandomStreams(seed=324) rv_u = srng.uniform((2,2)) rv_n = srng.normal((2,2)) f = function([], rv_u) g = function([], rv_n, no_default_updates=True) # 不更新rv_n.rng nearly_zeros = function([], rv_u + rv_u - 2 * rv_u)# rv_u表示服從均勻分布的2*2隨機數矩陣 # rv_n表示服從正太分布的2*2隨機數矩陣 # 現在我們來調用這些對象。如果調用f(),我們將會得到隨機均勻分布數。 # 隨機數產生器的內狀態將會自動更新,所以我們每次調用f()時將會得到不同的隨機數 f_val0 = f() f_val1 = f()# 當我們添加額外的參數no_default_updates=True(在函數g中)后,隨機數產生器的狀態將不會受調用函數的影響。 # 例如:多次調用g()將會返回相同的隨機數,g_val0和g_val1相同。 g_val0 = g() g_val1 = g()# 一個重要的觀點是:一個隨機變量在一次調用函數期中最多只能構建一次。 # 所以nearly_zeros函數保證了輸出近似為0,盡管rv_u隨機變量在輸出表達式中出現了3次。 nearly_zeros()種子流(Seeding Streams)
隨機變量可以單獨也可以共同產生,你可以通過對.rng屬性進行seeding或者使用.rng.set_value()對.rng進行賦值產生一個隨機變量。
rng_val = rv_u.rng.get_value(borrow=True) # 獲取rv_u的rng(隨機數生成器) rng_val.seed(89234) # 對generator(生成器)進行seeds(播種) rv_u.rng.set_value(rng_val, borrow=True) # 對rng進行賦值# 你可以seed由RandomStreams對象分配的所有隨機變量。 srng.seed(902340)函數之間共享流(Sharing Streams Between Functions)
像共享變量一樣,隨機變量使用的隨機數生成器在不同函數之間是相同的。所以我們的nearly_zeros函數將會更新f函數使用的生成器的狀態。例如:
state_after_v0 = rv_u.rng.get_value().get_state() nearly_zeros() # 這將會影響rv_u的生成器 v1 = f() rng = rv_u.rng.get_value(borrow=True) rng.set_state(state_after_v0) rv_u.rng.set_value(rng, borrow=True) v2 = f() # v2 != v1 v3 = f() # v3 == v1在Theano Graphs之間復制隨機狀態
在很多應用場景中,使用者可能想把一個theano graph(圖:g1,內置函數:f1)中的所有隨機數生成器的狀態傳遞給第二個theano graph(圖:g2,內置函數:f2)。
例如:如果你試圖從之前儲存模型的參數中,初始化一個模型的狀態,將會出現上述需要。theano.tensor.shared_randomstreams.RandomStreams和theano.sandbox.rng_mrg.MRG_RandomStreams這些在state_updates參數的復制元素可以實現。
每一次從RandomStreams對象中生成一個隨機變量,將會有一個元組添加到state_update列表中。 第一個元素是共享變量:它表示和特定變量相關的隨機數生成器的狀態。第二個元素表示和隨機數生成過程相對應的theano graph。
下面的例子展示了:隨機狀態(random states)如何從一個theano function 傳遞給另一個theano function中的。
import theano import numpy import theano.tensor as T from theano.sandbox.rng_mrg import MRG_RandomStreams from theano.tensor.shared_randomstreams import RandomStreamsclass 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)# 默認情況下,兩個函數f1,f2不同步 f1() f2()def copy_random_state(g1, g2):if isinstance(g1.rng, MRG_RandomStreams):g2.rng.rstate = g1.rng.rstatefor (su1, su2) in zip(g1.rng.state_updates, g2.rng.state_updates):su2[0].set_value(su1[0].get_value())# 現在我們賦值theano隨機數生成器的狀態 copy_random_state(g1, g2) f1() f2()一個真實的例子:邏輯回歸
import numpy import theano import theano.tensor as T rng = numpy.randomN = 400 # training sample size feats = 784 # number of input variables# generate a data set: D = (input_values, target_class) D = (rng.rand(N, feats), rng.randint(size=N, low=0, high=2)) training_steps = 10000# Declare Theano symbolic variables x = T.dmatrix('x') y = T.dvector('y')# initialize the weight vector w randomly # # this and the following bias variable b # are shared so they keep their values # between training iterations (updates) w = theano.shared(rng.randn(feats), name='w')# initialize the bias term b = theano.shared(0., name='b')print('Initial model:') print(w.get_value()) print(b.get_value())# Construct Theano expression graph p_1 = 1 / (1 + T.exp(-T.dot(x, w) - b)) # Probability that target = 1 prediction = p_1 > 0.5 # The prediction thresholded xent = -y * T.log(p_1) - (1-y) * T.log(1-p_1) # Cross-entropy loss function cost = xent.mean() + 0.01 * (w ** 2).sum() # The cost to minimize gw, gb = T.grad(cost, [w, b]) # Compute the gradient of the cost# Compile train = theano.function(inputs=[x,y],outputs=[prediction, xent],updates=((w, w - 0.1 * gw), (b, b - 0.1 * gb)) )predict = theano.function(inputs=[x], outputs=prediction)# Train for i in range(training_steps):pred, err = train(D[0], D[1])print('Final model:') print(w.get_value()) print(b.get_value()) print('target values for D:') print(D[1]) print('prediction on D:') print(predict(D[0]))總結
以上是生活随笔為你收集整理的Theano - 更多的例子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬虫:爬取医药数据库drug
- 下一篇: 华三交换机版本升级 华三交换机版本升级通