def test_local_sigm_times_exp(self): """ Test the `local_sigm_times_exp` optimization. exp(x) * sigm(-x) -> sigm(x) exp(-x) * sigm(x) -> sigm(-x) """ def match(func, ops): #print [node.op.scalar_op for node in func.maker.env.toposort()] assert [node.op for node in func.maker.env.toposort()] == ops m = self.get_mode(excluding=['local_elemwise_fusion', 'inplace']) x, y = tensor.vectors('x', 'y') f = theano.function([x], sigmoid(-x) * tensor.exp(x), mode=m) theano.printing.debugprint(f) match(f, [sigmoid]) f = theano.function([x], sigmoid(x) * tensor.exp(-x), mode=m) theano.printing.debugprint(f) match(f, [tensor.neg, sigmoid]) f = theano.function([x], -(-(-(sigmoid(x)))) * tensor.exp(-x), mode=m) theano.printing.debugprint(f) match(f, [tensor.neg, sigmoid, tensor.neg]) f = theano.function( [x, y], (sigmoid(x) * sigmoid(-y) * -tensor.exp(-x) * tensor.exp(x * y) * tensor.exp(y)), mode=m) theano.printing.debugprint(f) match(f, [sigmoid, tensor.mul, tensor.neg, tensor.exp, sigmoid, tensor.mul, tensor.neg])
def test_compute_mul(self): x, y, z = tensor.vectors('x', 'y', 'z') tree = (x * y) * -z mul_tree = parse_mul_tree(tree) assert parse_mul_tree(compute_mul(mul_tree)) == mul_tree assert theano.gof.graph.is_same_graph( compute_mul(parse_mul_tree(tree)), tree)
def test_local_sigm_times_exp(self): """ Test the `local_sigm_times_exp` optimization. exp(x) * sigm(-x) -> sigm(x) exp(-x) * sigm(x) -> sigm(-x) """ def match(func, ops): #print [node.op.scalar_op for node in func.maker.env.toposort()] assert [node.op for node in func.maker.env.toposort()] == ops m = self.get_mode(excluding=['local_elemwise_fusion', 'inplace']) x, y = tensor.vectors('x', 'y') f = theano.function([x], sigmoid(-x) * tensor.exp(x), mode=m) match(f, [sigmoid]) f = theano.function([x], sigmoid(x) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid]) f = theano.function([x], -(-(-(sigmoid(x)))) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid, tensor.neg]) f = theano.function([x, y], (sigmoid(x) * sigmoid(-y) * -tensor.exp(-x) * tensor.exp(x * y) * tensor.exp(y)), mode=m) match(f, [ sigmoid, tensor.mul, tensor.neg, tensor.exp, sigmoid, tensor.mul, tensor.neg ])
def test_parse_mul_tree(self): x, y, z = tensor.vectors("x", "y", "z") assert parse_mul_tree(x * y) == [False, [[False, x], [False, y]]] assert parse_mul_tree(-(x * y)) == [True, [[False, x], [False, y]]] assert parse_mul_tree(-x * y) == [False, [[True, x], [False, y]]] assert parse_mul_tree(-x) == [True, x] assert parse_mul_tree((x * y) * -z) == [False, [[False, [[False, x], [False, y]]], [True, z]]]
def test_perform_sigm_times_exp(self): """ Test the core function doing the `sigm_times_exp` optimization. It is easier to test different graph scenarios this way than by compiling a theano function. """ x, y, z, t = tensor.vectors("x", "y", "z", "t") exp = tensor.exp def ok(expr1, expr2): trees = [parse_mul_tree(e) for e in (expr1, expr2)] perform_sigm_times_exp(trees[0]) trees[0] = simplify_mul(trees[0]) good = theano.gof.graph.is_same_graph(compute_mul(trees[0]), compute_mul(trees[1])) if not good: print trees[0] print trees[1] print "***" theano.printing.debugprint(compute_mul(trees[0])) print "***" theano.printing.debugprint(compute_mul(trees[1])) assert good ok(sigmoid(x) * exp(-x), sigmoid(-x)) ok(-x * sigmoid(x) * (y * (-1 * z) * exp(-x)), -x * sigmoid(-x) * (y * (-1 * z))) ok( -sigmoid(-x) * (exp(y) * (-exp(-z) * 3 * -exp(x)) * (y * 2 * (-sigmoid(-y) * (z + t) * exp(z)) * sigmoid(z))) * -sigmoid(x), sigmoid(x) * (-sigmoid(y) * (-sigmoid(-z) * 3) * (y * 2 * ((z + t) * exp(z)))) * -sigmoid(x), ) ok(exp(-x) * -exp(-x) * (-sigmoid(x) * -sigmoid(x)), -sigmoid(-x) * sigmoid(-x)) ok(-exp(x) * -sigmoid(-x) * -exp(-x), -sigmoid(-x))
def test_parse_mul_tree(self): x, y, z = tensor.vectors('x', 'y', 'z') assert parse_mul_tree(x * y) == [False, [[False, x], [False, y]]] assert parse_mul_tree(-(x * y)) == [True, [[False, x], [False, y]]] assert parse_mul_tree(-x * y) == [False, [[True, x], [False, y]]] assert parse_mul_tree(-x) == [True, x] assert parse_mul_tree((x * y) * -z) == [ False, [[False, [[False, x], [False, y]]], [True, z]] ]
def test_perform_sigm_times_exp(self): """ Test the core function doing the `sigm_times_exp` optimization. It is easier to test different graph scenarios this way than by compiling a theano function. """ x, y, z, t = tensor.vectors('x', 'y', 'z', 't') exp = tensor.exp def ok(expr1, expr2): trees = [parse_mul_tree(e) for e in (expr1, expr2)] perform_sigm_times_exp(trees[0]) trees[0] = simplify_mul(trees[0]) good = theano.gof.graph.is_same_graph(compute_mul(trees[0]), compute_mul(trees[1])) if not good: print trees[0] print trees[1] print '***' theano.printing.debugprint(compute_mul(trees[0])) print '***' theano.printing.debugprint(compute_mul(trees[1])) assert good ok(sigmoid(x) * exp(-x), sigmoid(-x)) ok(-x * sigmoid(x) * (y * (-1 * z) * exp(-x)), -x * sigmoid(-x) * (y * (-1 * z))) ok( -sigmoid(-x) * (exp(y) * (-exp(-z) * 3 * -exp(x)) * (y * 2 * (-sigmoid(-y) * (z + t) * exp(z)) * sigmoid(z))) * -sigmoid(x), sigmoid(x) * (-sigmoid(y) * (-sigmoid(-z) * 3) * (y * 2 * ((z + t) * exp(z)))) * -sigmoid(x)) ok( exp(-x) * -exp(-x) * (-sigmoid(x) * -sigmoid(x)), -sigmoid(-x) * sigmoid(-x)) ok(-exp(x) * -sigmoid(-x) * -exp(-x), -sigmoid(-x))