http://deeplearning.net/software/theano/tutorial/conditions.html
IfElse vs Switch
- Both ops build a condition over symbolic variables.
IfElse
takes a boolean condition and two variables as inputs.Switch
takes a tensor as condition and two variables as inputs.switch
is an elementwise operation and is thus more general thanifelse
.- Whereas
switch
evaluates both output variables,ifelse
is lazy and only evaluates one variable with respect to the condition.
ifelse的使用:
>>> from theano.ifelse import ifelse
>>> a,b=T.dscalars('a','b')
>>> x=T.dscalar('x')
>>> y=T.dscalar('y')
>>> z=ifelse(T.lt(a,b),x+y,x-y)
>>> ifelseFun=theano.function([a,b,x,y],z,mode=theano.Mode(linker='vm'))
>>> AltB=ifelseFun(1,2,3,4)
>>> print AltB
7.0
>>> BltA=ifelseFun(2,1,3,4)
>>> print BltA
-1.0
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
op (两个都需要)的一半。
注意:Unless linker='vm'
or linker='cvm'
are used, ifelse
will compute both variables and take the same computation time as switch
. Although the linker is not currently set by default to cvm
, it will be in the near future.