Theano虽然是基于Python的工具包,但它本身是属于符号语言,因此无法直接使用Python中的if语句。IfElse和Switch这两种操作都是基于符号变量建立约束条件。IfElse 将 boolean 作为条件,将两个变量作为输入;Switch将 tensor 作为条件,将两个变量作为输入。Switch 是一个逐元素的操作,这一特性使得它比IfElse更加通用。
Switch 在两个输出变量上进行评估,而 IfElse 只对一个关于条件的变量进行评估。
from theano import tensor as T
from theano.ifelse import ifelse
import theano, time, numpy
m,n = T.scalars('m', 'n')
x,y = T.matrices('x', 'y')
z_switch = T.switch(T.lt(m, n), T.mean(x), T.mean(y))
z_lazy = ifelse(T.lt(m, n), T.mean(x), T.mean(y))
f_switch = theano.function([m, n, x, y],
z_switch,mode=theano.Mode(linker='vm'))
f_lazyifelse = theano.function([m, n, 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))
运行结果如下所示。
python ifelse_switch.py
time spent evaluating both values 0.234337 sec
time spent evaluating one value 0.134876 sec
在这个例子中,IfElse 操作比Switch花费更少的时间,从结果中看,这次操作中IfElse节省了大约一半的时间。这是因为IfElse只计算了两个变量中的一个。
只有在使用linker='vm' 或者linker='cvm'的情况下,Ifelse才会计算两个变量,计算时间与Switch相同。综上所述,IfElse 与Switch主要区别有以下两点:
IfElse的条件表达式condition只支持标量值,而Switch的条件表达式可以是任意形式的符号变量。在实际使用Theano的过程中,Switch的应用更为广泛。
IfElse的运算具有惰性,从上面的例子中可以看出,IfElse的执行过程采用了“短路”策略,只会执行其中一个分支,而Switch会执行全部的分支,当全部分支执行完成后才根据条件表达式condition的值返回执行结果。
上一篇:了解比特币挖矿原理