7.2.4 條件
譯者:Python 文檔協作翻譯小組,原文:Conditions。
本文以 CC BY-NC-SA 4.0 協議發布,轉載請保留作者署名和文章出處。
Python 文檔協作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
IfElse和Switch
- 這兩個op在符號變量上構建一個條件。
-
IfElse
接收一個布爾條件和兩個變量作為輸入。 -
Switch
接收一個張量作為條件,兩個變量作為輸入。switch
是按元素操作,因此比ifelse
更通用。 -
switch
對兩個輸出變量同時求值,ifelse
是延遲的并且只求值一個條件的變量。
示例
from theano import tensor as T
from theano.ifelse import ifelse
import theano, time, numpy
a,b = T.scalars('a', 'b')
x,y = T.matrices('x', 'y')
z_switch = T.switch(T.lt(a, b), T.mean(x), T.mean(y))
z_lazy = ifelse(T.lt(a, b), T.mean(x), T.mean(y))
f_switch = theano.function([a, b, x, y], z_switch,
mode=theano.Mode(linker='vm'))
f_lazyifelse = theano.function([a, b, x, y], z_lazy,
mode=theano.Mode(linker='vm'))
val1 = 0.
val2 = 1.
big_mat1 = numpy.ones((10000, 1000))
big_mat2 = numpy.ones((10000, 1000))
n_times = 10
tic = time.clock()
for i in range(n_times):
f_switch(val1, val2, big_mat1, big_mat2)
print('time spent evaluating both values %f sec' % (time.clock() - tic))
tic = time.clock()
for i in range(n_times):
f_lazyifelse(val1, val2, big_mat1, big_mat2)
print('time spent evaluating one value %f sec' % (time.clock() - tic))
在這個例子中,IfElse
op比起Switch
花費更少的時間(大約一半),因為它只計算兩個變量中的一個。
$ python ifelse_switch.py
time spent evaluating both values 0.6700 sec
time spent evaluating one value 0.3500 sec
除非使用linker='vm'
或linker='cvm'
,ifelse
將計算兩個變量并花費與switch
相同的計算時間。雖然linker當前未默認設置為cvm
,但在不久的將來將會設置為它。
沒有自動優化將switch
替換為使用broadcasted的標量的ifelse
,因為這不總是更快。查看這個ticket。
注意
如果你使用test values,則將計算IfElse的所有分支。這是正常的,因為使用test_value意味著當我們構建它時,由于Python的貪婪評估和測試值的語義,所有的都將被計算。當我們構建兩個分支時,它們都將被執行測試值。這在編譯的Theano函數的執行期間不引起任何改變。