提交 9fb9dea1 authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Merge pull request #3991 from vmichals/keep_stack_trace_in_opt

keep stack trace in optimizations of nnet folder
......@@ -3,6 +3,7 @@ from theano.gradient import DisconnectedType
from theano.gof import Op, Apply, TopoOptimizer
from theano import tensor
import theano.sandbox.cuda as cuda
from theano.tensor.opt import copy_stack_trace
def get_diagonal_subtensor_view(x, i0, i1):
......@@ -328,7 +329,11 @@ def make_gpu_optimizer(op, to_gpu):
new_inp = list(node.inputs)
for idx in to_gpu:
new_inp[idx] = cuda.gpu_from_host(new_inp[idx])
return [cuda.host_from_gpu(op()(*new_inp))]
result_node = op()(*new_inp)
copy_stack_trace(node.outputs[0], result_node)
transfer_node = cuda.host_from_gpu(result_node)
copy_stack_trace(node.outputs[0], transfer_node)
return [transfer_node]
if node.op == cuda.gpu_from_host:
# gpu_from_host(op) -> op(gpu_from_host)
host_input = node.inputs[0]
......@@ -338,7 +343,9 @@ def make_gpu_optimizer(op, to_gpu):
new_inp = list(op_node.inputs)
for idx in to_gpu:
new_inp[idx] = cuda.gpu_from_host(new_inp[idx])
return [op()(*new_inp)]
new_node = op()(*new_inp)
copy_stack_trace(host_input, new_node)
return [new_node]
return False
local_to_gpu.__name__ = "local_to_gpu_" + op.__name__
cuda.opt.register_opt()(local_to_gpu)
......@@ -355,6 +362,7 @@ def local_inplace_DiagonalSubtensor(node):
not node.op.inplace):
new_op = node.op.__class__(inplace=True)
new_node = new_op(*node.inputs)
copy_stack_trace(node.outputs[0], new_node)
return [new_node]
return False
theano.compile.optdb.register(
......
......@@ -752,7 +752,8 @@ def local_logsoftmax(node):
inVars = node.inputs[0].owner.inputs[0]
new_op = LogSoftmax()
ret = new_op(inVars)
ret.tag.values_eq_approx = values_eq_approx_remove_inf
ret .tag.values_eq_approx = values_eq_approx_remove_inf
copy_stack_trace([node.inputs[0], node.outputs[0]], ret)
return [ret]
......@@ -785,9 +786,9 @@ def local_logsoftmax_grad(node):
grads = node.inputs[0].owner.inputs[0]
if grads.broadcastable[1] and not sm.broadcastable[1]:
grads = tensor.alloc(grads, grads.shape[0], sm.shape[1])
ret = grads - tensor.sum(grads, axis=1, keepdims=True) * sm
ret.tag.values_eq_approx = values_eq_approx_remove_nan
copy_stack_trace(node.outputs[0], ret)
return [ret]
......
......@@ -36,6 +36,7 @@ def local_inplace_sparse_block_gemv(node):
"""
if isinstance(node.op, SparseBlockGemv) and not node.op.inplace:
new_node = sparse_block_gemv_inplace(*node.inputs)
copy_stack_trace(node.outputs[0], new_node)
return [new_node]
return False
compile.optdb.register('local_inplace_sparse_block_gemv',
......@@ -52,6 +53,7 @@ def local_inplace_sparse_block_outer(node):
"""
if isinstance(node.op, SparseBlockOuter) and not node.op.inplace:
new_node = sparse_block_outer_inplace(*node.inputs)
copy_stack_trace(node.outputs[0], new_node)
return [new_node]
return False
compile.optdb.register('local_inplace_sparse_block_outer',
......
......@@ -18,13 +18,14 @@ from theano.printing import pprint
from theano.tensor import basic as tensor
from theano.tensor import elemwise, opt, NotScalarConstantError
from theano.tensor.type import values_eq_approx_remove_inf
from theano.tensor.opt import copy_stack_trace
############
#
# SCALAR OPS
#
class ScalarSigmoid(scalar.UnaryScalarOp):
"""
This is just speed opt. Not for stability.
......@@ -262,6 +263,7 @@ def local_ultra_fast_sigmoid(node):
if (isinstance(node.op, tensor.Elemwise) and
node.op.scalar_op == scalar_sigmoid):
out = ultra_fast_sigmoid(node.inputs[0])
copy_stack_trace(node.outputs[0], out)
def values_eq_approx_remove_low_prec(a, b):
# atol is found by trial/error.
......@@ -301,6 +303,7 @@ def local_hard_sigmoid(node):
if (isinstance(node.op, tensor.Elemwise) and
node.op.scalar_op == scalar_sigmoid):
out = hard_sigmoid(node.inputs[0])
copy_stack_trace(node.outputs[0], out)
def values_eq_approx_remove_low_prec(a, b):
# atol is found by trial/error.
......@@ -925,7 +928,10 @@ def local_sigm_times_exp(node):
# get rid of them.
mul_tree = simplify_mul(mul_tree)
# Recompute final output based on the updated tree.
return [compute_mul(mul_tree)]
out = compute_mul(mul_tree)
# keep the stack trace
copy_stack_trace(node.outputs[0], out)
return [out]
@opt.register_stabilize
......@@ -946,10 +952,17 @@ def local_inv_1_plus_exp(node):
if len(nonconsts) == 1:
if nonconsts[0].owner and nonconsts[0].owner.op == tensor.exp:
if scalars and numpy.allclose(numpy.sum(scalars), 1):
return opt._fill_chain(
out = opt._fill_chain(
sigmoid(
tensor.neg(nonconsts[0].owner.inputs[0])),
scalar_inputs)
# keep combined stack traces of
# exp(x): nonconsts[0],
# 1 + exp(x): inv_arg,
# 1 / (1 + exp(x)): node.outputs[0]
copy_stack_trace(
[nonconsts[0], inv_arg, node.outputs[0]], out)
return out
# Registration is below, and conditional.
......@@ -970,7 +983,9 @@ def local_1msigmoid(node):
except Exception:
return
if numpy.allclose(numpy.sum(val_l), 1):
return [sigmoid(-sub_r.owner.inputs[0])]
out = sigmoid(-sub_r.owner.inputs[0])
copy_stack_trace([sub_r, node.outputs[0]], out)
return [out]
register_local_1msigmoid = False
# This is False because the Stabilize pattern above
......
......@@ -73,6 +73,10 @@ def pyconv3d(signals, filters):
r_i += o_i[Tf2:o_i_sh0-Tf2, Hf2:-Hf2, Wf2:-Wf2]
return rval
def check_diagonal_subtensor_view_traces(fn):
for apply_node in fn.maker.fgraph.apply_nodes:
if isinstance(apply_node.op, (DiagonalSubtensor, IncDiagonalSubtensor)):
assert hasattr(apply_node.outputs[0].tag, 'trace')
def test_conv3d(mode=mode_without_gpu, shared=theano.tensor._shared):
if ndimage is None:
......@@ -100,6 +104,7 @@ def test_conv3d(mode=mode_without_gpu, shared=theano.tensor._shared):
updates={s_output: out},
mode=mode)
check_diagonal_subtensor_view_traces(newconv3d)
t0 = time.time()
newconv3d()
print(time.time() - t0)
......@@ -110,6 +115,7 @@ def test_conv3d(mode=mode_without_gpu, shared=theano.tensor._shared):
(s_signals, gsignals)],
mode=mode,
name='grad')
check_diagonal_subtensor_view_traces(gnewconv3d)
t0 = time.time()
gnewconv3d()
......@@ -144,6 +150,7 @@ def test_conv3d(mode=mode_without_gpu, shared=theano.tensor._shared):
newconv3d = theano.function([], [],
updates={s_output: out},
mode=mode)
check_diagonal_subtensor_view_traces(newconv3d)
t0 = time.time()
newconv3d()
......@@ -155,6 +162,7 @@ def test_conv3d(mode=mode_without_gpu, shared=theano.tensor._shared):
(s_signals, gsignals)],
mode=mode,
name='grad')
check_diagonal_subtensor_view_traces(gnewconv3d)
t0 = time.time()
gnewconv3d()
......
......@@ -139,6 +139,15 @@ class T_SoftmaxWithBias(utt.InferShapeTester):
f([0, 1, 0])
# print f.maker.fgraph.toposort()
def test_softmax_with_bias_trace(self):
a = theano.shared(
numpy.random.randn(3).astype(config.floatX))
b = theano.shared(numpy.float32(numpy.random.randn()))
sm = T.nnet.softmax(a + b)
f = theano.function([], sm)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
print('f.maker.fgraph.outputs[0]: {0}'.format(f.maker.fgraph.outputs[0], ))
def test_infer_shape(self):
admat = matrix()
advec = vector()
......@@ -201,11 +210,11 @@ class T_LogSoftmax(utt.InferShapeTester):
# numerically stable log-softmax with crossentropy
logsm = tensor.nnet.logsoftmax(x)
sm2 = tensor.exp(logsm) # just used to show equivalence with sm
cm2 = -tensor.sum(y*logsm, axis=1)
cm2 = -tensor.sum(y * logsm, axis=1)
grad = tensor.grad(cm2.mean(), x)
# create some inputs into a softmax that are large and labels
a = numpy.exp(10*numpy.random.rand(5, 10).astype(theano.config.floatX))
a = numpy.exp(10 * numpy.random.rand(5, 10).astype(theano.config.floatX))
# create some one-hot coded labels
b = numpy.eye(5, 10).astype(theano.config.floatX)
......@@ -242,6 +251,7 @@ class T_LogSoftmax(utt.InferShapeTester):
sm = tensor.nnet.softmax(x)
logsm = tensor.log(sm)
f = theano.function([x], logsm)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
assert isinstance(f.maker.fgraph.outputs[0].owner.op,
theano.tensor.nnet.nnet.LogSoftmax)
......@@ -257,7 +267,7 @@ class T_LogSoftmax(utt.InferShapeTester):
m.check_isfinite = False
# some inputs that are large to make the gradient explode in the non
# optimized case
a = numpy.exp(10*numpy.random.rand(5, 10).astype(theano.config.floatX))
a = numpy.exp(10 * numpy.random.rand(5, 10).astype(theano.config.floatX))
def myfunc(x):
sm = tensor.nnet.softmax(x)
......@@ -265,6 +275,8 @@ class T_LogSoftmax(utt.InferShapeTester):
return logsm
# We set step to 0.1 because for big values we need a big epsilon
utt.verify_grad(myfunc, [a], eps=0.1, mode=m)
f = theano.function([], myfunc(a))
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
class T_SoftmaxGrad(utt.InferShapeTester):
......@@ -289,7 +301,7 @@ class T_CrossentropySoftmax1Hot(unittest.TestCase):
def f(a, b):
return crossentropy_softmax_1hot_with_bias(a, b, y_idx)[0]
utt.verify_grad(f, [numpy.random.rand(3, 4),
numpy.random.rand(4)])
numpy.random.rand(4)])
def test1(self):
y_idx = [0, 1, 3]
......@@ -318,12 +330,12 @@ class T_CrossentropySoftmax1HotWithBiasDx(utt.InferShapeTester):
def test0(self):
def ff(class_dtype):
def f(sm):
# Class indices
y = numpy.random.randint(low=0, high=5, size=10).astype(class_dtype)
return theano.tensor.nnet.crossentropy_softmax_1hot_with_bias_dx(
numpy.random.rand(10), # Gradient w.r.t. NLL.
sm, # Softmax output.
y)
# Class indices
y = numpy.random.randint(low=0, high=5, size=10).astype(class_dtype)
return theano.tensor.nnet.crossentropy_softmax_1hot_with_bias_dx(
numpy.random.rand(10), # Gradient w.r.t. NLL.
sm, # Softmax output.
y)
return f
# Build a random softmax output whose rows sum to 1.
softmax_output = numpy.random.rand(10, 5)
......@@ -642,6 +654,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
fgraph = gof.FunctionGraph(
[x, one_of_n],
[g_x])
self.assertTrue(hasattr(fgraph.outputs[0].tag, 'trace'))
# print 'BEFORE'
# for node in fgraph.toposort():
......@@ -737,6 +750,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
for expr in expressions:
# Verify the optimizer worked on the expressions
f = theano.function([x, y], expr, mode=mode)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
if verbose:
theano.printing.debugprint(f)
try:
......@@ -752,6 +766,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
# Also verify the gradient wrt x
g = theano.function([x, y], T.grad(expr, x), mode=mode)
self.assertTrue(hasattr(g.maker.fgraph.outputs[0].tag, 'trace'))
if verbose:
theano.printing.debugprint(g)
try:
......@@ -774,6 +789,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
for expr in bias_expressions:
f = theano.function([x, b, y], expr, mode=mode)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
if verbose:
theano.printing.debugprint(f)
try:
......@@ -785,6 +801,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
theano.printing.debugprint(f)
raise
g = theano.function([x, b, y], T.grad(expr, x), mode=mode)
self.assertTrue(hasattr(g.maker.fgraph.outputs[0].tag, 'trace'))
if verbose:
theano.printing.debugprint(g)
try:
......@@ -807,6 +824,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
for expr in mean_expressions:
f = theano.function([x, y], expr, mode=mode)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
if verbose:
theano.printing.debugprint(f)
try:
......@@ -821,6 +839,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
raise
g = theano.function([x, y], T.grad(expr, x), mode=mode)
self.assertTrue(hasattr(g.maker.fgraph.outputs[0].tag, 'trace'))
if verbose:
theano.printing.debugprint(g)
try:
......@@ -844,6 +863,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
for expr in mean_bias_expressions:
f = theano.function([x, b, y], expr, mode=mode)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
if verbose:
theano.printing.debugprint(f)
try:
......@@ -856,6 +876,7 @@ class T_CrossentropyCategorical1Hot(utt.InferShapeTester):
theano.printing.debugprint(f)
raise
g = theano.function([x, b, y], T.grad(expr, x), mode=mode)
self.assertTrue(hasattr(g.maker.fgraph.outputs[0].tag, 'trace'))
if verbose:
theano.printing.debugprint(g)
try:
......@@ -1269,6 +1290,7 @@ def test_argmax_pushdown():
fgraph = gof.FunctionGraph(
[x],
[out])
assert hasattr(fgraph.outputs[0].tag, 'trace')
backup = config.warn.argmax_pushdown_bug
config.warn.argmax_pushdown_bug = False
......@@ -1297,6 +1319,8 @@ def test_argmax_pushdown_bias():
fgraph = gof.FunctionGraph(
[x, b],
[out])
f = theano.function([x, b], out)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
theano.compile.mode.optdb.query(
theano.compile.mode.OPT_FAST_RUN).optimize(fgraph)
......@@ -1316,12 +1340,14 @@ def test_argmax_pushdown_bias():
fgraph = gof.FunctionGraph(
[x, b],
[out])
f = theano.function([x, b], out)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
backup = config.warn.argmax_pushdown_bug
config.warn.argmax_pushdown_bug = False
try:
theano.compile.mode.optdb.query(
theano.compile.mode.OPT_FAST_RUN).optimize(fgraph)
theano.compile.mode.OPT_FAST_RUN).optimize(fgraph)
finally:
config.warn.argmax_pushdown_bug = backup
......@@ -1405,6 +1431,9 @@ class Test_softmax_opt:
# test that function contains softmax and no div.
f = theano.function([c], p_y, mode=self.mode)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
f_ops = [n.op for n in f.maker.fgraph.toposort()]
# print '--- f ='
# printing.debugprint(f)
......@@ -1419,6 +1448,9 @@ class Test_softmax_opt:
# test that function contains softmax and no div.
f = theano.function([c], p_y, mode=self.mode)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
f_ops = [n.op for n in f.maker.fgraph.toposort()]
# print '--- f ='
# printing.debugprint(f)
......@@ -1437,6 +1469,7 @@ class Test_softmax_opt:
config.warn.sum_div_dimshuffle_bug = False
try:
g = theano.function([c, w], T.grad((p_y * w).sum(), c))
hasattr(g.maker.fgraph.outputs[0].tag, 'trace')
finally:
config.warn.sum_div_dimshuffle_bug = backup
g_ops = [n.op for n in g.maker.fgraph.toposort()]
......@@ -1464,6 +1497,7 @@ class Test_softmax_opt:
config.warn.sum_div_dimshuffle_bug = False
try:
g = theano.function([c], T.grad(p_y.sum(), c))
hasattr(g.maker.fgraph.outputs[0].tag, 'trace')
finally:
config.warn.sum_div_dimshuffle_bug = backup
# printing.debugprint(g)
......@@ -1476,6 +1510,7 @@ class Test_softmax_opt:
# test that function contains softmax and no div.
f = theano.function([c], p_y)
hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
# printing.debugprint(f)
# test that function contains softmax and no div.
......@@ -1483,6 +1518,7 @@ class Test_softmax_opt:
config.warn.sum_div_dimshuffle_bug = False
try:
g = theano.function([c], T.grad(p_y.sum(), c))
hasattr(g.maker.fgraph.outputs[0].tag, 'trace')
finally:
config.warn.sum_div_dimshuffle_bug = backup
# printing.debugprint(g)
......@@ -1522,6 +1558,7 @@ def test_stabilize_log_softmax():
z = theano.tensor.log(y)
f = theano.function([x], z, mode=mode)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
# check that the softmax has been optimized out
for node in f.maker.fgraph.toposort():
......@@ -1621,7 +1658,6 @@ def test_h_softmax():
#############
x_mat = numpy.random.normal(size=(batch_size, input_size)).astype(floatX)
y_mat = numpy.random.randint(0, output_size, batch_size).astype('int32')
tg_output = fun_output_tg(x_mat, y_mat)
all_outputs = fun_output(x_mat)
......
......@@ -13,6 +13,7 @@ def test_blocksparse_inplace_gemv_opt():
o = sparse_block_dot(W, h, iIdx, b, oIdx)
f = theano.function([W, h, iIdx, b, oIdx], o)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
if theano.config.mode == "FAST_COMPILE":
assert not f.maker.fgraph.toposort()[-1].op.inplace
......@@ -33,6 +34,7 @@ def test_blocksparse_inplace_outer_opt():
f = theano.function([W, h, iIdx, b, oIdx],
[o, tensor.grad(o.sum(), wrt=W)])
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
if theano.config.mode == "FAST_COMPILE":
assert not f.maker.fgraph.toposort()[-1].op.inplace
......
......@@ -126,32 +126,40 @@ class T_sigmoid_opts(unittest.TestCase):
# tests inv_1_plus_exp
f = theano.function([x], T.fill(x, 1.0) / (1 + T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] == [sigmoid]
f(data)
f = theano.function([x], T.fill(x, 1.0) / (2 + T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid]
f(data)
f = theano.function([x], T.fill(x, 1.0) / (1 - T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid]
f(data)
f = theano.function([x], T.fill(x, 1.1) / (1 + T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid]
f(data)
# tests inv_1_plus_exp with neg
f = theano.function([x], T.fill(x, -1.0) / (1 + T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] == [sigmoid,
theano.tensor.inplace.neg_inplace]
f(data)
f = theano.function([x], T.fill(x, -1.0) / (1 - T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid,
theano.tensor.inplace.neg_inplace]
f(data)
f = theano.function([x], T.fill(x, -1.0) / (2 + T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid,
theano.tensor.inplace.neg_inplace]
f(data)
f = theano.function([x], T.fill(x, -1.1) / (1 + T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid,
theano.tensor.inplace.neg_inplace]
f(data)
......@@ -162,31 +170,37 @@ class T_sigmoid_opts(unittest.TestCase):
# = - (sigm(x) * sigm(x))
f = theano.function([x], (T.fill(x, -1.0) * T.exp(x)) /
((1 + T.exp(x)) * (1 + T.exp(-x))), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] == [sigmoid,
T.mul]
f(data)
f = theano.function([x], (T.fill(x, -1.1) * T.exp(x)) /
((1 + T.exp(x)) * (1 + T.exp(-x))), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid,
T.mul, theano.tensor.inplace.neg_inplace]
f(data)
f = theano.function([x], (T.fill(x, -1.0) * T.exp(x)) /
((2 + T.exp(x)) * (1 + T.exp(-x))), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid,
T.mul, theano.tensor.inplace.neg_inplace]
f(data)
f = theano.function([x], (T.fill(x, -1.0) * T.exp(x)) /
((1 + T.exp(x)) * (2 + T.exp(-x))), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid,
T.mul, theano.tensor.inplace.neg_inplace]
f(data)
f = theano.function([x], (T.fill(x, -1.0) * T.exp(x)) /
((1 + T.exp(x)) * (1 + T.exp(x))), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid,
T.mul, theano.tensor.inplace.neg_inplace]
f(data)
f = theano.function([x], (T.fill(x, -1.0) * T.exp(x)) /
((1 + T.exp(x)) * (2 + T.exp(-x))), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid,
T.mul, theano.tensor.inplace.neg_inplace]
f(data)
......@@ -204,11 +218,13 @@ class T_sigmoid_opts(unittest.TestCase):
# tests exp_over_1_plus_exp
f = theano.function([x], 1 - T.exp(x) / (1 + T.exp(x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] == [
tensor.neg, sigmoid_inplace]
# tests inv_1_plus_exp
f = theano.function([x], 1 - T.fill(x, 1.0) / (1 + T.exp(-x)), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
assert [node.op for node in f.maker.fgraph.toposort()] == [tensor.neg,
sigmoid_inplace]
......@@ -225,12 +241,15 @@ class T_sigmoid_opts(unittest.TestCase):
x, y = tensor.vectors('x', 'y')
f = theano.function([x], sigmoid(-x) * tensor.exp(x), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
match(f, [sigmoid])
f = theano.function([x], sigmoid(x) * tensor.exp(-x), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
match(f, [tensor.neg, sigmoid])
f = theano.function([x], -(-(-(sigmoid(x)))) * tensor.exp(-x), mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
match(f, [tensor.neg, sigmoid, tensor.neg])
f = theano.function(
......@@ -238,6 +257,7 @@ class T_sigmoid_opts(unittest.TestCase):
(sigmoid(x) * sigmoid(-y) * -tensor.exp(-x) *
tensor.exp(x * y) * tensor.exp(y)),
mode=m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
match(f, [sigmoid, tensor.mul, tensor.neg, tensor.exp, sigmoid,
tensor.mul])
......@@ -298,6 +318,7 @@ class T_sigmoid_opts(unittest.TestCase):
mode = self.get_mode()
if not isinstance(mode, theano.compile.DebugMode):
f = theano.function([x, lr], ux, mode=mode)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
ux_v = f([[50]], 0.1)
assert not numpy.isnan(ux_v)
......@@ -307,12 +328,14 @@ class T_sigmoid_opts(unittest.TestCase):
mode = self.get_mode('local_ultra_fast_sigmoid')
f = theano.function([x], s, mode=mode)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
assert topo[0].op == sigmoid
mode = self.get_mode().including('local_ultra_fast_sigmoid')
f = theano.function([x], s, mode=mode)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
topo = f.maker.fgraph.toposort()
assert topo[0].op == ultra_fast_sigmoid
assert len(topo) == 1
......@@ -324,12 +347,14 @@ class T_sigmoid_opts(unittest.TestCase):
mode = self.get_mode('local_hard_sigmoid')
f = theano.function([x], s, mode=mode)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
topo = f.maker.fgraph.toposort()
assert topo[0].op == sigmoid
assert len(topo) == 1
mode = self.get_mode().including('local_hard_sigmoid')
f = theano.function([x], s, mode=mode)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
topo = f.maker.fgraph.toposort()
assert len(topo) > 1
assert not any([n.op == sigmoid for n in topo])
......@@ -352,6 +377,7 @@ class T_softplus_opts(unittest.TestCase):
out = T.log(sigmoid(x))
f = theano.function([x], out, mode=self.m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
topo = f.maker.fgraph.toposort()
assert len(topo) == 3
assert isinstance(topo[0].op.scalar_op, theano.scalar.Neg)
......@@ -375,6 +401,7 @@ class T_softplus_opts(unittest.TestCase):
# Same test with a flatten
out = T.log(1 - T.flatten(sigmoid(x)))
f = theano.function([x], out, mode=self.m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
topo = f.maker.fgraph.toposort()
assert len(topo) == 3
assert tensor.is_flat(topo[0].outputs[0])
......@@ -403,6 +430,7 @@ class T_softplus_opts(unittest.TestCase):
out = T.log(1 + T.exp(x))
f = theano.function([x], out, mode=self.m)
assert hasattr(f.maker.fgraph.outputs[0].tag, 'trace')
topo = f.maker.fgraph.toposort()
assert len(topo) == 1
assert isinstance(topo[0].op.scalar_op,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论