簡體   English   中英

在Theano中使用隨機數

[英]Using Random Numbers in Theano

我是theano新手。

有人可以解釋下面的代碼嗎?

from theano.tensor.shared_randomstreams import RandomStreams
from theano import function
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)    #Not updating rv_n.rng
nearly_zeros = function([], rv_u + rv_u - 2 * rv_u)

state_after_v0 = rv_u.rng.get_value().get_state()
nearly_zeros()       # this affects rv_u's generator
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

Q1。 near_zeros()如何影響rv_u的生成器?
Q2。 為什么?

v2 != v1
v3 == v1

Q1

看起來rv_u的生成器只生成1“值”(即2x2矩陣)。 如果使用theano.printing.debugprint打印函數圖,則可以看到此信息。 作為參考,這是我得到的:

>>> theano.printing.debugprint(nearly_zeros)
Elemwise{Composite{((i0 + i0) - (i1 * i0))}}[(0, 0)] [@A] ''   1
 |RandomFunction{uniform}.1 [@B] ''   0
 | |<RandomStateType> [@C]
 | |TensorConstant{(2,) of 2} [@D]
 | |TensorConstant{0.0} [@E]
 | |TensorConstant{1.0} [@F]
 |TensorConstant{(1, 1) of 2.0} [@G]
RandomFunction{uniform}.0 [@B] ''   0

這意味着兩個函數(almost_zero和f)都只從rv_u中獲取1個值,這就是原因

v3 == v1

Q2

Theano主要是一個象征性的數學包。 您定義符號變量之間的關系,Theano計算出如何評估這些關系。

因此,您可以將rv_u視為表示單個2x2矩陣的變量,而不是每次“調用”時生​​成新的2x2矩陣的rng。 鑒於該視圖,Theano只需要調用底層rng一次即可獲得變量rv_u的值。

Q1

nearly_zeros() ,它使用隨機流的當前rng狀態返回一個新的rv_u並遞增狀態,就像它對函數f 查看rv_u發生了什么的最簡單方法是將其作為輸出添加到nearly_zeros()函數中。 雖然rv_u存在三次,但rv_u的值rv_u隨機流中采樣一次,因此nearly_zero確實幾乎為零(直到浮點量化誤差)。

nearly_zeros = function([], [rv_u, rv_u + rv_u - 2 * rv_u])
f() # The return value will be different from the rv_u in the list above

如果您不打算增加它,可以像對g一樣指定no_default_updates=True

nearly_zeros = function([], [rv_u, rv_u + rv_u - 2 * rv_u], 
     no_default_updates=True)
f() # The return value will be equal to the rv_u in the list above

Q2

這里的“為什么”有點含糊不清,所以我提出了兩種可能性。

Q2(一)

為什么使用nearly_zeros()以這種方式影響rv_u

rv_u是一個統一的srng對象,它使用一個共享變量,每次請求時都會遞增,除非另有說明(通過no_defalut_updates參數)。無論fnearly_zero恰好是請求值的函數,都是如此。 rv_u

Q2(b)中

為什么以下是真的:

from theano.tensor.shared_randomstreams import RandomStreams
from theano import function
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)    #Not updating rv_n.rng
nearly_zeros = function([], [rv_u, rv_u + rv_u - 2 * rv_u]) # Give rv_u, too

state_after_v0 = rv_u.rng.get_value().get_state()
nearly_zeros()       # this affects rv_u's generator
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, but equal to rv_u used by nearly_zeros
v3 = f()             # v3 == v1

這是因為您的代碼在定義nearly_zeros但在調用之前保存狀態。 設置狀態時,返回的第一個值是nearly_zeros使用的值(等於v2 。)請求的下一個值將等於v3的值。 以下是幾乎完全相同的代碼副本,它應該說明:

 from theano.tensor.shared_randomstreams import RandomStreams from theano import function 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) #Not updating rv_n.rng nearly_zeros = function([], [rv_u, rv_u + rv_u - 2 * rv_u]) # Give rv_u, too state_after_v0 = rv_u.rng.get_value().get_state() nearly_zeros() # this affects rv_u's generator 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, but equal to rv_u used by nearly_zeros v3 = f() # v3 == v1 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM