Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

init.Constant does not work in symbol #12404

Closed
szha opened this issue Aug 30, 2018 · 1 comment · Fixed by #15150
Closed

init.Constant does not work in symbol #12404

szha opened this issue Aug 30, 2018 · 1 comment · Fixed by #15150

Comments

@szha
Copy link
Member

szha commented Aug 30, 2018

Note: Providing complete information in the most concise form is the best way to get help. This issue template serves as the checklist for essential information to most of the technical issues and bug reports. For non-technical issues and feature requests, feel free to present the information in what you believe is the best form.

For Q & A and discussion, please start a discussion thread at https://discuss.mxnet.io

Description

init.Constant fails when used in gluon parameter

Minimum reproducible example

Symbol

import mxnet as mx
import numpy as np
net = mx.sym.var('a', init=mx.init.Constant(np.ones((5, 5))))
---------------------------------------------------------------------------
<ipython-input-1-777255712a8b> in <module>()
      1 import mxnet as mx
      2 import numpy as np
----> 3 net = mx.sym.var('a', init=mx.init.Constant(np.ones((5, 5))))

mxnet/symbol/symbol.py in var(name, attr, shape, lr_mult, wd_mult, dtype, init, stype, **kwargs)
   2516     if init is not None:
   2517         if not isinstance(init, string_types):
-> 2518             init = init.dumps()
   2519         attr['__init__'] = init
   2520     if stype is not None:

mxnet/initializer.py in dumps(self)
    113         '["xavier", {"rnd_type": "uniform", "magnitude": 2.34, "factor_type": "in"}]'
    114         """
--> 115         return json.dumps([self.__class__.__name__.lower(), self._kwargs])
    116
    117     def __call__(self, desc, arr):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    229         cls is None and indent is None and separators is None and
    230         default is None and not sort_keys and not kw):
--> 231         return _default_encoder.encode(obj)
    232     if cls is None:
    233         cls = JSONEncoder

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in encode(self, o)
    197         # exceptions aren't as detailed.  The list call should be roughly
    198         # equivalent to the PySequence_Fast that ''.join() would do.
--> 199         chunks = self.iterencode(o, _one_shot=True)
    200         if not isinstance(chunks, (list, tuple)):
    201             chunks = list(chunks)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in iterencode(self, o, _one_shot)
    255                 self.key_separator, self.item_separator, self.sort_keys,
    256                 self.skipkeys, _one_shot)
--> 257         return _iterencode(o, 0)
    258
    259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in default(self, o)
    177
    178         """
--> 179         raise TypeError(f'Object of type {o.__class__.__name__} '
    180                         f'is not JSON serializable')
    181

TypeError: Object of type ndarray is not JSON serializable

Impact on Gluon

import mxnet as mx
from mxnet import gluon
net = gluon.nn.Dense(5)
import numpy as np
net = gluon.nn.Dense(5, weight_initializer=mx.init.Constant(np.ones((5, 5))))
net.initialize()
net.hybridize()
net(mx.nd.ones((5, 5)))

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-812f6ff55149> in <module>()
----> 1 net(mx.nd.ones((5, 5)))

mxnet/python/mxnet/gluon/block.py in __call__(self, *args)
    539             hook(self, args)
    540
--> 541         out = self.forward(*args)
    542
    543         for hook in self._forward_hooks.values():

mxnet/python/mxnet/gluon/block.py in forward(self, x, *args)
    906             with x.context as ctx:
    907                 if self._active:
--> 908                     return self._call_cached_op(x, *args)
    909
    910                 try:

mxnet/python/mxnet/gluon/block.py in _call_cached_op(self, *args)
    796     def _call_cached_op(self, *args):
    797         if self._cached_op is None:
--> 798             self._build_cache(*args)
    799
    800         args, fmt = _flatten(args, "input")

mxnet/python/mxnet/gluon/block.py in _build_cache(self, *args)
    748
    749     def _build_cache(self, *args):
--> 750         data, out = self._get_graph(*args)
    751         data_names = {data.name : i for i, data in enumerate(data)}
    752         params = self.collect_params()

mxnet/python/mxnet/gluon/block.py in _get_graph(self, *args)
    738             grouped_inputs = _regroup(inputs, self._in_format)[0]
    739
--> 740             params = {i: j.var() for i, j in self._reg_params.items()}
    741             with self.name_scope():
    742                 out = self.hybrid_forward(symbol, *grouped_inputs, **params)  # pylint: disable=no-value-for-parameter

mxnet/python/mxnet/gluon/block.py in <dictcomp>(.0)
    738             grouped_inputs = _regroup(inputs, self._in_format)[0]
    739
--> 740             params = {i: j.var() for i, j in self._reg_params.items()}
    741             with self.name_scope():
    742                 out = self.hybrid_forward(symbol, *grouped_inputs, **params)  # pylint: disable=no-value-for-parameter

mxnet/python/mxnet/gluon/parameter.py in var(self)
    553             self._var = symbol.var(self.name, shape=self.shape, dtype=self.dtype,
    554                                    lr_mult=self.lr_mult, wd_mult=self.wd_mult,
--> 555                                    init=self.init, stype=self._stype)
    556         return self._var
    557

mxnet/python/mxnet/symbol/symbol.py in var(name, attr, shape, lr_mult, wd_mult, dtype, init, stype, **kwargs)
   2516     if init is not None:
   2517         if not isinstance(init, string_types):
-> 2518             init = init.dumps()
   2519         attr['__init__'] = init
   2520     if stype is not None:

mxnet/python/mxnet/initializer.py in dumps(self)
    113         '["xavier", {"rnd_type": "uniform", "magnitude": 2.34, "factor_type": "in"}]'
    114         """
--> 115         return json.dumps([self.__class__.__name__.lower(), self._kwargs])
    116
    117     def __call__(self, desc, arr):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    229         cls is None and indent is None and separators is None and
    230         default is None and not sort_keys and not kw):
--> 231         return _default_encoder.encode(obj)
    232     if cls is None:
    233         cls = JSONEncoder

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in encode(self, o)
    197         # exceptions aren't as detailed.  The list call should be roughly
    198         # equivalent to the PySequence_Fast that ''.join() would do.
--> 199         chunks = self.iterencode(o, _one_shot=True)
    200         if not isinstance(chunks, (list, tuple)):
    201             chunks = list(chunks)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in iterencode(self, o, _one_shot)
    255                 self.key_separator, self.item_separator, self.sort_keys,
    256                 self.skipkeys, _one_shot)
--> 257         return _iterencode(o, 0)
    258
    259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/json/encoder.py in default(self, o)
    177
    178         """
--> 179         raise TypeError(f'Object of type {o.__class__.__name__} '
    180                         f'is not JSON serializable')
    181

TypeError: Object of type ndarray is not JSON serializable
@szha szha changed the title init.Constant does not work in Gluon parameter init.Constant does not work in symbol Sep 3, 2018
@anirudhacharya
Copy link
Member

The error happens here - https://github.com/apache/incubator-mxnet/blob/master/python/mxnet/initializer.py#L116 while trying to serialize a numpy array into json format.

I think the fix is instead of using the in-built json.dumps we should write our own custom JSONEncoder and JSONDecoder that will extend the one implemented in json package. This implementation should handle numpy.ndarrays. I will try to do that.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants