From b40fe25eda89f1d01bdc153a1408c2a7ccacbddb Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Tue, 6 Aug 2019 18:12:09 -0700 Subject: [PATCH 1/9] symbol api for randn, fix shape issue for randn ndarray and symbol api --- python/mxnet/ndarray/random.py | 2 -- python/mxnet/symbol/random.py | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/python/mxnet/ndarray/random.py b/python/mxnet/ndarray/random.py index f19c1e03202f..ef43445645d1 100644 --- a/python/mxnet/ndarray/random.py +++ b/python/mxnet/ndarray/random.py @@ -220,8 +220,6 @@ def randn(*shape, **kwargs): dtype = kwargs.pop('dtype', _Null) ctx = kwargs.pop('ctx', None) out = kwargs.pop('out', None) - assert isinstance(loc, (int, float)) - assert isinstance(scale, (int, float)) return _random_helper(_internal._random_normal, _internal._sample_normal, [loc, scale], shape, dtype, ctx, out, kwargs) diff --git a/python/mxnet/symbol/random.py b/python/mxnet/symbol/random.py index 4bdfe7045625..461bdcbcf86a 100644 --- a/python/mxnet/symbol/random.py +++ b/python/mxnet/symbol/random.py @@ -113,6 +113,31 @@ def normal(loc=0, scale=1, shape=_Null, dtype=_Null, **kwargs): [loc, scale], shape, dtype, kwargs) +def randn(*shape, **kwargs): + """Draw random samples from a normal (Gaussian) distribution. + + Samples are distributed according to a normal distribution parametrized + by *loc* (mean) and *scale* (standard deviation). + + + Parameters + ---------- + loc : float or NDArray + Mean (centre) of the distribution. + scale : float or NDArray + Standard deviation (spread or width) of the distribution. + shape : int or tuple of ints + The number of samples to draw. If shape is, e.g., `(m, n)` and `loc` and + `scale` are scalars, output shape will be `(m, n)`. If `loc` and `scale` + are NDArrays with shape, e.g., `(x, y)`, then output will have shape + `(x, y, m, n)`, where `m*n` samples are drawn for each `[loc, scale)` pair. + dtype : {'float16', 'float32', 'float64'} + Data type of output samples. Default is 'float32' + """ + return _random_helper(_internal._random_normal, _internal._sample_normal, + [loc, scale], shape, dtype, ctx, out, kwargs) + + def poisson(lam=1, shape=_Null, dtype=_Null, **kwargs): """Draw random samples from a Poisson distribution. From 438735503dbefc65ca0c3363f9dfe450b310cb3b Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Tue, 6 Aug 2019 22:56:52 -0700 Subject: [PATCH 2/9] address comments; add unit test for symbol and check for NDArray --- python/mxnet/ndarray/random.py | 2 ++ tests/python/unittest/test_random.py | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/mxnet/ndarray/random.py b/python/mxnet/ndarray/random.py index ef43445645d1..b0683b439c2a 100644 --- a/python/mxnet/ndarray/random.py +++ b/python/mxnet/ndarray/random.py @@ -220,6 +220,8 @@ def randn(*shape, **kwargs): dtype = kwargs.pop('dtype', _Null) ctx = kwargs.pop('ctx', None) out = kwargs.pop('out', None) + assert isinstance(loc, (int, float, NDArray)) + assert isinstance(scale, (int, float, NDArray)) return _random_helper(_internal._random_normal, _internal._sample_normal, [loc, scale], shape, dtype, ctx, out, kwargs) diff --git a/tests/python/unittest/test_random.py b/tests/python/unittest/test_random.py index 8fdca619a5c8..280ecbdb8014 100644 --- a/tests/python/unittest/test_random.py +++ b/tests/python/unittest/test_random.py @@ -61,6 +61,7 @@ def check_with_device(device, dtype): }, { 'name': 'randn', + 'symbol': mx.sym.random.randn, 'ndop': mx.nd.random.randn, 'params': { 'loc': 10.0, 'scale': 0.5 }, 'checks': [ @@ -228,9 +229,6 @@ def check_with_device(device, dtype): params = symbdic['params'].copy() params.update(shape=shape, dtype=dtype, ctx=device) args = () - if name == 'randn': - params.pop('shape') # randn does not accept shape param - args = shape if name.endswith('_like'): params['data'] = mx.nd.ones(params.pop('shape'), dtype=params.pop('dtype'), From c34e9dc85fa6b8196f97ac674e9b1237e664c49b Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Wed, 7 Aug 2019 08:21:07 -0700 Subject: [PATCH 3/9] shape issue --- tests/python/unittest/test_random.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/python/unittest/test_random.py b/tests/python/unittest/test_random.py index 280ecbdb8014..f15458a2b978 100644 --- a/tests/python/unittest/test_random.py +++ b/tests/python/unittest/test_random.py @@ -229,6 +229,9 @@ def check_with_device(device, dtype): params = symbdic['params'].copy() params.update(shape=shape, dtype=dtype, ctx=device) args = () + if name == 'randn': + params.pop('shape') # randn does not accept shape param + args = shape if name.endswith('_like'): params['data'] = mx.nd.ones(params.pop('shape'), dtype=params.pop('dtype'), From 20e537630cf36a08a90fc7a4e86d3823c861b41d Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Wed, 7 Aug 2019 11:26:52 -0700 Subject: [PATCH 4/9] address comments - unit test, doc fix, etc --- python/mxnet/symbol/random.py | 15 ++++++++++----- tests/python/unittest/test_random.py | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/python/mxnet/symbol/random.py b/python/mxnet/symbol/random.py index 461bdcbcf86a..b2ff104ff0f3 100644 --- a/python/mxnet/symbol/random.py +++ b/python/mxnet/symbol/random.py @@ -22,7 +22,7 @@ from .symbol import Symbol -__all__ = ['uniform', 'normal', 'poisson', 'exponential', 'gamma', 'multinomial', +__all__ = ['uniform', 'normal', 'randn', 'poisson', 'exponential', 'gamma', 'multinomial', 'negative_binomial', 'generalized_negative_binomial', 'shuffle', 'randint'] @@ -122,20 +122,25 @@ def randn(*shape, **kwargs): Parameters ---------- - loc : float or NDArray + loc : float or Symbol, optional Mean (centre) of the distribution. - scale : float or NDArray + scale : float or Symbol, optional Standard deviation (spread or width) of the distribution. shape : int or tuple of ints The number of samples to draw. If shape is, e.g., `(m, n)` and `loc` and `scale` are scalars, output shape will be `(m, n)`. If `loc` and `scale` are NDArrays with shape, e.g., `(x, y)`, then output will have shape `(x, y, m, n)`, where `m*n` samples are drawn for each `[loc, scale)` pair. - dtype : {'float16', 'float32', 'float64'} + dtype : {'float16', 'float32', 'float64'}, optional Data type of output samples. Default is 'float32' """ + loc = kwargs.pop('loc', 0) + scale = kwargs.pop('scale', 1) + dtype = kwargs.pop('dtype', _Null) + assert isinstance(loc, (int, float, Symbol)) + assert isinstance(scale, (int, float, Symbol)) return _random_helper(_internal._random_normal, _internal._sample_normal, - [loc, scale], shape, dtype, ctx, out, kwargs) + [loc, scale], shape, dtype, kwargs) def poisson(lam=1, shape=_Null, dtype=_Null, **kwargs): diff --git a/tests/python/unittest/test_random.py b/tests/python/unittest/test_random.py index f15458a2b978..f5811f9ac6c0 100644 --- a/tests/python/unittest/test_random.py +++ b/tests/python/unittest/test_random.py @@ -64,6 +64,7 @@ def check_with_device(device, dtype): 'symbol': mx.sym.random.randn, 'ndop': mx.nd.random.randn, 'params': { 'loc': 10.0, 'scale': 0.5 }, + 'inputs': [ ('loc',[ [ 0.0, 2.5 ], [ -9.75, -7.0 ] ]) , ('scale',[ [ 1.0, 3.7 ], [ 4.2, 1.5 ] ]) ], 'checks': [ ('mean', lambda x, params: np.mean(x.astype(np.float64) - params['loc']), tol), ('std', lambda x, params: np.std(x.astype(np.float64)) - params['scale'], tol) From 4ca832028902f8efa1ce8cf0900d659274770662 Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Mon, 19 Aug 2019 11:19:01 -0700 Subject: [PATCH 5/9] remove prints, test randn for symbol and multidistribution --- mxnet_py3/include/python3.6m | 1 + tests/python/unittest/test_random.py | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 120000 mxnet_py3/include/python3.6m diff --git a/mxnet_py3/include/python3.6m b/mxnet_py3/include/python3.6m new file mode 120000 index 000000000000..61924afe925d --- /dev/null +++ b/mxnet_py3/include/python3.6m @@ -0,0 +1 @@ +/Users/bapac/anaconda3/include/python3.6m \ No newline at end of file diff --git a/tests/python/unittest/test_random.py b/tests/python/unittest/test_random.py index f5811f9ac6c0..2561adf96865 100644 --- a/tests/python/unittest/test_random.py +++ b/tests/python/unittest/test_random.py @@ -252,6 +252,9 @@ def check_with_device(device, dtype): params = {'shape': shape, 'dtype': dtype, 'ctx': device} params.update({k : mx.nd.array(v, ctx=device, dtype=dtype) for k, v in symbdic['inputs']}) + if name == 'randn': + params.pop('shape') # randn does not accept shape param + args = shape mx.random.seed(128) ret1 = ndop(*args, **params).asnumpy() mx.random.seed(128) @@ -265,14 +268,12 @@ def check_with_device(device, dtype): err = np.abs(check_func(ret2[i,j], stats)) assert err < tol, "%f vs %f: symbolic test: %s check for `%s` did not pass" % (err, tol, check_name, name) - if 'symbol' not in symbdic: continue # randn does not have symbol - # check symbolic symbol = symbdic['symbol'] X = mx.sym.Variable("X") params = symbdic['params'].copy() params.update(shape=shape, dtype=dtype) - if name.endswith('_like'): + if name.endswith('_like') or name == 'randn': params['data'] = mx.sym.ones(params.pop('shape')) Y = symbol(**params) + X x = mx.nd.zeros(shape, dtype=dtype, ctx=device) @@ -300,7 +301,12 @@ def check_with_device(device, dtype): single_param = len(symbdic['inputs']) == 1 v1 = mx.sym.Variable('v1') v2 = mx.sym.Variable('v2') - Y = symbol(v1,**params) if single_param else symbol(v1,v2,**params) + if name == 'randn': + params.pop('shape') # randn does not accept shape param + args=shape + Y = symbol(v1, **params) if single_param else symbol(*args, loc=v1, scale=v2,**params) + else: + Y = symbol(v1,**params) if single_param else symbol(v1,v2,**params) bindings = { 'v1' : mx.nd.array(symbdic['inputs'][0][1]) } if not single_param : bindings.update({ 'v2' : mx.nd.array(symbdic['inputs'][1][1]) }) @@ -317,9 +323,10 @@ def check_with_device(device, dtype): for check_name, check_func, tol in symbdic['checks']: assert np.abs(check_func(samples, params)) < tol, "symbolic test: %s check for `%s` did not pass" % (check_name, name) + if 'pdfsymbol' not in symbdic: continue # randn not tested for pdf + # check pdfs with only a subset of the generated samples un1 = np.resize(un1, (un1.shape[0], un1.shape[1], pdfshape[0], pdfshape[1])) - print(name) symbol = symbdic['pdfsymbol'] pdffunc = symbdic['pdffunc'] v0 = mx.sym.Variable('v0') @@ -357,7 +364,6 @@ def check_with_device(device, dtype): check_symbolic_forward(test_pdf, [un1, p1, p2], [res], atol=forw_atol, rtol=forw_rtol, dtype=dtype) if dtype == np.float64: grad_nodes = ['v1', 'v2'] if symbdic['discrete'] else ['v0', 'v1', 'v2'] - print(backw_rtol) check_numeric_gradient(test_pdf, [un1, p1, p2], grad_nodes=grad_nodes, atol=backw_atol, rtol=backw_rtol, dtype=dtype) @with_seed(1000) From ef82a90f8ba685fd555510bd5f5ca0bb86774e5e Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Mon, 19 Aug 2019 12:49:54 -0700 Subject: [PATCH 6/9] Trigger notification bcoz data.mxnet.io failed From 6aad046c8899207e4f0b942380ae21cec0b2d491 Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Tue, 20 Aug 2019 10:41:05 -0700 Subject: [PATCH 7/9] removed stray file --- mxnet_py3/include/python3.6m | 1 - 1 file changed, 1 deletion(-) delete mode 120000 mxnet_py3/include/python3.6m diff --git a/mxnet_py3/include/python3.6m b/mxnet_py3/include/python3.6m deleted file mode 120000 index 61924afe925d..000000000000 --- a/mxnet_py3/include/python3.6m +++ /dev/null @@ -1 +0,0 @@ -/Users/bapac/anaconda3/include/python3.6m \ No newline at end of file From 4f8a56c335d56a8d78c84ffd2a32531334949e0f Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Wed, 21 Aug 2019 08:41:30 -0700 Subject: [PATCH 8/9] Trigger notification bcoz R/cpu failed From 1e3b3830fe3b3ad54d6113dd440846c0617b4bd5 Mon Sep 17 00:00:00 2001 From: ChaiBapchya Date: Wed, 21 Aug 2019 15:25:40 -0700 Subject: [PATCH 9/9] add to symbol doc --- docs/api/python/symbol/symbol.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/api/python/symbol/symbol.md b/docs/api/python/symbol/symbol.md index fea746bb02f4..264f69093709 100644 --- a/docs/api/python/symbol/symbol.md +++ b/docs/api/python/symbol/symbol.md @@ -612,6 +612,7 @@ Composite multiple symbols into a new one by an operator. random.normal random.poisson random.randint + random.randn random.shuffle random.uniform mxnet.random.seed