摘要:函數(shù)同時(shí)執(zhí)行多種計(jì)算任務(wù)支持多種輸出的函數(shù)。例如多次調(diào)用將會(huì)返回相同的隨機(jī)數(shù)和相同。第一個(gè)元素是共享變量它表示和特定變量相關(guān)的隨機(jī)數(shù)生成器的狀態(tài)。第二個(gè)元素表示和隨機(jī)數(shù)生成過(guò)程相對(duì)應(yīng)的。
Logistic函數(shù)
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]])同時(shí)執(zhí)行多種計(jì)算任務(wù)
Theano支持多種輸出的函數(shù)。例如,我們可以同時(shí)計(jì)算兩個(gè)矩陣a,b相應(yīng)元素之間的差、絕對(duì)差、平方差。當(dāng)我們調(diào)用函數(shù)f是,返回三個(gè)變量:
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]])為參數(shù)設(shè)置默認(rèn)值
假設(shè)我們要定義一個(gè)實(shí)現(xiàn)兩個(gè)數(shù)字加法的函數(shù)。如果你僅僅提供一個(gè)數(shù)字,另一個(gè)數(shù)字假設(shè)(默認(rèn))為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)
含有默認(rèn)值的輸入必須位于不含默認(rèn)值的輸入之后(和python的函數(shù)類(lèi)似)。允許多個(gè)輸入含有默認(rèn)值,這些參數(shù)可以通過(guò)位置設(shè)定,也可以通過(guò)名字進(jìn)行設(shè)定。
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 不知道通過(guò)參數(shù)傳遞的局部變量x,y的名字。符號(hào)變量對(duì)象擁有名字(name)屬性(在上本例中通過(guò)dscalars進(jìn)行設(shè)置),這也是我們構(gòu)建函數(shù)function關(guān)鍵字參數(shù)的名字。通過(guò)In(y, value=1)這一機(jī)制實(shí)現(xiàn)。在In(w, value=2, name="w_by_name")中,我們重寫(xiě)了符號(hào)變量的名字屬性。所有當(dāng)我們通過(guò)f(x=33, y=0, w=1)的形式調(diào)用函數(shù)時(shí),就會(huì)出錯(cuò)。w應(yīng)該改為w_by_name.
使用共享變量我們也可以構(gòu)建一個(gè)含有內(nèi)狀態(tài)(internal state)的函數(shù)。例如,假設(shè)我們要構(gòu)造一個(gè)累加函數(shù)(accumulator):初始狀態(tài)設(shè)置為0。接著,每次調(diào)用函數(shù),狀態(tài)就會(huì)通過(guò)函數(shù)的參數(shù)自動(dòng)增加。
# 首先,我們定義一個(gè)累加函數(shù)。它將自己的內(nèi)狀態(tài)加上它的參數(shù),然后返回舊狀態(tài)的值。 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的值可以通過(guò).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() # 我們可以構(gòu)造多個(gè)函數(shù),使用相同共享變量,這些函數(shù)都可以更新?tīng)顟B(tài)的值 decrementor = function([inc], state, updates=[(state, state-inc)]) decrementor(2) state.get_value() # 可能你會(huì)使用一個(gè)共享變量表達(dá)多個(gè)公式,但是你并不想使用共享變量的值。 # 這種情況下,你可以使用function中的givens參數(shù)。 fn_of_state = state * 2 + inc foo = T.scalar(dtype=state.dtype) # foo的類(lèi)型必須和將要通過(guò)givens取代的共享變量的類(lèi)型保持一致 skip_shared = function([inc, foo], fn_of_state, givens=[(state, foo)]) skip_shared(1, 3) # 我們正在使用3作為state,并非state.value state.get_value() # 舊的狀態(tài)(state)一直存在,但是我們使用它。復(fù)制函數(shù)(copying functions)
Theano中的函數(shù)可以被復(fù)制,被用于構(gòu)造相似的函數(shù)(擁有不同的共享變量和更新),這可以通過(guò)function中的copy()實(shí)現(xiàn)。讓我們從以上定義的累加函數(shù)(accumulator)開(kāi)始:
import theano import theano.tensor as T state = theano.shared(0) inc = T.iscalar("inc") accumulator = function([inc], state, updates=[(state, state+inc)]) # 我們可以像平常一樣增加它的狀態(tài)(state) accumulator(10) state.get_value() # 我們可以用copy()創(chuàng)建一個(gè)相似的累加器(accumulator),但是可以通過(guò)swap參數(shù)擁有自己的內(nèi)狀態(tài), # swap參數(shù)是將要交換的共享參數(shù)字典 new_state = theano.shared(0) new_accumulator = accumulator.copy(swap={state:new_state}) new_accumulator(100) new_state.get_value() state.get_value() # 現(xiàn)在我們創(chuàng)建一個(gè)復(fù)制,但是使用delete_updates參數(shù)移除更新,此時(shí),默認(rèn)為False # 此時(shí),共享狀態(tài)將不會(huì)再更新。 null_accumulator = accumulator.copy(delete_updates=True) null_accumulator(9000) state.get_value()使用隨機(jī)數(shù)(Using Random Numbers) 簡(jiǎn)潔的例子
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隨機(jī)數(shù)矩陣 # rv_n表示服從正太分布的2*2隨機(jī)數(shù)矩陣 # 現(xiàn)在我們來(lái)調(diào)用這些對(duì)象。如果調(diào)用f(),我們將會(huì)得到隨機(jī)均勻分布數(shù)。 # 隨機(jī)數(shù)產(chǎn)生器的內(nèi)狀態(tài)將會(huì)自動(dòng)更新,所以我們每次調(diào)用f()時(shí)將會(huì)得到不同的隨機(jī)數(shù) f_val0 = f() f_val1 = f() # 當(dāng)我們添加額外的參數(shù)no_default_updates=True(在函數(shù)g中)后,隨機(jī)數(shù)產(chǎn)生器的狀態(tài)將不會(huì)受調(diào)用函數(shù)的影響。 # 例如:多次調(diào)用g()將會(huì)返回相同的隨機(jī)數(shù),g_val0和g_val1相同。 g_val0 = g() g_val1 = g() # 一個(gè)重要的觀點(diǎn)是:一個(gè)隨機(jī)變量在一次調(diào)用函數(shù)期中最多只能構(gòu)建一次。 # 所以nearly_zeros函數(shù)保證了輸出近似為0,盡管rv_u隨機(jī)變量在輸出表達(dá)式中出現(xiàn)了3次。 nearly_zeros()種子流(Seeding Streams)
隨機(jī)變量可以多帶帶也可以共同產(chǎn)生,你可以通過(guò)對(duì).rng屬性進(jìn)行seeding或者使用.rng.set_value()對(duì).rng進(jìn)行賦值產(chǎn)生一個(gè)隨機(jī)變量。
rng_val = rv_u.rng.get_value(borrow=True) # 獲取rv_u的rng(隨機(jī)數(shù)生成器) rng_val.seed(89234) # 對(duì)generator(生成器)進(jìn)行seeds(播種) rv_u.rng.set_value(rng_val, borrow=True) # 對(duì)rng進(jìn)行賦值 # 你可以seed由RandomStreams對(duì)象分配的所有隨機(jī)變量。 srng.seed(902340)函數(shù)之間共享流(Sharing Streams Between Functions)
像共享變量一樣,隨機(jī)變量使用的隨機(jī)數(shù)生成器在不同函數(shù)之間是相同的。所以我們的nearly_zeros函數(shù)將會(huì)更新f函數(shù)使用的生成器的狀態(tài)。例如:
state_after_v0 = rv_u.rng.get_value().get_state() nearly_zeros() # 這將會(huì)影響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之間復(fù)制隨機(jī)狀態(tài)
在很多應(yīng)用場(chǎng)景中,使用者可能想把一個(gè)theano graph(圖:g1,內(nèi)置函數(shù):f1)中的所有隨機(jī)數(shù)生成器的狀態(tài)傳遞給第二個(gè)theano graph(圖:g2,內(nèi)置函數(shù):f2)。
例如:如果你試圖從之前儲(chǔ)存模型的參數(shù)中,初始化一個(gè)模型的狀態(tài),將會(huì)出現(xiàn)上述需要。theano.tensor.shared_randomstreams.RandomStreams和theano.sandbox.rng_mrg.MRG_RandomStreams這些在state_updates參數(shù)的復(fù)制元素可以實(shí)現(xiàn)。
每一次從RandomStreams對(duì)象中生成一個(gè)隨機(jī)變量,將會(huì)有一個(gè)元組添加到state_update列表中。 第一個(gè)元素是共享變量:它表示和特定變量相關(guān)的隨機(jī)數(shù)生成器的狀態(tài)。第二個(gè)元素表示和隨機(jī)數(shù)生成過(guò)程相對(duì)應(yīng)的theano graph。
下面的例子展示了:隨機(jī)狀態(tài)(random states)如何從一個(gè)theano function 傳遞給另一個(gè)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 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) # 默認(rèn)情況下,兩個(gè)函數(shù)f1,f2不同步 f1() 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()) # 現(xiàn)在我們賦值theano隨機(jī)數(shù)生成器的狀態(tài) copy_random_state(g1, g2) f1() f2()一個(gè)真實(shí)的例子:邏輯回歸
import numpy import theano import theano.tensor as T rng = numpy.random N = 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]))
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/38634.html
摘要:是怎么處理形狀信息在構(gòu)建圖的時(shí)候,不可能?chē)?yán)格執(zhí)行變量的形狀。形狀推斷問(wèn)題在圖中,將會(huì)傳播形狀的信息。以下情形是目前我們可以做到的當(dāng)調(diào)用時(shí),你可以直接把形狀信息傳遞給。例如你可以在圖的任何位置使用添加位置信息。 Theano是怎么處理形狀信息(Shape Information) 在構(gòu)建圖的時(shí)候,不可能?chē)?yán)格執(zhí)行Theano變量的形狀。因?yàn)樵谶\(yùn)行的時(shí)候,傳遞給Theano函數(shù)的某一參數(shù)的值...
摘要:另外,當(dāng)損失函數(shù)接近全局最小時(shí),概率會(huì)增加。降低訓(xùn)練過(guò)程中的學(xué)習(xí)率。對(duì)抗樣本的訓(xùn)練據(jù)最近信息顯示,神經(jīng)網(wǎng)絡(luò)很容易被對(duì)抗樣本戲弄。使用高度正則化會(huì)有所幫助,但會(huì)影響判斷不含噪聲圖像的準(zhǔn)確性。 由 Yoshua Bengio、 Leon Bottou 等大神組成的講師團(tuán)奉獻(xiàn)了 10 天精彩的講座,劍橋大學(xué)自然語(yǔ)言處理與信息檢索研究組副研究員 Marek Rei 參加了本次課程,在本文中,他精煉地...
摘要:八月初,我有幸有機(jī)會(huì)參加了蒙特利爾深度學(xué)習(xí)暑期學(xué)校的課程,由最知名的神經(jīng)網(wǎng)絡(luò)研究人員組成的為期天的講座。另外,當(dāng)損失函數(shù)接近全局最小時(shí),概率會(huì)增加。降低訓(xùn)練過(guò)程中的學(xué)習(xí)率。對(duì)抗樣本的訓(xùn)練據(jù)最近信息顯示,神經(jīng)網(wǎng)絡(luò)很容易被對(duì)抗樣本戲弄。 8月初的蒙特利爾深度學(xué)習(xí)暑期班,由Yoshua Bengio、 Leon Bottou等大神組成的講師團(tuán)奉獻(xiàn)了10天精彩的講座,劍橋大學(xué)自然語(yǔ)言處理與信息檢索研...
摘要:復(fù)發(fā)的一種常用形式,可以用于循環(huán)和是的特例可以根據(jù)一些輸出序列一個(gè)函數(shù),每一步都會(huì)生成一個(gè)輸出可以查看之前步的輸出給定一個(gè)初始狀態(tài)可以通過(guò)函數(shù)計(jì)算一個(gè)列表的和通常一個(gè)循環(huán)可以用操作符進(jìn)行實(shí)現(xiàn)使用的優(yōu)點(diǎn)迭代次數(shù)為符號(hào)圖的一部分最大限度地減少傳 Scan 復(fù)發(fā)(Recurrence)的一種常用形式,可以用于循環(huán)(looping) Reduction和map是scan的特例 可以根據(jù)一些輸...
摘要:我認(rèn)為對(duì)機(jī)器學(xué)習(xí)開(kāi)發(fā)者來(lái)說(shuō),是一個(gè)了不起的工具集。這個(gè)帖子發(fā)出后得到了很多機(jī)器學(xué)習(xí)研究者和開(kāi)發(fā)者的關(guān)注,他們紛紛跟貼談?wù)撟约旱南敕ê徒?jīng)驗(yàn)不只是關(guān)于和,討論中還涉及到更多工具。 Theano、TensorFlow、Torch、MXNet 再到近日比較熱門(mén)的 PyTorch 等等,深度學(xué)習(xí)框架之間的比較一直以來(lái)都是非常受人關(guān)注的熱點(diǎn)話題。機(jī)器之心也曾發(fā)表過(guò)多篇相關(guān)的介紹和對(duì)比文章,如《主流深度學(xué)...
閱讀 2613·2021-09-26 10:17
閱讀 3236·2021-09-22 15:16
閱讀 2145·2021-09-03 10:43
閱讀 3271·2019-08-30 11:23
閱讀 3667·2019-08-29 13:23
閱讀 1315·2019-08-29 11:31
閱讀 3699·2019-08-26 13:52
閱讀 1404·2019-08-26 12:22