提交 85db9b9d authored 作者: Frédéric Bastien's avatar Frédéric Bastien

Merge pull request #1608 from lamblin/fix_rng_empty_shape

Fix rng empty shape
...@@ -10,6 +10,7 @@ import warnings ...@@ -10,6 +10,7 @@ import warnings
import numpy import numpy
from theano import Op, Apply, shared, config, Variable from theano import Op, Apply, shared, config, Variable
from theano import tensor
from theano.tensor import (raw_random, TensorType, as_tensor_variable, from theano.tensor import (raw_random, TensorType, as_tensor_variable,
get_vector_length, cast, opt, scal) get_vector_length, cast, opt, scal)
from theano.tensor import sqrt, log, sin, cos, join, prod from theano.tensor import sqrt, log, sin, cos, join, prod
...@@ -890,7 +891,8 @@ class MRG_RandomStreams(object): ...@@ -890,7 +891,8 @@ class MRG_RandomStreams(object):
constant = False constant = False
if isinstance(size, tuple) and all([isinstance(i, (numpy.integer, int)) for i in size]): if isinstance(size, tuple) and all([isinstance(i, (numpy.integer, int)) for i in size]):
constant = True constant = True
n_samples = numpy.prod(size) # Force dtype because it defaults to float when size is empty
n_samples = numpy.prod(size, dtype='int64')
if n_samples % 2 == 1: if n_samples % 2 == 1:
n_samples += 1 n_samples += 1
...@@ -928,8 +930,10 @@ class MRG_RandomStreams(object): ...@@ -928,8 +930,10 @@ class MRG_RandomStreams(object):
else: else:
final_samples = normal_samples[:prod(size)] final_samples = normal_samples[:prod(size)]
if size: if not size:
final_samples = final_samples.reshape(size) # Force the dtype to be int64, otherwise reshape complains
size = tensor.constant(size, dtype='int64')
final_samples = final_samples.reshape(size)
final_samples = avg + std * final_samples final_samples = avg + std * final_samples
......
...@@ -303,11 +303,11 @@ def test_consistency_GPU_parallel(): ...@@ -303,11 +303,11 @@ def test_consistency_GPU_parallel():
def basictest(f, steps, sample_size, prefix="", allow_01=False, inputs=None, def basictest(f, steps, sample_size, prefix="", allow_01=False, inputs=None,
target_avg=0.5, target_std=None, mean_rtol=0.01): target_avg=0.5, target_std=None, mean_rtol=0.01, std_tol=0.01):
if inputs is None: if inputs is None:
inputs = [] inputs = []
dt = 0.0 dt = 0.0
avg_std = 0.0 avg_var = 0.0
for i in xrange(steps): for i in xrange(steps):
t0 = time.time() t0 = time.time()
...@@ -317,16 +317,14 @@ def basictest(f, steps, sample_size, prefix="", allow_01=False, inputs=None, ...@@ -317,16 +317,14 @@ def basictest(f, steps, sample_size, prefix="", allow_01=False, inputs=None,
ival = numpy.asarray(ival) ival = numpy.asarray(ival)
if i == 0: if i == 0:
mean = numpy.array(ival, copy=True) mean = numpy.array(ival, copy=True)
#avg_std = numpy.std(ival) avg_var = numpy.mean((ival - target_avg) ** 2)
avg_std = numpy.sqrt(numpy.mean((ival - target_avg) ** 2))
min_ = ival.min() min_ = ival.min()
max_ = ival.max() max_ = ival.max()
else: else:
alpha = 1.0 / (1 + i) alpha = 1.0 / (1 + i)
mean = alpha * ival + (1 - alpha) * mean mean = alpha * ival + (1 - alpha) * mean
#avg_std = alpha * numpy.std(ival) + (1-alpha)*avg_std avg_var = (alpha * numpy.mean((ival - target_avg) ** 2)
avg_std = alpha * numpy.sqrt(numpy.mean((ival - target_avg) ** 2 + (1 - alpha) * avg_var)
)) + (1 - alpha) * avg_std
min_ = min(min_, ival.min()) min_ = min(min_, ival.min())
max_ = max(max_, ival.max()) max_ = max(max_, ival.max())
if not allow_01: if not allow_01:
...@@ -336,17 +334,21 @@ def basictest(f, steps, sample_size, prefix="", allow_01=False, inputs=None, ...@@ -336,17 +334,21 @@ def basictest(f, steps, sample_size, prefix="", allow_01=False, inputs=None,
if hasattr(target_avg, 'shape'): # looks if target_avg is an array if hasattr(target_avg, 'shape'): # looks if target_avg is an array
diff = numpy.mean(abs(mean - target_avg)) diff = numpy.mean(abs(mean - target_avg))
#print prefix, 'mean diff with mean', diff #print prefix, 'mean diff with mean', diff
assert diff < mean_rtol, 'bad mean? %f %f' % (mean, target_avg) assert numpy.all(diff < mean_rtol * (1 + abs(target_avg))), (
'bad mean? %s %s' % (mean, target_avg))
else: # if target_avg is a scalar, then we can do the mean of else: # if target_avg is a scalar, then we can do the mean of
# `mean` to get something more precise # `mean` to get something more precise
mean = numpy.mean(mean) mean = numpy.mean(mean)
#print prefix, 'mean', mean #print prefix, 'mean', mean
assert abs(mean - target_avg) < mean_rtol, 'bad mean? %f %f' % ( assert abs(mean - target_avg) < mean_rtol * (1 + abs(target_avg)), (
numpy.mean(mean), target_avg) 'bad mean? %f %f' % (mean, target_avg))
#print prefix, 'std', avg_std
std = numpy.sqrt(avg_var)
#print prefix, 'var', avg_var
#print prefix, 'std', std
if target_std is not None: if target_std is not None:
assert abs(avg_std - target_std) < .01, 'bad std? %f %f' % (avg_std, assert abs(std - target_std) < std_tol * (1 + abs(target_std)), (
target_std) 'bad std? %f %f' % (std, target_std))
#print prefix, 'time', dt #print prefix, 'time', dt
#print prefix, 'elements', steps * sample_size[0] * sample_size[1] #print prefix, 'elements', steps * sample_size[0] * sample_size[1]
#print prefix, 'samples/sec', steps * sample_size[0] * sample_size[1] / dt #print prefix, 'samples/sec', steps * sample_size[0] * sample_size[1] / dt
...@@ -368,11 +370,14 @@ def test_uniform(): ...@@ -368,11 +370,14 @@ def test_uniform():
steps = int(1e3) steps = int(1e3)
x = tensor.matrix() x = tensor.matrix()
for size, var_input, input in [ for size, const_size, var_input, input in [
(sample_size, [], []), (sample_size, sample_size, [], []),
(x.shape, [x], [numpy.zeros(sample_size, dtype=config.floatX)]), (x.shape, sample_size, [x],
((x.shape[0], sample_size[1]), [x], [numpy.zeros(sample_size, dtype=config.floatX)]),
[numpy.zeros(sample_size, dtype=config.floatX)]) ((x.shape[0], sample_size[1]), sample_size, [x],
[numpy.zeros(sample_size, dtype=config.floatX)]),
# test empty size (scalar)
((), (), [], []),
]: ]:
#### TEST CPU IMPLEMENTATION #### #### TEST CPU IMPLEMENTATION ####
...@@ -396,7 +401,13 @@ def test_uniform(): ...@@ -396,7 +401,13 @@ def test_uniform():
#print 'CPU: random?[:10], random?[-10:]' #print 'CPU: random?[:10], random?[-10:]'
#print cpu_out[0, 0:10] #print cpu_out[0, 0:10]
#print cpu_out[-1, -10:] #print cpu_out[-1, -10:]
basictest(f, steps, sample_size, prefix='mrg cpu', inputs=input)
# Increase the number of steps if sizes implies only a few samples
if numpy.prod(const_size) < 10:
steps_ = steps * 100
else:
steps_ = steps
basictest(f, steps_, const_size, prefix='mrg cpu', inputs=input)
if mode != 'FAST_COMPILE' and cuda_available: if mode != 'FAST_COMPILE' and cuda_available:
#print '' #print ''
...@@ -418,7 +429,7 @@ def test_uniform(): ...@@ -418,7 +429,7 @@ def test_uniform():
#print 'GPU: random?[:10], random?[-10:]' #print 'GPU: random?[:10], random?[-10:]'
#print gpu_out[0, 0:10] #print gpu_out[0, 0:10]
#print gpu_out[-1, -10:] #print gpu_out[-1, -10:]
basictest(f, steps, sample_size, prefix='mrg gpu', inputs=input) basictest(f, steps_, const_size, prefix='mrg gpu', inputs=input)
numpy.testing.assert_array_almost_equal(cpu_out, gpu_out, numpy.testing.assert_array_almost_equal(cpu_out, gpu_out,
decimal=6) decimal=6)
...@@ -430,7 +441,7 @@ def test_uniform(): ...@@ -430,7 +441,7 @@ def test_uniform():
uu = RR.uniform(size=size) uu = RR.uniform(size=size)
ff = theano.function(var_input, uu, mode=mode) ff = theano.function(var_input, uu, mode=mode)
# It's not our problem if numpy generates 0 or 1 # It's not our problem if numpy generates 0 or 1
basictest(ff, steps, sample_size, prefix='numpy', basictest(ff, steps_, const_size, prefix='numpy',
allow_01=True, inputs=input) allow_01=True, inputs=input)
...@@ -456,11 +467,14 @@ def test_binomial(): ...@@ -456,11 +467,14 @@ def test_binomial():
x = tensor.matrix() x = tensor.matrix()
v = tensor.vector() v = tensor.vector()
for mean in [0.1, 0.5]: for mean in [0.1, 0.5]:
for size, var_input, input in [ for size, const_size, var_input, input in [
(sample_size, [], []), (sample_size, sample_size, [], []),
(x.shape, [x], [numpy.zeros(sample_size, dtype=config.floatX)]), (x.shape, sample_size, [x],
((x.shape[0], sample_size[1]), [x], [numpy.zeros(sample_size, dtype=config.floatX)]),
[numpy.zeros(sample_size, dtype=config.floatX)]) ((x.shape[0], sample_size[1]), sample_size, [x],
[numpy.zeros(sample_size, dtype=config.floatX)]),
# test empty size (scalar)
((), (), [], []),
]: ]:
#print '' #print ''
...@@ -474,7 +488,13 @@ def test_binomial(): ...@@ -474,7 +488,13 @@ def test_binomial():
out = f(*input) out = f(*input)
#print 'random?[:10]\n', out[0, 0:10] #print 'random?[:10]\n', out[0, 0:10]
#print 'random?[-1,-10:]\n', out[-1, -10:] #print 'random?[-1,-10:]\n', out[-1, -10:]
basictest(f, steps, sample_size, prefix='mrg cpu',
# Increase the number of steps if sizes implies only a few samples
if numpy.prod(const_size) < 10:
steps_ = steps * 100
else:
steps_ = steps
basictest(f, steps_, const_size, prefix='mrg cpu',
inputs=input, allow_01=True, inputs=input, allow_01=True,
target_avg=mean, mean_rtol=rtol) target_avg=mean, mean_rtol=rtol)
...@@ -494,7 +514,7 @@ def test_binomial(): ...@@ -494,7 +514,7 @@ def test_binomial():
gpu_out = numpy.asarray(f(*input)) gpu_out = numpy.asarray(f(*input))
#print 'random?[:10]\n', gpu_out[0, 0:10] #print 'random?[:10]\n', gpu_out[0, 0:10]
#print 'random?[-1,-10:]\n', gpu_out[-1, -10:] #print 'random?[-1,-10:]\n', gpu_out[-1, -10:]
basictest(f, steps, sample_size, prefix='mrg gpu', basictest(f, steps_, const_size, prefix='mrg gpu',
inputs=input, allow_01=True, inputs=input, allow_01=True,
target_avg=mean, mean_rtol=rtol) target_avg=mean, mean_rtol=rtol)
numpy.testing.assert_array_almost_equal(out, gpu_out, numpy.testing.assert_array_almost_equal(out, gpu_out,
...@@ -508,7 +528,7 @@ def test_binomial(): ...@@ -508,7 +528,7 @@ def test_binomial():
uu = RR.binomial(size=size, p=mean) uu = RR.binomial(size=size, p=mean)
ff = theano.function(var_input, uu, mode=mode) ff = theano.function(var_input, uu, mode=mode)
# It's not our problem if numpy generates 0 or 1 # It's not our problem if numpy generates 0 or 1
basictest(ff, steps, sample_size, prefix='numpy', allow_01=True, basictest(ff, steps_, const_size, prefix='numpy', allow_01=True,
inputs=input, target_avg=mean, mean_rtol=rtol) inputs=input, target_avg=mean, mean_rtol=rtol)
...@@ -525,24 +545,32 @@ def test_normal0(): ...@@ -525,24 +545,32 @@ def test_normal0():
default_rtol = .01 default_rtol = .01
sample_size_odd = (sample_size[0], sample_size[1] - 1) sample_size_odd = (sample_size[0], sample_size[1] - 1)
x = tensor.matrix() x = tensor.matrix()
for size, const_size, var_input, input, avg, rtol in [
(sample_size, sample_size, [], [], -5., default_rtol), for size, const_size, var_input, input, avg, rtol, std_tol in [
(sample_size, sample_size, [], [], -5., default_rtol, default_rtol),
(x.shape, sample_size, [x], (x.shape, sample_size, [x],
[numpy.zeros(sample_size, dtype=config.floatX)], [numpy.zeros(sample_size, dtype=config.floatX)],
-5., default_rtol), -5., default_rtol, default_rtol),
((x.shape[0], sample_size[1]), sample_size, [x], ((x.shape[0], sample_size[1]), sample_size, [x],
[numpy.zeros(sample_size, dtype=config.floatX)], [numpy.zeros(sample_size, dtype=config.floatX)],
-5., default_rtol), -5., default_rtol, default_rtol),
#test odd value #test odd value
(sample_size_odd, sample_size_odd, [], [], -5., default_rtol), (sample_size_odd, sample_size_odd, [], [], -5.,
default_rtol, default_rtol),
#test odd value #test odd value
(x.shape, sample_size_odd, [x], (x.shape, sample_size_odd, [x],
[numpy.zeros(sample_size_odd, dtype=config.floatX)], [numpy.zeros(sample_size_odd, dtype=config.floatX)],
-5., default_rtol), -5., default_rtol, default_rtol),
(sample_size, sample_size, [], [], (sample_size, sample_size, [], [],
numpy.arange(numpy.prod(sample_size), numpy.arange(numpy.prod(sample_size),
dtype='float32').reshape(sample_size), dtype='float32').reshape(sample_size),
10. * std / numpy.sqrt(steps)), 10. * std / numpy.sqrt(steps), default_rtol),
# test empty size (scalar)
((), (), [], [], -5., default_rtol, 0.02),
# test with few samples at the same time
((1,), (1,), [], [], -5., default_rtol, 0.02),
((2,), (2,), [], [], -5., default_rtol, 0.02),
((3,), (3,), [], [], -5., default_rtol, 0.02),
]: ]:
#print '' #print ''
#print 'ON CPU:' #print 'ON CPU:'
...@@ -555,8 +583,15 @@ def test_normal0(): ...@@ -555,8 +583,15 @@ def test_normal0():
#theano.printing.debugprint(f) #theano.printing.debugprint(f)
out = f(*input) out = f(*input)
#print 'random?[:10]\n', out[0, 0:10] #print 'random?[:10]\n', out[0, 0:10]
basictest(f, steps, const_size, target_avg=avg, target_std=std,
prefix='mrg ', allow_01=True, inputs=input, mean_rtol=rtol) # Increase the number of steps if size implies only a few samples
if numpy.prod(const_size) < 10:
steps_ = steps * 50
else:
steps_ = steps
basictest(f, steps_, const_size, target_avg=avg, target_std=std,
prefix='mrg ', allow_01=True, inputs=input,
mean_rtol=rtol, std_tol=std_tol)
sys.stdout.flush() sys.stdout.flush()
...@@ -578,7 +613,7 @@ def test_normal0(): ...@@ -578,7 +613,7 @@ def test_normal0():
#print 'random?[:10]\n', gpu_out[0, 0:10] #print 'random?[:10]\n', gpu_out[0, 0:10]
#print '----' #print '----'
sys.stdout.flush() sys.stdout.flush()
basictest(f, steps, const_size, target_avg=avg, target_std=std, basictest(f, steps_, const_size, target_avg=avg, target_std=std,
prefix='gpu mrg ', allow_01=True, inputs=input, prefix='gpu mrg ', allow_01=True, inputs=input,
mean_rtol=rtol) mean_rtol=rtol)
# Need to allow some rounding error as their is float # Need to allow some rounding error as their is float
...@@ -592,7 +627,7 @@ def test_normal0(): ...@@ -592,7 +627,7 @@ def test_normal0():
nn = RR.normal(size=size, avg=avg, std=std) nn = RR.normal(size=size, avg=avg, std=std)
ff = theano.function(var_input, nn) ff = theano.function(var_input, nn)
basictest(ff, steps, const_size, target_avg=avg, target_std=std, basictest(ff, steps_, const_size, target_avg=avg, target_std=std,
prefix='numpy ', allow_01=True, inputs=input, mean_rtol=rtol) prefix='numpy ', allow_01=True, inputs=input, mean_rtol=rtol)
......
...@@ -351,7 +351,10 @@ def _infer_ndim_bcast(ndim, shape, *args): ...@@ -351,7 +351,10 @@ def _infer_ndim_bcast(ndim, shape, *args):
ValueError('negative shape', s) ValueError('negative shape', s)
# post-condition: shape may still contain both symbolic and # post-condition: shape may still contain both symbolic and
# non-symbolic things # non-symbolic things
v_shape = tensor.stack(*pre_v_shape) if len(pre_v_shape) == 0:
v_shape = tensor.constant([], dtype='int32')
else:
v_shape = tensor.stack(*pre_v_shape)
elif shape is None: elif shape is None:
# The number of drawn samples will be determined automatically, # The number of drawn samples will be determined automatically,
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论