提交 540af3cc authored 作者: Olivier Delalleau's avatar Olivier Delalleau

Merged

...@@ -589,6 +589,35 @@ class GPU_mrg_uniform(mrg_uniform_base): ...@@ -589,6 +589,35 @@ class GPU_mrg_uniform(mrg_uniform_base):
def c_code_cache_version(self): def c_code_cache_version(self):
return (4,) return (4,)
def guess_n_streams(size, warn=True):
"""
Return a guess at a good number of streams.
:param warn: If True, warn when a guess cannot be made (in which case
we return 30 * 256).
"""
# TODO: a smart way of choosing the number of streams, see #612.
# Note that this code was moved out of `MRG_RandomStreams` so that it can
# be easily accessed from tests, where we want to disable the warning.
if (isinstance(size, (tuple, list)) and
all([isinstance(i, int) for i in size])):
# We can make a guess.
r = 1
for s in size:
r *= s
if r > 6:
r = r/6 # chosen as fastest for rbm_benchmark
return r
else:
if warn:
assert False
print >> sys.stderr, (
"MRG_RandomStreams Can't determine #streams from "
"size (%s), guessing 30*256") % str(size)
return 30 * 256
class MRG_RandomStreams(object): class MRG_RandomStreams(object):
"""Module component with similar interface to numpy.random (numpy.random.RandomState)""" """Module component with similar interface to numpy.random (numpy.random.RandomState)"""
...@@ -654,18 +683,7 @@ class MRG_RandomStreams(object): ...@@ -654,18 +683,7 @@ class MRG_RandomStreams(object):
return rval return rval
def n_streams(self, size): def n_streams(self, size):
# TODO: a smart way of choosing the number of streams, see #612. return guess_n_streams(size, warn=True)
if isinstance(size, (tuple, list)) and all([isinstance(i,int) for i in size]):
r = 1
for s in size:
r *= s
if r > 6:
r = r/6 # chosen as fastest for rbm_benchmark
return r
print >> sys.stderr, ("MRG_RandomStreams Can't determine #streams from "
"size (%s), guessing 30*256")%str(size)
return 30*256
def pretty_return(self, node_rstate, new_rstate, sample): def pretty_return(self, node_rstate, new_rstate, sample):
sample.rstate = node_rstate sample.rstate = node_rstate
...@@ -674,7 +692,8 @@ class MRG_RandomStreams(object): ...@@ -674,7 +692,8 @@ class MRG_RandomStreams(object):
node_rstate.default_update = new_rstate node_rstate.default_update = new_rstate
return sample return sample
def uniform(self, size=None, low=0.0, high=1.0, ndim=None, dtype=config.floatX, nstreams=None): def uniform(self, size, low=0.0, high=1.0, ndim=None, dtype='floatX',
nstreams=None):
""" """
Sample a tensor of given size whose element from a uniform Sample a tensor of given size whose element from a uniform
distribution between low and high. distribution between low and high.
...@@ -683,10 +702,14 @@ class MRG_RandomStreams(object): ...@@ -683,10 +702,14 @@ class MRG_RandomStreams(object):
ndim may be a plain integer to supplement the missing ndim may be a plain integer to supplement the missing
information. information.
:param: size: Can be a list of integer or Theano variable :param size: Can be a list of integer or Theano variable
(ex: the shape of other Theano Variable) (ex: the shape of other Theano Variable)
TODO: can size be None?
:param dtype: The output data type.
""" """
if dtype == 'floatX':
dtype = config.floatX
if isinstance(size, tuple): if isinstance(size, tuple):
msg = "size must be a tuple of int or a Theano variable" msg = "size must be a tuple of int or a Theano variable"
assert all([isinstance(i,int) or isinstance(i,Variable) assert all([isinstance(i,int) or isinstance(i,Variable)
...@@ -728,16 +751,19 @@ class MRG_RandomStreams(object): ...@@ -728,16 +751,19 @@ class MRG_RandomStreams(object):
raise NotImplementedError( 'Increase the size to match the broadcasting pattern of `low` and `high` arguments') raise NotImplementedError( 'Increase the size to match the broadcasting pattern of `low` and `high` arguments')
return r return r
def binomial(self, size=None, n=1, p=0.5, ndim=None, dtype='int64'): def binomial(self, size=None, n=1, p=0.5, ndim=None, dtype='int64',
nstreams=None):
if n == 1: if n == 1:
if dtype=='float32' and self.use_cuda: if dtype == 'float32' and self.use_cuda:
return cast(self.uniform(size=size, dtype=dtype) < p, dtype) x = self.uniform(size=size, dtype=dtype, nstreams=nstreams)
else: else:
return cast(self.uniform(size=size) < p, dtype) x = self.uniform(size=size, nstreams=nstreams)
return cast(x < p, dtype)
else: else:
raise NotImplementedError("MRG_RandomStreams.binomial with n > 1") raise NotImplementedError("MRG_RandomStreams.binomial with n > 1")
def multinomial(self, size=None, n=1, pvals=None, ndim=None, dtype='int64'): def multinomial(self, size=None, n=1, pvals=None, ndim=None, dtype='int64',
nstreams=None):
""" """
Sample `n` (currently `n` needs to be 1) times from a multinomial Sample `n` (currently `n` needs to be 1) times from a multinomial
distribution defined by probabilities pvals. distribution defined by probabilities pvals.
...@@ -758,22 +784,31 @@ class MRG_RandomStreams(object): ...@@ -758,22 +784,31 @@ class MRG_RandomStreams(object):
ndim, size, pvals[:,0]) ndim, size, pvals[:,0])
assert ndim==1 assert ndim==1
bcast = bcast+(pvals.type.broadcastable[-1],) bcast = bcast+(pvals.type.broadcastable[-1],)
unis = self.uniform(size=size, ndim=1) unis = self.uniform(size=size, ndim=1, nstreams=nstreams)
op = multinomial.MultinomialFromUniform(dtype) op = multinomial.MultinomialFromUniform(dtype)
return op(pvals, unis) return op(pvals, unis)
else: else:
raise NotImplementedError(("MRG_RandomStreams.multinomial only" raise NotImplementedError(("MRG_RandomStreams.multinomial only"
" implemented with n == 1 and pvals.ndim = 2")) " implemented with n == 1 and pvals.ndim = 2"))
def normal(self, size=None, avg=0.0, std=1.0, ndim=None, dtype=config.floatX): def normal(self, size=None, avg=0.0, std=1.0, ndim=None,
dtype='floatX', nstreams=None):
""" """
:param: size: Can be a list of integer or Theano variable(ex: the shape of other Theano Variable) :param size: Can be a list of integers or Theano variables (ex: the
shape of another Theano Variable)
:param dtype: The output data type.
:param nstreams: Number of streams.
""" """
# We need an even number of ]0,1[ samples. Then we split them # We need an even number of ]0,1[ samples. Then we split them
# in two halves. First half becomes our U1's for Box-Muller, # in two halves. First half becomes our U1's for Box-Muller,
# second half our U2's. See Wikipedia page: # second half our U2's. See Wikipedia page:
# http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform # http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
if dtype == 'floatX':
dtype = config.floatX
evened = False evened = False
constant = False constant = False
if isinstance(size, tuple) and all([isinstance(i,int) for i in size]): if isinstance(size, tuple) and all([isinstance(i,int) for i in size]):
...@@ -786,7 +821,8 @@ class MRG_RandomStreams(object): ...@@ -786,7 +821,8 @@ class MRG_RandomStreams(object):
else: else:
#if even, don't change, if odd, +1 #if even, don't change, if odd, +1
n_samples = prod(size)+(prod(size)%2) n_samples = prod(size)+(prod(size)%2)
flattened = self.uniform(size=(n_samples,), dtype=dtype) flattened = self.uniform(size=(n_samples,), dtype=dtype,
nstreams=nstreams)
if constant: if constant:
U1 = flattened[:n_samples // 2] U1 = flattened[:n_samples // 2]
......
...@@ -350,7 +350,9 @@ def test_uniform(): ...@@ -350,7 +350,9 @@ def test_uniform():
print 'ON CPU with size=(%s):'%str(size) print 'ON CPU with size=(%s):'%str(size)
x = tensor.matrix() x = tensor.matrix()
R = MRG_RandomStreams(234, use_cuda=False) R = MRG_RandomStreams(234, use_cuda=False)
u = R.uniform(size=size) # Note: we specify `nstreams` to avoid a warning.
u = R.uniform(size=size,
nstreams=rng_mrg.guess_n_streams(size, warn=False))
f = theano.function(var_input, u, mode=mode) f = theano.function(var_input, u, mode=mode)
assert any([isinstance(node.op,theano.sandbox.rng_mrg.mrg_uniform) assert any([isinstance(node.op,theano.sandbox.rng_mrg.mrg_uniform)
for node in f.maker.env.toposort()]) for node in f.maker.env.toposort()])
...@@ -366,7 +368,8 @@ def test_uniform(): ...@@ -366,7 +368,8 @@ def test_uniform():
print '' print ''
print 'ON GPU with size=(%s):'%str(size) print 'ON GPU with size=(%s):'%str(size)
R = MRG_RandomStreams(234, use_cuda=True) R = MRG_RandomStreams(234, use_cuda=True)
u = R.uniform(size=size, dtype='float32') u = R.uniform(size=size, dtype='float32',
nstreams=rng_mrg.guess_n_streams(size, warn=False))
assert u.dtype == 'float32' #well, it's really that this test w GPU doesn't make sense otw assert u.dtype == 'float32' #well, it's really that this test w GPU doesn't make sense otw
f = theano.function(var_input, theano.Out( f = theano.function(var_input, theano.Out(
theano.sandbox.cuda.basic_ops.gpu_from_host(u), theano.sandbox.cuda.basic_ops.gpu_from_host(u),
...@@ -421,7 +424,9 @@ def test_binomial(): ...@@ -421,7 +424,9 @@ def test_binomial():
print '' print ''
print 'ON CPU with size=(%s) and mean(%d):'%(str(size),mean) print 'ON CPU with size=(%s) and mean(%d):'%(str(size),mean)
R = MRG_RandomStreams(234, use_cuda=False) R = MRG_RandomStreams(234, use_cuda=False)
u = R.binomial(size=size, p=mean) # Note: we specify `nstreams` to avoid a warning.
u = R.binomial(size=size, p=mean,
nstreams=rng_mrg.guess_n_streams(size, warn=False))
f = theano.function(var_input, u, mode=mode) f = theano.function(var_input, u, mode=mode)
theano.printing.debugprint(f) theano.printing.debugprint(f)
out = f(*input) out = f(*input)
...@@ -433,7 +438,9 @@ def test_binomial(): ...@@ -433,7 +438,9 @@ def test_binomial():
print '' print ''
print 'ON GPU with size=(%s) and mean(%d):'%(str(size),mean) print 'ON GPU with size=(%s) and mean(%d):'%(str(size),mean)
R = MRG_RandomStreams(234, use_cuda=True) R = MRG_RandomStreams(234, use_cuda=True)
u = R.binomial(size=size, p=mean, dtype='float32') u = R.binomial(size=size, p=mean, dtype='float32',
nstreams=rng_mrg.guess_n_streams(size,
warn=False))
assert u.dtype == 'float32' #well, it's really that this test w GPU doesn't make sense otw assert u.dtype == 'float32' #well, it's really that this test w GPU doesn't make sense otw
f = theano.function(var_input, theano.Out( f = theano.function(var_input, theano.Out(
theano.sandbox.cuda.basic_ops.gpu_from_host(u), theano.sandbox.cuda.basic_ops.gpu_from_host(u),
...@@ -478,7 +485,9 @@ def test_normal0(): ...@@ -478,7 +485,9 @@ def test_normal0():
print 'ON CPU:' print 'ON CPU:'
R = MRG_RandomStreams(234, use_cuda=False) R = MRG_RandomStreams(234, use_cuda=False)
n = R.normal(size=size, avg=avg, std=std) # Note: we specify `nstreams` to avoid a warning.
n = R.normal(size=size, avg=avg, std=std,
nstreams=rng_mrg.guess_n_streams(size, warn=False))
f = theano.function(var_input, n, mode=mode) f = theano.function(var_input, n, mode=mode)
theano.printing.debugprint(f) theano.printing.debugprint(f)
out = f(*input) out = f(*input)
...@@ -491,7 +500,8 @@ def test_normal0(): ...@@ -491,7 +500,8 @@ def test_normal0():
print '' print ''
print 'ON GPU:' print 'ON GPU:'
R = MRG_RandomStreams(234, use_cuda=True) R = MRG_RandomStreams(234, use_cuda=True)
n = R.normal(size=size, avg=avg, std=std, dtype='float32') n = R.normal(size=size, avg=avg, std=std, dtype='float32',
nstreams=rng_mrg.guess_n_streams(size, warn=False))
assert n.dtype == 'float32' #well, it's really that this test w GPU doesn't make sense otw assert n.dtype == 'float32' #well, it's really that this test w GPU doesn't make sense otw
f = theano.function(var_input, theano.Out( f = theano.function(var_input, theano.Out(
theano.sandbox.cuda.basic_ops.gpu_from_host(n), theano.sandbox.cuda.basic_ops.gpu_from_host(n),
...@@ -557,7 +567,8 @@ def test_multinomial(): ...@@ -557,7 +567,8 @@ def test_multinomial():
pvals = numpy.asarray(numpy.random.uniform(size=sample_size)) pvals = numpy.asarray(numpy.random.uniform(size=sample_size))
pvals = numpy.apply_along_axis(lambda row : row/numpy.sum(row), 1, pvals) pvals = numpy.apply_along_axis(lambda row : row/numpy.sum(row), 1, pvals)
R = MRG_RandomStreams(234, use_cuda=False) R = MRG_RandomStreams(234, use_cuda=False)
m = R.multinomial(pvals=pvals, dtype=config.floatX) # Note: we specify `nstreams` to avoid a warning.
m = R.multinomial(pvals=pvals, dtype=config.floatX, nstreams=30 * 256)
f = theano.function([], m, mode=mode_) f = theano.function([], m, mode=mode_)
theano.printing.debugprint(f) theano.printing.debugprint(f)
out = f() out = f()
......
...@@ -1034,11 +1034,11 @@ def div_proxy(x, y): ...@@ -1034,11 +1034,11 @@ def div_proxy(x, y):
# division"), we will change the semantics of "/" on integer types in # division"), we will change the semantics of "/" on integer types in
# Theano 0.4. Until then, it is forbidden to use "/" on integers. # Theano 0.4. Until then, it is forbidden to use "/" on integers.
raise IntegerDivisionError( raise IntegerDivisionError(
"Dividing two integers with '/' is forbidden until Theano v0.4" "Dividing two integers with '/' is currently forbidden "
" is released (where the result will be a floating point " "to avoid confusion between integer and floating point "
"number). In the meantime, please either use '//' for integer " "divisions. Please either use '//' for integer division, or "
"division, or cast one of the arguments to a floating point " "cast one of the arguments to a floating point type for float "
"type for float division.") "division.")
else: else:
return true_div(x, y) return true_div(x, y)
......
...@@ -2589,11 +2589,11 @@ def div_proxy(x, y): ...@@ -2589,11 +2589,11 @@ def div_proxy(x, y):
as_tensor_variable(y).dtype in discrete_dtypes): as_tensor_variable(y).dtype in discrete_dtypes):
# See the same in scalar/basic.py # See the same in scalar/basic.py
raise IntegerDivisionError( raise IntegerDivisionError(
"Dividing two integer arrays with '/' is forbidden until " "Dividing two integer arrays with '/' is currently forbidden "
"Theano v0.4 is released (where the result will be a floating " "to avoid confusion between integer and floating point "
"point number). In the meantime, please either use '//' for " "divisions. Please either use '//' for integer division, or "
"integer division, or cast one of the arguments to a floating " "cast one of the arguments to a floating point type for float "
"point type for float division.") "division.")
else: else:
return true_div(x, y) return true_div(x, y)
...@@ -3044,8 +3044,11 @@ def setsubtensor(x, y, idx_list, inplace=False): ...@@ -3044,8 +3044,11 @@ def setsubtensor(x, y, idx_list, inplace=False):
print >> sys.stderr, "tensor.setsubtensor is deprecated - please use set_subtensor" print >> sys.stderr, "tensor.setsubtensor is deprecated - please use set_subtensor"
the_op = IncSubtensor(idx_list, inplace, set_instead_of_inc=True) the_op = IncSubtensor(idx_list, inplace, set_instead_of_inc=True)
return the_op(x, y, *Subtensor.collapse(idx_list, lambda entry: isinstance(entry, Variable))) return the_op(x, y, *Subtensor.collapse(idx_list, lambda entry: isinstance(entry, Variable)))
def incsubtensor(x, y, idx_list, inplace=False): def incsubtensor(x, y, idx_list, inplace=False, show_warning=True):
print >> sys.stderr, "tensor.incsubtensor is deprecated - please use inc_subtensor" # Note that `show_warning` should only be set to False by tests, in order
# to make sure this old code is still working.
if show_warning:
print >> sys.stderr, "tensor.incsubtensor is deprecated - please use inc_subtensor"
the_op = IncSubtensor(idx_list, inplace, set_instead_of_inc=False) the_op = IncSubtensor(idx_list, inplace, set_instead_of_inc=False)
return the_op(x, y, *Subtensor.collapse(idx_list, lambda entry: isinstance(entry, Variable))) return the_op(x, y, *Subtensor.collapse(idx_list, lambda entry: isinstance(entry, Variable)))
......
...@@ -458,8 +458,9 @@ _grad_broadcast_div_mod_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)), ...@@ -458,8 +458,9 @@ _grad_broadcast_div_mod_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)),
div_grad_rtol=None div_grad_rtol=None
if config.floatX=='float32': if config.floatX=='float32':
#We raise the relative tolerence for the grad as their is error in float32 # We raise the relative tolerance for the grad as there can be errors in
#This is probably caused by our way of computing the gradient error. # float32.
# This is probably caused by our way of computing the gradient error.
div_grad_rtol=0.025 div_grad_rtol=0.025
DivTester = makeBroadcastTester(op = true_div, DivTester = makeBroadcastTester(op = true_div,
expected = lambda x, y: x / y, expected = lambda x, y: x / y,
......
...@@ -32,7 +32,8 @@ class Test_incsubtensor(unittest.TestCase): ...@@ -32,7 +32,8 @@ class Test_incsubtensor(unittest.TestCase):
if do_set: if do_set:
resut = T.setsubtensor(a, increment, [sl1, sl2]) resut = T.setsubtensor(a, increment, [sl1, sl2])
else: else:
resut = T.incsubtensor(a, increment, [sl1, sl2]) resut = T.incsubtensor(a, increment, [sl1, sl2],
show_warning=False)
f = theano.function([a, increment, sl2_end], resut) f = theano.function([a, increment, sl2_end], resut)
...@@ -59,7 +60,7 @@ class Test_incsubtensor(unittest.TestCase): ...@@ -59,7 +60,7 @@ class Test_incsubtensor(unittest.TestCase):
def inc_slice(*s): def inc_slice(*s):
def just_numeric_args(a,b): def just_numeric_args(a,b):
return T.incsubtensor(a, b, s) return T.incsubtensor(a, b, s, show_warning=False)
return just_numeric_args return just_numeric_args
# vector # vector
......
...@@ -2490,6 +2490,7 @@ class T_local_sum(unittest.TestCase): ...@@ -2490,6 +2490,7 @@ class T_local_sum(unittest.TestCase):
assert numpy.allclose(f(input),input.sum()) assert numpy.allclose(f(input),input.sum())
config.warn.sum_sum_bug = False
f = theano.function([a],a.sum(0).sum(0).sum(0),mode=self.mode) f = theano.function([a],a.sum(0).sum(0).sum(0),mode=self.mode)
assert len(f.maker.env.nodes)==1 assert len(f.maker.env.nodes)==1
assert numpy.allclose(f(input),input.sum()) assert numpy.allclose(f(input),input.sum())
...@@ -2499,6 +2500,7 @@ class T_local_sum(unittest.TestCase): ...@@ -2499,6 +2500,7 @@ class T_local_sum(unittest.TestCase):
input=numpy.arange(3*3*3, dtype=config.floatX).reshape(3,3,3) input=numpy.arange(3*3*3, dtype=config.floatX).reshape(3,3,3)
dims=[(0,0),(1,0),(2,0),(0,1),(1,1),(2,1)] dims=[(0,0),(1,0),(2,0),(0,1),(1,1),(2,1)]
config.warn.sum_sum_bug = False
for d,dd in dims: for d,dd in dims:
f = theano.function([a],a.sum(d).sum(dd),mode=self.mode) f = theano.function([a],a.sum(d).sum(dd),mode=self.mode)
assert numpy.allclose(f(input),input.sum(d).sum(dd)) assert numpy.allclose(f(input),input.sum(d).sum(dd))
...@@ -2544,6 +2546,7 @@ class T_local_sum(unittest.TestCase): ...@@ -2544,6 +2546,7 @@ class T_local_sum(unittest.TestCase):
assert len(f.maker.env.nodes)==nb_nodes[2] assert len(f.maker.env.nodes)==nb_nodes[2]
assert f.maker.env.toposort()[-1].op==T.alloc assert f.maker.env.toposort()[-1].op==T.alloc
config.warn.sum_sum_bug = False
for d, dd in [(0,0),(1,0),(2,0),(0,1),(1,1),(2,1)]: for d, dd in [(0,0),(1,0),(2,0),(0,1),(1,1),(2,1)]:
f = theano.function([a],t_like(a).sum(d).sum(dd),mode=mode) f = theano.function([a],t_like(a).sum(d).sum(dd),mode=mode)
print f.maker.env.toposort() print f.maker.env.toposort()
...@@ -2603,6 +2606,8 @@ class T_local_sum_dimshuffle(unittest.TestCase): ...@@ -2603,6 +2606,8 @@ class T_local_sum_dimshuffle(unittest.TestCase):
c_val = rng.randn(2,2,2).astype(config.floatX) c_val = rng.randn(2,2,2).astype(config.floatX)
d_val = numpy.asarray(rng.randn(), config.floatX) d_val = numpy.asarray(rng.randn(), config.floatX)
config.warn.sum_sum_bug = False
config.warn.sum_div_dimshuffle_bug = False
for i,s in enumerate(sums): for i,s in enumerate(sums):
print i print i
f = theano.function([a,b,c,d], s, mode=self.mode) f = theano.function([a,b,c,d], s, mode=self.mode)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论