You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by an...@apache.org on 2018/06/15 23:29:45 UTC
[incubator-mxnet] 03/04: Improve hybridblock doc (#11236)
This is an automated email from the ASF dual-hosted git repository.
anirudh2290 pushed a commit to branch v1.2.0
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
commit dfc17bb6ec2627e4ee7bb65c89cc16154c9fa2f9
Author: Eric Junyuan Xie <pi...@users.noreply.github.com>
AuthorDate: Thu Jun 14 14:02:48 2018 -0700
Improve hybridblock doc (#11236)
---
docs/tutorials/gluon/hybrid.md | 29 ++++++++++++++++-------------
python/mxnet/gluon/block.py | 39 +++++++++++++++++++++++++++++++++++----
python/mxnet/gluon/parameter.py | 14 +++++++++++---
3 files changed, 62 insertions(+), 20 deletions(-)
diff --git a/docs/tutorials/gluon/hybrid.md b/docs/tutorials/gluon/hybrid.md
index 5c8372a..fe8ca6f 100644
--- a/docs/tutorials/gluon/hybrid.md
+++ b/docs/tutorials/gluon/hybrid.md
@@ -87,7 +87,7 @@ net(x)
Hybrid execution can be activated by simply calling `.hybridize()` on the top
level layer. The first forward call after activation will try to build a
computation graph from `hybrid_forward` and cache it. On subsequent forward
-calls the cached graph instead of `hybrid_forward` will be invoked:
+calls the cached graph, instead of `hybrid_forward`, will be invoked:
```python
net.hybridize()
@@ -105,23 +105,26 @@ Hybridize will speed up execution and save memory. If the top level layer is
not a `HybridBlock`, you can still call `.hybridize()` on it and Gluon will try
to hybridize its children layers instead.
+Please refer to the [API manual](https://mxnet.incubator.apache.org/api/python/gluon/gluon.html?highlight=hybridize#mxnet.gluon.Block.hybridize)
+for details.
+
## Serializing trained model for deployment
-Models implemented as `HybridBlock` can be easily serialized for deployment
-using other language front-ends like C, C++ and Scala. To this end, we simply
-forward the model with symbolic variables instead of NDArrays and save the
-output Symbol(s):
+Models implemented as `HybridBlock` can be easily serialized. The serialized
+model can be loaded back later or used for deployment
+with other language front-ends like C, C++ and Scala. To this end, we simply
+use `export` and `SymbolBlock.imports`:
```python
-x = mx.sym.var('data')
-y = net(x)
-print(y)
-y.save('model.json')
-net.save_parameters('model.params')
+net.export('model', epoch=1)
```
-If your network outputs more than one value, you can use `mx.sym.Group` to
-combine them into a grouped Symbol and then save. The saved json and params
-files can then be loaded with C, C++ and Scala interface for prediction.
+Two files `model-symbol.json` and `model-0001.params` are saved on disk.
+You can use other language bindings to load them. You can also load them back
+to gluon with `SymbolBlock`:
+
+```python
+net2 = gluon.SymbolBlock.imports('model-symbol.json', ['data'], 'model-0001.params')
+```
<!-- INSERT SOURCE DOWNLOAD BUTTONS -->
diff --git a/python/mxnet/gluon/block.py b/python/mxnet/gluon/block.py
index 1720526..948a6a8 100644
--- a/python/mxnet/gluon/block.py
+++ b/python/mxnet/gluon/block.py
@@ -148,7 +148,8 @@ class Block(object):
Child :py:class:`Block` assigned this way will be registered and :py:meth:`collect_params`
- will collect their Parameters recursively.
+ will collect their Parameters recursively. You can also manually register
+ child blocks with :py:meth:`register_child`.
Parameters
----------
@@ -307,6 +308,8 @@ class Block(object):
def save_parameters(self, filename):
"""Save parameters to file.
+ Parameters
+ ----------
filename : str
Path to file.
"""
@@ -333,6 +336,8 @@ class Block(object):
ignore_extra=False):
"""Load parameters from file.
+ Parameters
+ ----------
filename : str
Path to parameter file.
ctx : Context or list of Context, default cpu()
@@ -462,9 +467,31 @@ class Block(object):
class HybridBlock(Block):
"""`HybridBlock` supports forwarding with both Symbol and NDArray.
+ `HybridBlock` is similar to `Block`, with a few differences::
+
+ import mxnet as mx
+ from mxnet.gluon import HybridBlock, nn
+
+ class Model(HybridBlock):
+ def __init__(self, **kwargs):
+ super(Model, self).__init__(**kwargs)
+ # use name_scope to give child Blocks appropriate names.
+ with self.name_scope():
+ self.dense0 = nn.Dense(20)
+ self.dense1 = nn.Dense(20)
+
+ def hybrid_forward(self, F, x):
+ x = F.relu(self.dense0(x))
+ return F.relu(self.dense1(x))
+
+ model = Model()
+ model.initialize(ctx=mx.cpu(0))
+ model.hybridize()
+ model(mx.nd.zeros((10, 10), ctx=mx.cpu(0)))
+
Forward computation in :py:class:`HybridBlock` must be static to work with :py:class:`Symbol` s,
i.e. you cannot call :py:meth:`NDArray.asnumpy`, :py:attr:`NDArray.shape`,
- :py:attr:`NDArray.dtype`, etc on tensors.
+ :py:attr:`NDArray.dtype`, `NDArray` indexing (`x[i]`) etc on tensors.
Also, you cannot use branching or loop logic that bases on non-constant
expressions like random numbers or intermediate results, since they change
the graph structure for each iteration.
@@ -474,8 +501,12 @@ class HybridBlock(Block):
representing the forward computation and cache it. On subsequent forwards,
the cached graph will be used instead of :py:meth:`hybrid_forward`.
- Refer `Hybrid tutorial <http://mxnet.io/tutorials/gluon/hybrid.html>`_ to see
- the end-to-end usage.
+ Please see references for detailed tutorial.
+
+ References
+ ----------
+ `Hybrid - Faster training and easy deployment
+ <http://mxnet.io/tutorials/gluon/hybrid.html>`_
"""
def __init__(self, prefix=None, params=None):
super(HybridBlock, self).__init__(prefix=prefix, params=params)
diff --git a/python/mxnet/gluon/parameter.py b/python/mxnet/gluon/parameter.py
index 99885eb..ac2eb40 100644
--- a/python/mxnet/gluon/parameter.py
+++ b/python/mxnet/gluon/parameter.py
@@ -342,6 +342,8 @@ class Parameter(object):
def reset_ctx(self, ctx):
"""Re-assign Parameter to other contexts.
+ Parameters
+ ----------
ctx : Context or list of Context, default ``context.current_context()``.
Assign Parameter to given context. If ctx is a list of Context, a
copy will be made for each context.
@@ -478,8 +480,8 @@ class Constant(Parameter):
super(Block, self).__init__(**kwargs)
self.const = self.params.get_constant('const', [[1,2],[3,4]])
- Parameter
- ---------
+ Parameters
+ ----------
name : str
Name of the parameter.
value : array-like
@@ -619,7 +621,7 @@ class ParameterDict(object):
found, :py:func:`get` will create a new :py:class:`Constant` with key-word
arguments and insert it to self.
- Constants
+ Parameters
----------
name : str
Name of the desired Constant. It will be prepended with this dictionary's
@@ -694,6 +696,8 @@ class ParameterDict(object):
def reset_ctx(self, ctx):
"""Re-assign all Parameters to other contexts.
+ Parameters
+ ----------
ctx : Context or list of Context, default :py:meth:`context.current_context()`.
Assign Parameter to given context. If ctx is a list of Context, a
copy will be made for each context.
@@ -726,6 +730,8 @@ class ParameterDict(object):
def save(self, filename, strip_prefix=''):
"""Save parameters to file.
+ Parameters
+ ----------
filename : str
Path to parameter file.
strip_prefix : str, default ''
@@ -750,6 +756,8 @@ class ParameterDict(object):
ignore_extra=False, restore_prefix=''):
"""Load parameters from file.
+ Parameters
+ ----------
filename : str
Path to parameter file.
ctx : Context or list of Context
--
To stop receiving notification emails like this one, please contact
anirudh2290@apache.org.