译者:Python 文档协作翻译小组,原文:Conditions。 本文以 CC BY-NC-SA 4.0 协议发布,转载请保留作者署名和文章出处。
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函数的执行期间不引起任何改变。