提交 29b9b721 authored 作者: fsavard's avatar fsavard

Merge

...@@ -601,7 +601,7 @@ dimensions, see :meth:`_tensor_py_operators.dimshuffle` ...@@ -601,7 +601,7 @@ dimensions, see :meth:`_tensor_py_operators.dimshuffle`
Create a matrix by filling the shape of `a` with `b` Create a matrix by filling the shape of `a` with `b`
.. function:: eye(n, m = None, k = 0, dtype='float64') .. function:: eye(n, m = None, k = 0, dtype=theano.config.floatX)
:param n: number of rows in output (value or theano scalar) :param n: number of rows in output (value or theano scalar)
:param m: number of columns in output (value or theano scalar) :param m: number of columns in output (value or theano scalar)
...@@ -628,6 +628,7 @@ Reductions ...@@ -628,6 +628,7 @@ Reductions
:Parameter: *x* - symbolic Tensor (or compatible) :Parameter: *x* - symbolic Tensor (or compatible)
:Parameter: *axis* - axis along which to compute the maximum :Parameter: *axis* - axis along which to compute the maximum
:Returns: the maximum value along a given axis :Returns: the maximum value along a given axis
:note: see maximum for elemwise max
If axis=None, then axis is assumed to be ndim(x)-1 If axis=None, then axis is assumed to be ndim(x)-1
...@@ -636,6 +637,7 @@ Reductions ...@@ -636,6 +637,7 @@ Reductions
:Parameter: *x* - symbolic Tensor (or compatible) :Parameter: *x* - symbolic Tensor (or compatible)
:Parameter: *axis* - axis along which to compute the minimum :Parameter: *axis* - axis along which to compute the minimum
:Returns: the minimum value along a given axis :Returns: the minimum value along a given axis
:note: see miminum for elemwise min
if axis=None, then axis is assumed to be ndim(x)-1 if axis=None, then axis is assumed to be ndim(x)-1
...@@ -920,6 +922,14 @@ Mathematical ...@@ -920,6 +922,14 @@ Mathematical
Returns a variable representing the exponential of a, ie e^a. Returns a variable representing the exponential of a, ie e^a.
.. function:: maximum(a,b)
Returns a variable representing the maximum element by element of a and b
.. function:: minimum(a,b)
Returns a variable representing the minimum element by element of a and b
.. function:: neg(a) .. function:: neg(a)
Returns a variable representing the negation of `a` (also ``-a``). Returns a variable representing the negation of `a` (also ``-a``).
......
...@@ -392,6 +392,7 @@ class T_picklefunction(unittest.TestCase): ...@@ -392,6 +392,7 @@ class T_picklefunction(unittest.TestCase):
old_default_mode = config.mode old_default_mode = config.mode
old_default_opt = config.optimizer old_default_opt = config.optimizer
old_default_link = config.linker old_default_link = config.linker
try:
try: try:
str_f = cPickle.dumps(f) str_f = cPickle.dumps(f)
config.mode = 'Mode' config.mode = 'Mode'
......
...@@ -46,7 +46,7 @@ def raise_with_op(op, exc_info = None): ...@@ -46,7 +46,7 @@ def raise_with_op(op, exc_info = None):
except AttributeError: except AttributeError:
trace = () trace = ()
exc_value.__thunk_trace__ = trace exc_value.__thunk_trace__ = trace
exc_value.args = exc_value.args + (op, ) exc_value.args = exc_value.args + (op, ) + ('Sequence id of Apply node='+str(op.env.toposort().index(op)),)
raise exc_type, exc_value, exc_trace raise exc_type, exc_value, exc_trace
......
...@@ -7,7 +7,9 @@ def run(TF): ...@@ -7,7 +7,9 @@ def run(TF):
if TF and RUN_TESTS: if TF and RUN_TESTS:
print 'running test', f.__name__ print 'running test', f.__name__
f() f()
return f if RUN_TESTS else None if RUN_TESTS:
return f
else: return None
return deco return deco
......
...@@ -726,6 +726,42 @@ invert = Invert() ...@@ -726,6 +726,42 @@ invert = Invert()
# Arithmetic # Arithmetic
############## ##############
class Maximum(BinaryScalarOp):
commutative = True
associative = True
def impl(self, *inputs):
return max(inputs)
def c_code(self, node, name, (x,y), (z, ), sub):
return "%(z)s = ((%(y)s)>(%(x)s)? (%(y)s):(%(x)s));" %locals()
def grad(self, (x, y), (gz, )):
gx, gy = None, None
if x.type in grad_types:
gx = eq(maximum(x,y), x)*gz
if y.type in grad_types:
gy = eq(maximum(x,y), y)*gz
return (gx,gy)
maximum = Maximum(upcast_out, name = 'maximum')
class Minimum(BinaryScalarOp):
commutative = True
associative = True
def impl(self, *inputs):
return min(inputs)
def c_code(self, node, name, (x,y), (z, ), sub):
return "%(z)s = ((%(y)s)<(%(x)s)? (%(y)s):(%(x)s));" %locals()
def grad(self, (x, y), (gz, )):
gx, gy = None, None
if x.type in grad_types:
gx = eq(minimum(x,y), x)*gz
if y.type in grad_types:
gy = eq(minimum(x,y), y)*gz
return (gx,gy)
minimum = Minimum(upcast_out, name = 'minimum')
class Add(ScalarOp): class Add(ScalarOp):
identity = 0 identity = 0
commutative = True commutative = True
......
...@@ -1703,7 +1703,7 @@ def zeros_like(model): ...@@ -1703,7 +1703,7 @@ def zeros_like(model):
return fill(model, constant(0.0, dtype=model.type.dtype)) return fill(model, constant(0.0, dtype=model.type.dtype))
class Eye(gof.Op): class Eye(gof.Op):
def __init__(self, dtype='float64'): def __init__(self, dtype=config.floatX):
self.dtype = dtype self.dtype = dtype
def make_node(self,n,m,k): def make_node(self,n,m,k):
n = as_tensor_variable(n) n = as_tensor_variable(n)
...@@ -1724,7 +1724,7 @@ class Eye(gof.Op): ...@@ -1724,7 +1724,7 @@ class Eye(gof.Op):
return hash(self.dtype) ^ hash(type(self)) return hash(self.dtype) ^ hash(type(self))
def eye(n, m=None, k = 0, dtype = 'float64'): def eye(n, m=None, k = 0, dtype = config.floatX):
if m == None: if m == None:
m = n m = n
localop = Eye(dtype) localop = Eye(dtype)
...@@ -2029,6 +2029,17 @@ setdefault = default # legacy ...@@ -2029,6 +2029,17 @@ setdefault = default # legacy
########################## ##########################
# Arithmetics # Arithmetics
########################## ##########################
@_scal_elemwise
def maximum(x,y):
"""elemwise maximum. See max for the maximum in one tensor
"""
# see decorator for function body
@_scal_elemwise
def minimum(x,y):
"""elemwise minimum. See min for the minimum in one tensor
"""
# see decorator for function body
def div_proxy(x, y): def div_proxy(x, y):
"""Proxy for either true_div or int_div, depending on types of x, y. """Proxy for either true_div or int_div, depending on types of x, y.
...@@ -3172,9 +3183,10 @@ class ARange(Op): ...@@ -3172,9 +3183,10 @@ class ARange(Op):
if is_constant_value(start, 0): if is_constant_value(start, 0):
return [(cast(stop, 'int64'),)] return [(cast(stop, 'int64'),)]
else: else:
return [(theano.tensor.max([cast(stop-start, 'int64'),0]),)] return [(maximum(cast(stop-start, 'int64'),0),)]
else: else:
return [(theano.tensor.max([cast(ceil(cast((stop-start),'float64')/step),'int64'),0]),)] return [(maximum(cast(ceil(cast((stop-start),'float64')
/step),'int64'),0),)]
def perform(self, node, (start, stop, step), (out,)): def perform(self, node, (start, stop, step), (out,)):
start = start.item() start = start.item()
......
...@@ -168,6 +168,14 @@ fill_inplace = second_inplace ...@@ -168,6 +168,14 @@ fill_inplace = second_inplace
pprint.assign(fill_inplace, printing.FunctionPrinter('fill=')) pprint.assign(fill_inplace, printing.FunctionPrinter('fill='))
@_scal_inplace
def maximum_inplace(a, b):
"""elementwise addition (inplace on `a`)"""
@_scal_inplace
def minimum_inplace(a, b):
"""elementwise addition (inplace on `a`)"""
@_scal_inplace @_scal_inplace
def add_inplace(a, b): def add_inplace(a, b):
"""elementwise addition (inplace on `a`)""" """elementwise addition (inplace on `a`)"""
......
...@@ -43,8 +43,11 @@ class T_sigmoid_opts(unittest.TestCase): ...@@ -43,8 +43,11 @@ class T_sigmoid_opts(unittest.TestCase):
# tests inv_1_plus_exp with neg # tests inv_1_plus_exp with neg
f = theano.function([x], T.fill(x,-1.0) / (1+T.exp(-x)), mode=m) f = theano.function([x], T.fill(x,-1.0) / (1+T.exp(-x)), mode=m)
#theano.printing.debugprint(f) #theano.printing.debugprint(f)
assert [node.op for node in f.maker.env.toposort()] == [sigmoid, assert len(f.maker.env.toposort())==1
T.inplace.neg_inplace] assert str(f.maker.env.toposort()[0].op)=='Elemwise{Composite{scalar_sigmoid,neg}}'
#without fusion
#assert [node.op for node in f.maker.env.toposort()] == [sigmoid,
# T.inplace.neg_inplace]
# tests double inv_1_plus_exp with neg # tests double inv_1_plus_exp with neg
# (-1)(exp(x)) / (1+exp(x))(1+exp(-x)) # (-1)(exp(x)) / (1+exp(x))(1+exp(-x))
...@@ -52,8 +55,12 @@ class T_sigmoid_opts(unittest.TestCase): ...@@ -52,8 +55,12 @@ class T_sigmoid_opts(unittest.TestCase):
# = - (sigm(x) * sigm(x)) # = - (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) f = theano.function([x], (T.fill(x,-1.0)*T.exp(x)) / ((1+T.exp(x))*(1+T.exp(-x))), mode=m)
theano.printing.debugprint(f) theano.printing.debugprint(f)
assert [node.op for node in f.maker.env.toposort()] == [sigmoid, assert len(f.maker.env.toposort())==2
T.mul, T.inplace.neg_inplace] assert f.maker.env.toposort()[0].op == sigmoid
assert str(f.maker.env.toposort()[1].op)=='Elemwise{Composite{mul,neg}}'
#without fusion
#assert [node.op for node in f.maker.env.toposort()] == [sigmoid,
# T.mul, T.inplace.neg_inplace]
def test_1msigmoid(self): def test_1msigmoid(self):
if not register_local_1msigmoid: if not register_local_1msigmoid:
......
import traceback
import numpy import numpy
import theano.tensor.basic import theano.tensor.basic
from basic import TensorType, _tensor_py_operators from basic import TensorType, _tensor_py_operators
......
...@@ -9,6 +9,7 @@ import numpy ...@@ -9,6 +9,7 @@ import numpy
import theano import theano
import theano.tensor as T import theano.tensor as T
from theano.gof.python25 import any
def gen_data(): def gen_data():
...@@ -301,7 +302,7 @@ def test_mlp(): ...@@ -301,7 +302,7 @@ def test_mlp():
y:train_set_y[index*batch_size:(index+1)*batch_size]}, y:train_set_y[index*batch_size:(index+1)*batch_size]},
mode=mode) mode=mode)
for i in train_model.maker.env.toposort(): print i for i in train_model.maker.env.toposort(): print i
theano.printing.pydotprint(train_model) #theano.printing.pydotprint(train_model)
assert any( [isinstance(i.op,T.nnet.CrossentropySoftmax1HotWithBiasDx) for i in train_model.maker.env.toposort()]) assert any( [isinstance(i.op,T.nnet.CrossentropySoftmax1HotWithBiasDx) for i in train_model.maker.env.toposort()])
train_model =theano.function( inputs = [index], train_model =theano.function( inputs = [index],
......
...@@ -250,6 +250,36 @@ SubInplaceTester = makeBroadcastTester(op = inplace.sub_inplace, ...@@ -250,6 +250,36 @@ SubInplaceTester = makeBroadcastTester(op = inplace.sub_inplace,
grad = _grad_broadcast_binary_normal, grad = _grad_broadcast_binary_normal,
inplace = True) inplace = True)
MaximumTester = makeBroadcastTester(op = maximum,
expected = numpy.maximum,
good = _good_broadcast_binary_normal,
bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal,
grad = _grad_broadcast_binary_normal)
MaximumInplaceTester = makeBroadcastTester(op = inplace.maximum_inplace,
expected = numpy.maximum,
good = _good_broadcast_binary_normal,
bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal,
grad = _grad_broadcast_binary_normal,
inplace = True)
MinimumTester = makeBroadcastTester(op = minimum,
expected = numpy.minimum,
good = _good_broadcast_binary_normal,
bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal,
grad = _grad_broadcast_binary_normal)
MinimumInplaceTester = makeBroadcastTester(op = inplace.minimum_inplace,
expected = numpy.minimum,
good = _good_broadcast_binary_normal,
bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal,
grad = _grad_broadcast_binary_normal,
inplace = True)
MulTester = makeBroadcastTester(op = mul, MulTester = makeBroadcastTester(op = mul,
expected = lambda *inputs: reduce(lambda x, y: x * y, inputs), expected = lambda *inputs: reduce(lambda x, y: x * y, inputs),
good = dict(three_inputs_same_shapes = (rand(2, 3), rand(2, 3), rand(2, 3)), good = dict(three_inputs_same_shapes = (rand(2, 3), rand(2, 3), rand(2, 3)),
...@@ -654,6 +684,7 @@ class T_max_and_argmax(unittest.TestCase): ...@@ -654,6 +684,7 @@ class T_max_and_argmax(unittest.TestCase):
_logger = logging.getLogger('theano.gof.opt') _logger = logging.getLogger('theano.gof.opt')
oldlevel = _logger.getEffectiveLevel() oldlevel = _logger.getEffectiveLevel()
_logger.setLevel(logging.CRITICAL) _logger.setLevel(logging.CRITICAL)
try:
try: try:
eval_outputs(max_and_argmax(n,3)) eval_outputs(max_and_argmax(n,3))
assert False assert False
...@@ -665,6 +696,7 @@ class T_max_and_argmax(unittest.TestCase): ...@@ -665,6 +696,7 @@ class T_max_and_argmax(unittest.TestCase):
n = as_tensor_variable(numpy.random.rand(2,3)) n = as_tensor_variable(numpy.random.rand(2,3))
old_stderr = sys.stderr old_stderr = sys.stderr
sys.stderr = StringIO.StringIO() sys.stderr = StringIO.StringIO()
try:
try: try:
eval_outputs(max_and_argmax(n,-3)) eval_outputs(max_and_argmax(n,-3))
assert False assert False
...@@ -725,6 +757,7 @@ class T_subtensor(unittest.TestCase): ...@@ -725,6 +757,7 @@ class T_subtensor(unittest.TestCase):
_logger = logging.getLogger('theano.gof.opt') _logger = logging.getLogger('theano.gof.opt')
oldlevel = _logger.getEffectiveLevel() oldlevel = _logger.getEffectiveLevel()
_logger.setLevel(logging.CRITICAL) _logger.setLevel(logging.CRITICAL)
try:
try: try:
tval = eval_outputs([t]) tval = eval_outputs([t])
assert 0 assert 0
...@@ -802,6 +835,7 @@ class T_subtensor(unittest.TestCase): ...@@ -802,6 +835,7 @@ class T_subtensor(unittest.TestCase):
_logger = logging.getLogger('theano.gof.opt') _logger = logging.getLogger('theano.gof.opt')
oldlevel = _logger.getEffectiveLevel() oldlevel = _logger.getEffectiveLevel()
_logger.setLevel(logging.CRITICAL) _logger.setLevel(logging.CRITICAL)
try:
try: try:
tval = eval_outputs([t]) tval = eval_outputs([t])
assert 0 assert 0
...@@ -815,6 +849,7 @@ class T_subtensor(unittest.TestCase): ...@@ -815,6 +849,7 @@ class T_subtensor(unittest.TestCase):
self.failUnless(isinstance(t.owner.op, Subtensor)) self.failUnless(isinstance(t.owner.op, Subtensor))
old_stderr = sys.stderr old_stderr = sys.stderr
sys.stderr = StringIO.StringIO() sys.stderr = StringIO.StringIO()
try:
try: try:
tval = eval_outputs([t]) tval = eval_outputs([t])
except Exception, e: except Exception, e:
...@@ -1496,6 +1531,7 @@ class t_dot(unittest.TestCase): ...@@ -1496,6 +1531,7 @@ class t_dot(unittest.TestCase):
_logger = logging.getLogger('theano.gof.opt') _logger = logging.getLogger('theano.gof.opt')
oldlevel = _logger.getEffectiveLevel() oldlevel = _logger.getEffectiveLevel()
_logger.setLevel(logging.CRITICAL) _logger.setLevel(logging.CRITICAL)
try:
try: try:
tz = eval_outputs([z]) tz = eval_outputs([z])
assert False # should have raised exception assert False # should have raised exception
...@@ -2038,9 +2074,14 @@ class TestARange(unittest.TestCase): ...@@ -2038,9 +2074,14 @@ class TestARange(unittest.TestCase):
def test_infer_shape(self): def test_infer_shape(self):
start, stop, step = iscalars('start', 'stop', 'step') start, stop, step = iscalars('start', 'stop', 'step')
out = arange(start, stop, step) out = arange(start, stop, step)
f = function([start, stop, step], out.shape, mode=compile.mode.get_default_mode().excluding('fusion')) mode = theano.config.mode
assert len(f.maker.env.toposort())==12 if mode == 'FAST_COMPILE':
#ungly graph... [DimShuffle{x}(step), DimShuffle{x}(start), DimShuffle{x}(stop), Elemwise{Sub{output_types_preference=transfer_type{0}}}[(0, 0)](DimShuffle{x}.0, DimShuffle{x}.0), Elemwise{Cast{float64}}(Elemwise{Sub{output_types_preference=transfer_type{0}}}[(0, 0)].0), Elemwise{TrueDiv{output_types_preference=transfer_type{0}}}[(0, 0)](Elemwise{Cast{float64}}.0, DimShuffle{x}.0), Rebroadcast{0}(Elemwise{TrueDiv{output_types_preference=transfer_type{0}}}[(0, 0)].0), Elemwise{Ceil{output_types_preference=transfer_type{0}}}[(0, 0)](Rebroadcast{0}.0), Elemwise{Cast{int64}}(Elemwise{Ceil{output_types_preference=transfer_type{0}}}[(0, 0)].0), <theano.tensor.basic.Join object at 0x1fb1d10>(0, Elemwise{Cast{int64}}.0, [0]), MaxAndArgmax(<theano.tensor.basic.Join object at 0x1fb1d10>.0, [0]), MakeVector(max)] mode = 'FAST_RUN'
mode = compile.mode.get_mode(mode).excluding('fusion')
f = function([start, stop, step], out.shape, mode=mode)
assert len(f.maker.env.toposort())==7
#7 [Elemwise{sub,no_inplace}(stop, start), Elemwise{Cast{float64}}(Elemwise{sub,no_inplace}.0), Elemwise{TrueDiv{output_types_preference=transfer_type{0}}}[(0, 0)](Elemwise{Cast{float64}}.0, step), Elemwise{Ceil{output_types_preference=transfer_type{0}}}[(0, 0)](Elemwise{TrueDiv{output_types_preference=transfer_type{0}}}[(0, 0)].0), Elemwise{Cast{int64}}(Elemwise{Ceil{output_types_preference=transfer_type{0}}}[(0, 0)].0), Elemwise{Maximum{output_types_preference=transfer_type{0}}}[(0, 0)](Elemwise{Cast{int64}}.0, 0), MakeVector(Elemwise{Maximum{output_types_preference=transfer_type{0}}}[(0, 0)].0)]
assert out.dtype == start.type.dtype assert out.dtype == start.type.dtype
assert numpy.all(f(0,5,1) == len(numpy.arange(0,5,1))) assert numpy.all(f(0,5,1) == len(numpy.arange(0,5,1)))
assert numpy.all(f(2,11,4) == len(numpy.arange(2,11,4))) assert numpy.all(f(2,11,4) == len(numpy.arange(2,11,4)))
...@@ -2050,10 +2091,9 @@ class TestARange(unittest.TestCase): ...@@ -2050,10 +2091,9 @@ class TestARange(unittest.TestCase):
assert numpy.all(f(0,0,1) == len(numpy.arange(0,0,1))) assert numpy.all(f(0,0,1) == len(numpy.arange(0,0,1)))
out = arange(start, stop, 1) out = arange(start, stop, 1)
f = function([start, stop], out.shape, mode=compile.mode.get_default_mode().excluding('fusion')) f = function([start, stop], out.shape, mode=mode)
assert len(f.maker.env.toposort())==8 assert len(f.maker.env.toposort())==4
#ungly graph... [DimShuffle{x}(start), DimShuffle{x}(stop), Elemwise{Sub{output_types_preference=transfer_type{0}}}[(0, 0)](DimShuffle{x}.0, DimShuffle{x}.0), Rebroadcast{0}(Elemwise{Sub{output_types_preference=transfer_type{0}}}[(0, 0)].0), Elemwise{Cast{int64}}(Rebroadcast{0}.0), <theano.tensor.basic.Join object at 0x1fb1d10>(0, Elemwise{Cast{int64}}.0, [0]), MaxAndArgmax(<theano.tensor.basic.Join object at 0x1fb1d10>.0, [0]), MakeVector(max)] #4 [Elemwise{sub,no_inplace}(stop, start), Elemwise{Cast{int64}}(Elemwise{sub,no_inplace}.0), Elemwise{Maximum{output_types_preference=transfer_type{0}}}[(0, 0)](Elemwise{Cast{int64}}.0, 0), MakeVector(Elemwise{Maximum{output_types_preference=transfer_type{0}}}[(0, 0)].0)]
assert out.dtype == start.type.dtype assert out.dtype == start.type.dtype
assert numpy.all(f(0,5) == len(numpy.arange(0,5))) assert numpy.all(f(0,5) == len(numpy.arange(0,5)))
assert numpy.all(f(2,11) == len(numpy.arange(2,11))) assert numpy.all(f(2,11) == len(numpy.arange(2,11)))
...@@ -2063,7 +2103,7 @@ class TestARange(unittest.TestCase): ...@@ -2063,7 +2103,7 @@ class TestARange(unittest.TestCase):
assert numpy.all(f(0,0) == len(numpy.arange(0,0))) assert numpy.all(f(0,0) == len(numpy.arange(0,0)))
out = arange(0, stop, 1) out = arange(0, stop, 1)
f = function([stop], out.shape, mode=compile.mode.get_default_mode().excluding('fusion')) f = function([stop], out.shape, mode=mode)
assert len(f.maker.env.toposort())==2 assert len(f.maker.env.toposort())==2
#[Elemwise{Cast{int64}}(stop), MakeVector(Elemwise{Cast{int64}}.0)] #[Elemwise{Cast{int64}}(stop), MakeVector(Elemwise{Cast{int64}}.0)]
...@@ -2447,7 +2487,7 @@ def test_autocast(): ...@@ -2447,7 +2487,7 @@ def test_autocast():
ac = autocast_float_as('float32', 'float64') ac = autocast_float_as('float32', 'float64')
ac.__enter__() ac.__enter__()
assert (dvector()+ 1.1).dtype == 'float64' assert (dvector()+ 1.1).dtype == 'float64'
assert (fvector()+ 1.1).dtype == 'float64' assert (fvector()+ 1.1).dtype == theano.config.floatX
assert (fvector()+ 1.0).dtype == 'float32' assert (fvector()+ 1.0).dtype == 'float32'
try: #ghetto 2.4 version of with try: #ghetto 2.4 version of with
ac2 = autocast_float_as('float64') ac2 = autocast_float_as('float64')
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论