You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by mu...@apache.org on 2017/09/22 22:31:19 UTC
[incubator-mxnet] branch master updated: add math fluent functions
(#7992)
This is an automated email from the ASF dual-hosted git repository.
muli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
The following commit(s) were added to refs/heads/master by this push:
new 22bea88 add math fluent functions (#7992)
22bea88 is described below
commit 22bea8878cfb3e9042c8d48a00cacd35abbfebce
Author: Sheng Zha <sz...@users.noreply.github.com>
AuthorDate: Fri Sep 22 15:31:16 2017 -0700
add math fluent functions (#7992)
---
python/mxnet/ndarray/ndarray.py | 184 ++++++++++++++++++++++++++++++++++
python/mxnet/symbol/symbol.py | 184 ++++++++++++++++++++++++++++++++++
python/mxnet/test_utils.py | 8 +-
tests/python/unittest/test_ndarray.py | 17 +++-
tests/python/unittest/test_symbol.py | 24 +++--
5 files changed, 401 insertions(+), 16 deletions(-)
diff --git a/python/mxnet/ndarray/ndarray.py b/python/mxnet/ndarray/ndarray.py
index 5eb68fa..6077d0e 100644
--- a/python/mxnet/ndarray/ndarray.py
+++ b/python/mxnet/ndarray/ndarray.py
@@ -1025,6 +1025,190 @@ fixed-size items.
"""
return op.trunc(self, *args, **kwargs)
+ def sin(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sin`.
+
+ The arguments are the same as for :py:func:`sin`, with
+ this array as data.
+ """
+ return op.sin(self, *args, **kwargs)
+
+ def cos(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`cos`.
+
+ The arguments are the same as for :py:func:`cos`, with
+ this array as data.
+ """
+ return op.cos(self, *args, **kwargs)
+
+ def tan(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`tan`.
+
+ The arguments are the same as for :py:func:`tan`, with
+ this array as data.
+ """
+ return op.tan(self, *args, **kwargs)
+
+ def arcsin(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arcsin`.
+
+ The arguments are the same as for :py:func:`arcsin`, with
+ this array as data.
+ """
+ return op.arcsin(self, *args, **kwargs)
+
+ def arccos(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arccos`.
+
+ The arguments are the same as for :py:func:`arccos`, with
+ this array as data.
+ """
+ return op.arccos(self, *args, **kwargs)
+
+ def arctan(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arctan`.
+
+ The arguments are the same as for :py:func:`arctan`, with
+ this array as data.
+ """
+ return op.arctan(self, *args, **kwargs)
+
+ def degrees(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`degrees`.
+
+ The arguments are the same as for :py:func:`degrees`, with
+ this array as data.
+ """
+ return op.degrees(self, *args, **kwargs)
+
+ def radians(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`radians`.
+
+ The arguments are the same as for :py:func:`radians`, with
+ this array as data.
+ """
+ return op.radians(self, *args, **kwargs)
+
+ def sinh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sinh`.
+
+ The arguments are the same as for :py:func:`sinh`, with
+ this array as data.
+ """
+ return op.sinh(self, *args, **kwargs)
+
+ def cosh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`cosh`.
+
+ The arguments are the same as for :py:func:`cosh`, with
+ this array as data.
+ """
+ return op.cosh(self, *args, **kwargs)
+
+ def tanh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`tanh`.
+
+ The arguments are the same as for :py:func:`tanh`, with
+ this array as data.
+ """
+ return op.tanh(self, *args, **kwargs)
+
+ def arcsinh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arcsinh`.
+
+ The arguments are the same as for :py:func:`arcsinh`, with
+ this array as data.
+ """
+ return op.arcsinh(self, *args, **kwargs)
+
+ def arccosh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arccosh`.
+
+ The arguments are the same as for :py:func:`arccosh`, with
+ this array as data.
+ """
+ return op.arccosh(self, *args, **kwargs)
+
+ def arctanh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arctanh`.
+
+ The arguments are the same as for :py:func:`arctanh`, with
+ this array as data.
+ """
+ return op.arctanh(self, *args, **kwargs)
+
+ def exp(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`exp`.
+
+ The arguments are the same as for :py:func:`exp`, with
+ this array as data.
+ """
+ return op.exp(self, *args, **kwargs)
+
+ def expm1(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`expm1`.
+
+ The arguments are the same as for :py:func:`expm1`, with
+ this array as data.
+ """
+ return op.expm1(self, *args, **kwargs)
+
+ def log(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`log`.
+
+ The arguments are the same as for :py:func:`log`, with
+ this array as data.
+ """
+ return op.log(self, *args, **kwargs)
+
+ def log10(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`log10`.
+
+ The arguments are the same as for :py:func:`log10`, with
+ this array as data.
+ """
+ return op.log10(self, *args, **kwargs)
+
+ def log2(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`log2`.
+
+ The arguments are the same as for :py:func:`log2`, with
+ this array as data.
+ """
+ return op.log2(self, *args, **kwargs)
+
+ def log1p(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`log1p`.
+
+ The arguments are the same as for :py:func:`log1p`, with
+ this array as data.
+ """
+ return op.log1p(self, *args, **kwargs)
+
+ def sqrt(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sqrt`.
+
+ The arguments are the same as for :py:func:`sqrt`, with
+ this array as data.
+ """
+ return op.sqrt(self, *args, **kwargs)
+
+ def rsqrt(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`rsqrt`.
+
+ The arguments are the same as for :py:func:`rsqrt`, with
+ this array as data.
+ """
+ return op.rsqrt(self, *args, **kwargs)
+
+ def square(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`square`.
+
+ The arguments are the same as for :py:func:`square`, with
+ this array as data.
+ """
+ return op.square(self, *args, **kwargs)
+
# pylint: disable= undefined-variable
def broadcast_to(self, shape):
"""Broadcasts the input array to a new shape.
diff --git a/python/mxnet/symbol/symbol.py b/python/mxnet/symbol/symbol.py
index 2a7d5ba..394f8b6 100644
--- a/python/mxnet/symbol/symbol.py
+++ b/python/mxnet/symbol/symbol.py
@@ -2072,6 +2072,190 @@ class Symbol(SymbolBase):
"""
return op.trunc(self, *args, **kwargs)
+ def sin(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sin`.
+
+ The arguments are the same as for :py:func:`sin`, with
+ this array as data.
+ """
+ return op.sin(self, *args, **kwargs)
+
+ def cos(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`cos`.
+
+ The arguments are the same as for :py:func:`cos`, with
+ this array as data.
+ """
+ return op.cos(self, *args, **kwargs)
+
+ def tan(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`tan`.
+
+ The arguments are the same as for :py:func:`tan`, with
+ this array as data.
+ """
+ return op.tan(self, *args, **kwargs)
+
+ def arcsin(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arcsin`.
+
+ The arguments are the same as for :py:func:`arcsin`, with
+ this array as data.
+ """
+ return op.arcsin(self, *args, **kwargs)
+
+ def arccos(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arccos`.
+
+ The arguments are the same as for :py:func:`arccos`, with
+ this array as data.
+ """
+ return op.arccos(self, *args, **kwargs)
+
+ def arctan(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arctan`.
+
+ The arguments are the same as for :py:func:`arctan`, with
+ this array as data.
+ """
+ return op.arctan(self, *args, **kwargs)
+
+ def degrees(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`degrees`.
+
+ The arguments are the same as for :py:func:`degrees`, with
+ this array as data.
+ """
+ return op.degrees(self, *args, **kwargs)
+
+ def radians(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`radians`.
+
+ The arguments are the same as for :py:func:`radians`, with
+ this array as data.
+ """
+ return op.radians(self, *args, **kwargs)
+
+ def sinh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sinh`.
+
+ The arguments are the same as for :py:func:`sinh`, with
+ this array as data.
+ """
+ return op.sinh(self, *args, **kwargs)
+
+ def cosh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`cosh`.
+
+ The arguments are the same as for :py:func:`cosh`, with
+ this array as data.
+ """
+ return op.cosh(self, *args, **kwargs)
+
+ def tanh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`tanh`.
+
+ The arguments are the same as for :py:func:`tanh`, with
+ this array as data.
+ """
+ return op.tanh(self, *args, **kwargs)
+
+ def arcsinh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arcsinh`.
+
+ The arguments are the same as for :py:func:`arcsinh`, with
+ this array as data.
+ """
+ return op.arcsinh(self, *args, **kwargs)
+
+ def arccosh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arccosh`.
+
+ The arguments are the same as for :py:func:`arccosh`, with
+ this array as data.
+ """
+ return op.arccosh(self, *args, **kwargs)
+
+ def arctanh(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`arctanh`.
+
+ The arguments are the same as for :py:func:`arctanh`, with
+ this array as data.
+ """
+ return op.arctanh(self, *args, **kwargs)
+
+ def exp(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`exp`.
+
+ The arguments are the same as for :py:func:`exp`, with
+ this array as data.
+ """
+ return op.exp(self, *args, **kwargs)
+
+ def expm1(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`expm1`.
+
+ The arguments are the same as for :py:func:`expm1`, with
+ this array as data.
+ """
+ return op.expm1(self, *args, **kwargs)
+
+ def log(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`log`.
+
+ The arguments are the same as for :py:func:`log`, with
+ this array as data.
+ """
+ return op.log(self, *args, **kwargs)
+
+ def log10(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`log10`.
+
+ The arguments are the same as for :py:func:`log10`, with
+ this array as data.
+ """
+ return op.log10(self, *args, **kwargs)
+
+ def log2(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`log2`.
+
+ The arguments are the same as for :py:func:`log2`, with
+ this array as data.
+ """
+ return op.log2(self, *args, **kwargs)
+
+ def log1p(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`log1p`.
+
+ The arguments are the same as for :py:func:`log1p`, with
+ this array as data.
+ """
+ return op.log1p(self, *args, **kwargs)
+
+ def sqrt(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`sqrt`.
+
+ The arguments are the same as for :py:func:`sqrt`, with
+ this array as data.
+ """
+ return op.sqrt(self, *args, **kwargs)
+
+ def rsqrt(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`rsqrt`.
+
+ The arguments are the same as for :py:func:`rsqrt`, with
+ this array as data.
+ """
+ return op.rsqrt(self, *args, **kwargs)
+
+ def square(self, *args, **kwargs):
+ """Convenience fluent method for :py:func:`square`.
+
+ The arguments are the same as for :py:func:`square`, with
+ this array as data.
+ """
+ return op.square(self, *args, **kwargs)
+
def wait_to_read(self):
raise NotImplementedForSymbol(self.wait_to_read, None)
diff --git a/python/mxnet/test_utils.py b/python/mxnet/test_utils.py
index 1c73f88..075d61d 100644
--- a/python/mxnet/test_utils.py
+++ b/python/mxnet/test_utils.py
@@ -1171,7 +1171,7 @@ def check_speed(sym, location=None, ctx=None, N=20, grad_req=None, typ="whole",
def check_consistency(sym, ctx_list, scale=1.0, grad_req='write',
arg_params=None, aux_params=None, tol=None,
- raise_on_err=True, ground_truth=None):
+ raise_on_err=True, ground_truth=None, equal_nan=False):
"""Check symbol gives the same output for different running context
Parameters
@@ -1271,7 +1271,8 @@ def check_consistency(sym, ctx_list, scale=1.0, grad_req='write',
gtarr = gt[name].astype(dtypes[i]).asnumpy()
arr = arr.asnumpy()
try:
- assert_almost_equal(arr, gtarr, rtol=tol[dtypes[i]], atol=tol[dtypes[i]])
+ assert_almost_equal(arr, gtarr, rtol=tol[dtypes[i]], atol=tol[dtypes[i]],
+ equal_nan=equal_nan)
except AssertionError as e:
print('Predict Err: ctx %d vs ctx %d at %s'%(i, max_idx, name))
traceback.print_exc()
@@ -1297,7 +1298,8 @@ def check_consistency(sym, ctx_list, scale=1.0, grad_req='write',
gtarr = gt[name].astype(dtypes[i]).asnumpy()
arr = arr.asnumpy()
try:
- assert_almost_equal(arr, gtarr, rtol=tol[dtypes[i]], atol=tol[dtypes[i]])
+ assert_almost_equal(arr, gtarr, rtol=tol[dtypes[i]], atol=tol[dtypes[i]],
+ equal_nan=equal_nan)
except AssertionError as e:
print('Train Err: ctx %d vs ctx %d at %s'%(i, max_idx, name))
traceback.print_exc()
diff --git a/tests/python/unittest/test_ndarray.py b/tests/python/unittest/test_ndarray.py
index c0865c1..f6b8203 100644
--- a/tests/python/unittest/test_ndarray.py
+++ b/tests/python/unittest/test_ndarray.py
@@ -733,22 +733,29 @@ def test_ndarray_fluent():
'nanprod', 'mean', 'max', 'min', 'reshape', 'broadcast_to', 'split',
'broadcast_axes', 'pad', 'swapaxes', 'slice', 'slice_axis', 'take',
'one_hot', 'pick', 'sort', 'topk', 'argsort', 'argmax', 'argmin',
- 'clip', 'abs' 'sign'])
- def check_fluent_regular(func, kwargs, shape=(5, 17, 1)):
+ 'clip', 'abs', 'sign', 'sin', 'cos', 'tan', 'arcsin', 'arccos', 'arctan',
+ 'degrees', 'radians', 'sinh', 'cosh', 'tanh', 'arcsinh', 'arccosh', 'arctanh',
+ 'exp', 'expm1', 'log', 'log10', 'log2', 'log1p', 'sqrt', 'rsqrt', 'square'])
+ def check_fluent_regular(func, kwargs, shape=(5, 17, 1), equal_nan=False):
with mx.name.NameManager():
data = mx.nd.random_uniform(shape=shape, ctx=default_context())
regular = getattr(mx.ndarray, func)(data, **kwargs)
fluent = getattr(data, func)(**kwargs)
if isinstance(regular, list):
for r, f in zip(regular, fluent):
- assert almost_equal(r.asnumpy(), f.asnumpy())
+ assert almost_equal(r.asnumpy(), f.asnumpy(), equal_nan=equal_nan)
else:
- assert almost_equal(regular.asnumpy(), fluent.asnumpy())
+ assert almost_equal(regular.asnumpy(), fluent.asnumpy(), equal_nan=equal_nan)
for func in ['flatten', 'norm', 'round', 'rint', 'fix', 'floor', 'ceil', 'trunc', 'zeros_like',
- 'ones_like', 'abs', 'sign']:
+ 'ones_like', 'abs', 'sign', 'sin', 'cos', 'degrees', 'radians',
+ 'exp', 'expm1', 'square']:
check_fluent_regular(func, {})
+ for func in ['arccosh', 'arcsin', 'arccos', 'arctan', 'tan', 'sinh', 'cosh', 'tanh',
+ 'arcsinh', 'arctanh', 'log', 'log10', 'log2', 'log1p', 'sqrt', 'rsqrt']:
+ check_fluent_regular(func, {}, equal_nan=True)
+
for func in ['expand_dims', 'flip', 'sort', 'topk', 'argsort', 'argmax', 'argmin']:
check_fluent_regular(func, {'axis': 1})
diff --git a/tests/python/unittest/test_symbol.py b/tests/python/unittest/test_symbol.py
index 4a2cdb3..4c8e8e0 100644
--- a/tests/python/unittest/test_symbol.py
+++ b/tests/python/unittest/test_symbol.py
@@ -42,10 +42,8 @@ def test_symbol_compose():
net2 = mx.symbol.FullyConnected(name='fc3', num_hidden=10)
net2 = mx.symbol.Activation(data=net2, act_type='relu')
net2 = mx.symbol.FullyConnected(data=net2, name='fc4', num_hidden=20)
- #print(net2.debug_str())
composed = net2(fc3_data=net1, name='composed')
- #print(composed.debug_str())
multi_out = mx.symbol.Group([composed, net1])
assert len(multi_out.list_outputs()) == 2
@@ -167,20 +165,29 @@ def test_symbol_fluent():
'nanprod', 'mean', 'max', 'min', 'reshape', 'broadcast_to', 'split',
'broadcast_axes', 'pad', 'swapaxes', 'slice', 'slice_axis', 'take',
'one_hot', 'pick', 'sort', 'topk', 'argsort', 'argmax', 'argmin',
- 'clip', 'abs' 'sign'])
- def check_fluent_regular(func, kwargs, shape=(5, 17, 1)):
+ 'clip', 'abs', 'sign', 'sin', 'cos', 'tan', 'arcsin', 'arccos', 'arctan',
+ 'degrees', 'radians', 'sinh', 'cosh', 'tanh', 'arcsinh', 'arccosh', 'arctanh',
+ 'exp', 'expm1', 'log', 'log10', 'log2', 'log1p', 'sqrt', 'rsqrt',
+ 'square'])
+ def check_fluent_regular(func, kwargs, shape=(5, 17, 1), equal_nan=False):
with mx.name.NameManager():
data = mx.symbol.Variable('data')
regular = getattr(mx.symbol, func)(data, name=func+'0', **kwargs)
fluent = getattr(data, func)(**kwargs)
check_symbol_consistency(regular, fluent, {'ctx': mx.context.current_context(),
'data': shape},
- skip_grad=func not in has_grad)
+ skip_grad=func not in has_grad,
+ equal_nan=equal_nan)
for func in ['flatten', 'norm', 'round', 'rint', 'fix', 'floor', 'ceil', 'trunc', 'zeros_like',
- 'ones_like', 'abs', 'sign']:
+ 'ones_like', 'abs', 'sign', 'sin', 'cos', 'degrees', 'radians',
+ 'exp', 'expm1', 'square']:
check_fluent_regular(func, {})
+ for func in ['arccosh', 'arcsin', 'arccos', 'arctan', 'tan', 'sinh', 'cosh', 'tanh',
+ 'arcsinh', 'arctanh', 'log', 'log10', 'log2', 'log1p', 'sqrt', 'rsqrt']:
+ check_fluent_regular(func, {}, equal_nan=True)
+
for func in ['expand_dims', 'flip', 'sort', 'topk', 'argsort', 'argmax', 'argmin']:
check_fluent_regular(func, {'axis': 1})
@@ -201,13 +208,14 @@ def test_symbol_fluent():
check_fluent_regular('reshape', {'shape': (17, 1, 5)})
check_fluent_regular('broadcast_to', {'shape': (5, 17, 47)})
-def check_symbol_consistency(sym1, sym2, ctx, skip_grad=False):
+def check_symbol_consistency(sym1, sym2, ctx, skip_grad=False, equal_nan=False):
assert sym1.list_arguments() == sym2.list_arguments()
assert sym1.list_auxiliary_states() == sym2.list_auxiliary_states()
assert sym1.list_outputs() == sym2.list_outputs()
mx.test_utils.check_consistency([sym1, sym2], ctx_list=[ctx, ctx],
- grad_req='null' if skip_grad else 'write')
+ grad_req='null' if skip_grad else 'write',
+ equal_nan=equal_nan)
def test_load_000800():
with mx.AttrScope(ctx_group='stage1'):
--
To stop receiving notification emails like this one, please contact
['"commits@mxnet.apache.org" <co...@mxnet.apache.org>'].