| <!DOCTYPE html> |
| |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"/> |
| <meta content="IE=edge" http-equiv="X-UA-Compatible"/> |
| <meta content="width=device-width, initial-scale=1" name="viewport"/> |
| <meta content="Creating custom operators with numpy" property="og:title"> |
| <meta content="https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/image/og-logo.png" property="og:image"> |
| <meta content="https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/image/og-logo.png" property="og:image:secure_url"> |
| <meta content="Creating custom operators with numpy" property="og:description"/> |
| <title>Creating custom operators with numpy — mxnet documentation</title> |
| <link crossorigin="anonymous" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" rel="stylesheet"/> |
| <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/> |
| <link href="../../_static/basic.css" rel="stylesheet" type="text/css"> |
| <link href="../../_static/pygments.css" rel="stylesheet" type="text/css"> |
| <link href="../../_static/mxnet.css" rel="stylesheet" type="text/css"/> |
| <script type="text/javascript"> |
| var DOCUMENTATION_OPTIONS = { |
| URL_ROOT: '../../', |
| VERSION: '', |
| COLLAPSE_INDEX: false, |
| FILE_SUFFIX: '.html', |
| HAS_SOURCE: true, |
| SOURCELINK_SUFFIX: '.txt' |
| }; |
| </script> |
| <script src="https://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script> |
| <script src="../../_static/underscore.js" type="text/javascript"></script> |
| <script src="../../_static/searchtools_custom.js" type="text/javascript"></script> |
| <script src="../../_static/doctools.js" type="text/javascript"></script> |
| <script src="../../_static/selectlang.js" type="text/javascript"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script> |
| <script type="text/javascript"> jQuery(function() { Search.loadIndex("/versions/1.5.0/searchindex.js"); Search.init();}); </script> |
| <script> |
| (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ |
| (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new |
| Date();a=s.createElement(o), |
| m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) |
| })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); |
| |
| ga('create', 'UA-96378503-1', 'auto'); |
| ga('send', 'pageview'); |
| |
| </script> |
| <!-- --> |
| <!-- <script type="text/javascript" src="../../_static/jquery.js"></script> --> |
| <!-- --> |
| <!-- <script type="text/javascript" src="../../_static/underscore.js"></script> --> |
| <!-- --> |
| <!-- <script type="text/javascript" src="../../_static/doctools.js"></script> --> |
| <!-- --> |
| <!-- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> --> |
| <!-- --> |
| <link href="../../genindex.html" rel="index" title="Index"> |
| <link href="../../search.html" rel="search" title="Search"/> |
| <link href="index.html" rel="up" title="Tutorials"/> |
| <link href="data_augmentation.html" rel="next" title="Image Augmentation"/> |
| <link href="custom_layer.html" rel="prev" title="How to write a custom layer in Apache MxNet Gluon API"/> |
| <link href="https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/image/mxnet-icon.png" rel="icon" type="image/png"/> |
| </link></link></link></meta></meta></meta></head> |
| <body background="https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/image/mxnet-background-compressed.jpeg" role="document"> |
| <div class="content-block"><div class="navbar navbar-fixed-top"> |
| <div class="container" id="navContainer"> |
| <div class="innder" id="header-inner"> |
| <h1 id="logo-wrap"> |
| <a href="../../" id="logo"><img src="https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/image/mxnet_logo.png"/></a> |
| </h1> |
| <nav class="nav-bar" id="main-nav"> |
| <a class="main-nav-link" href="/versions/1.5.0/install/index.html">Install</a> |
| <span id="dropdown-menu-position-anchor"> |
| <a aria-expanded="true" aria-haspopup="true" class="main-nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button">Gluon <span class="caret"></span></a> |
| <ul class="dropdown-menu navbar-menu" id="package-dropdown-menu"> |
| <li><a class="main-nav-link" href="/versions/1.5.0/tutorials/gluon/gluon.html">About</a></li> |
| <li><a class="main-nav-link" href="https://www.d2l.ai/">Dive into Deep Learning</a></li> |
| <li><a class="main-nav-link" href="https://gluon-cv.mxnet.io">GluonCV Toolkit</a></li> |
| <li><a class="main-nav-link" href="https://gluon-nlp.mxnet.io/">GluonNLP Toolkit</a></li> |
| </ul> |
| </span> |
| <span id="dropdown-menu-position-anchor"> |
| <a aria-expanded="true" aria-haspopup="true" class="main-nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button">API <span class="caret"></span></a> |
| <ul class="dropdown-menu navbar-menu" id="package-dropdown-menu"> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/python/index.html">Python</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/c++/index.html">C++</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/clojure/index.html">Clojure</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/java/index.html">Java</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/julia/index.html">Julia</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/perl/index.html">Perl</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/r/index.html">R</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/scala/index.html">Scala</a></li> |
| </ul> |
| </span> |
| <span id="dropdown-menu-position-anchor-docs"> |
| <a aria-expanded="true" aria-haspopup="true" class="main-nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button">Docs <span class="caret"></span></a> |
| <ul class="dropdown-menu navbar-menu" id="package-dropdown-menu-docs"> |
| <li><a class="main-nav-link" href="/versions/1.5.0/faq/index.html">FAQ</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/tutorials/index.html">Tutorials</a> |
| <li><a class="main-nav-link" href="https://github.com/apache/incubator-mxnet/tree/1.5.0/example">Examples</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/architecture/index.html">Architecture</a></li> |
| <li><a class="main-nav-link" href="https://cwiki.apache.org/confluence/display/MXNET/Apache+MXNet+Home">Developer Wiki</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/model_zoo/index.html">Model Zoo</a></li> |
| <li><a class="main-nav-link" href="https://github.com/onnx/onnx-mxnet">ONNX</a></li> |
| </li></ul> |
| </span> |
| <span id="dropdown-menu-position-anchor-community"> |
| <a aria-expanded="true" aria-haspopup="true" class="main-nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button">Community <span class="caret"></span></a> |
| <ul class="dropdown-menu navbar-menu" id="package-dropdown-menu-community"> |
| <li><a class="main-nav-link" href="http://discuss.mxnet.io">Forum</a></li> |
| <li><a class="main-nav-link" href="https://github.com/apache/incubator-mxnet/tree/1.5.0">Github</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/community/contribute.html">Contribute</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/community/ecosystem.html">Ecosystem</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/community/powered_by.html">Powered By</a></li> |
| </ul> |
| </span> |
| <span id="dropdown-menu-position-anchor-version" style="position: relative"><a href="#" class="main-nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="true">1.5.0<span class="caret"></span></a><ul id="package-dropdown-menu" class="dropdown-menu"><li><a href="/">master</a></li><li><a href="/versions/1.7/">1.7</a></li><li><a href=/versions/1.6/>1.6</a></li><li><a href=/versions/1.5.0/>1.5.0</a></li><li><a href=/versions/1.4.1/>1.4.1</a></li><li><a href=/versions/1.3.1/>1.3.1</a></li><li><a href=/versions/1.2.1/>1.2.1</a></li><li><a href=/versions/1.1.0/>1.1.0</a></li><li><a href=/versions/1.0.0/>1.0.0</a></li><li><a href=/versions/0.12.1/>0.12.1</a></li><li><a href=/versions/0.11.0/>0.11.0</a></li></ul></span></nav> |
| <script> function getRootPath(){ return "../../" } </script> |
| <div class="burgerIcon dropdown"> |
| <a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button">☰</a> |
| <ul class="dropdown-menu" id="burgerMenu"> |
| <li><a href="/versions/1.5.0/install/index.html">Install</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/tutorials/index.html">Tutorials</a></li> |
| <li class="dropdown-submenu dropdown"> |
| <a aria-expanded="true" aria-haspopup="true" class="dropdown-toggle burger-link" data-toggle="dropdown" href="#" tabindex="-1">Gluon</a> |
| <ul class="dropdown-menu navbar-menu" id="package-dropdown-menu"> |
| <li><a class="main-nav-link" href="/versions/1.5.0/tutorials/gluon/gluon.html">About</a></li> |
| <li><a class="main-nav-link" href="http://gluon.mxnet.io">The Straight Dope (Tutorials)</a></li> |
| <li><a class="main-nav-link" href="https://gluon-cv.mxnet.io">GluonCV Toolkit</a></li> |
| <li><a class="main-nav-link" href="https://gluon-nlp.mxnet.io/">GluonNLP Toolkit</a></li> |
| </ul> |
| </li> |
| <li class="dropdown-submenu"> |
| <a aria-expanded="true" aria-haspopup="true" class="dropdown-toggle burger-link" data-toggle="dropdown" href="#" tabindex="-1">API</a> |
| <ul class="dropdown-menu"> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/python/index.html">Python</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/c++/index.html">C++</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/clojure/index.html">Clojure</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/java/index.html">Java</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/julia/index.html">Julia</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/perl/index.html">Perl</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/r/index.html">R</a></li> |
| <li><a class="main-nav-link" href="/versions/1.5.0/api/scala/index.html">Scala</a></li> |
| </ul> |
| </li> |
| <li class="dropdown-submenu"> |
| <a aria-expanded="true" aria-haspopup="true" class="dropdown-toggle burger-link" data-toggle="dropdown" href="#" tabindex="-1">Docs</a> |
| <ul class="dropdown-menu"> |
| <li><a href="/versions/1.5.0/faq/index.html" tabindex="-1">FAQ</a></li> |
| <li><a href="/versions/1.5.0/tutorials/index.html" tabindex="-1">Tutorials</a></li> |
| <li><a href="https://github.com/apache/incubator-mxnet/tree/1.5.0/example" tabindex="-1">Examples</a></li> |
| <li><a href="/versions/1.5.0/architecture/index.html" tabindex="-1">Architecture</a></li> |
| <li><a href="https://cwiki.apache.org/confluence/display/MXNET/Apache+MXNet+Home" tabindex="-1">Developer Wiki</a></li> |
| <li><a href="/versions/1.5.0/model_zoo/index.html" tabindex="-1">Gluon Model Zoo</a></li> |
| <li><a href="https://github.com/onnx/onnx-mxnet" tabindex="-1">ONNX</a></li> |
| </ul> |
| </li> |
| <li class="dropdown-submenu dropdown"> |
| <a aria-haspopup="true" class="dropdown-toggle burger-link" data-toggle="dropdown" href="#" role="button" tabindex="-1">Community</a> |
| <ul class="dropdown-menu"> |
| <li><a href="http://discuss.mxnet.io" tabindex="-1">Forum</a></li> |
| <li><a href="https://github.com/apache/incubator-mxnet/tree/1.5.0" tabindex="-1">Github</a></li> |
| <li><a href="/versions/1.5.0/community/contribute.html" tabindex="-1">Contribute</a></li> |
| <li><a href="/versions/1.5.0/community/ecosystem.html" tabindex="-1">Ecosystem</a></li> |
| <li><a href="/versions/1.5.0/community/powered_by.html" tabindex="-1">Powered By</a></li> |
| </ul> |
| </li> |
| <li id="dropdown-menu-position-anchor-version-mobile" class="dropdown-submenu" style="position: relative"><a href="#" tabindex="-1">1.5.0</a><ul class="dropdown-menu"><li><a tabindex="-1" href=/>master</a></li><li><a tabindex="-1" href=/versions/1.6/>1.6</a></li><li><a tabindex="-1" href=/versions/1.5.0/>1.5.0</a></li><li><a tabindex="-1" href=/versions/1.4.1/>1.4.1</a></li><li><a tabindex="-1" href=/versions/1.3.1/>1.3.1</a></li><li><a tabindex="-1" href=/versions/1.2.1/>1.2.1</a></li><li><a tabindex="-1" href=/versions/1.1.0/>1.1.0</a></li><li><a tabindex="-1" href=/versions/1.0.0/>1.0.0</a></li><li><a tabindex="-1" href=/versions/0.12.1/>0.12.1</a></li><li><a tabindex="-1" href=/versions/0.11.0/>0.11.0</a></li></ul></li></ul> |
| </div> |
| <div class="plusIcon dropdown"> |
| <a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button"><span aria-hidden="true" class="glyphicon glyphicon-plus"></span></a> |
| <ul class="dropdown-menu dropdown-menu-right" id="plusMenu"></ul> |
| </div> |
| <div id="search-input-wrap"> |
| <form action="../../search.html" autocomplete="off" class="" method="get" role="search"> |
| <div class="form-group inner-addon left-addon"> |
| <i class="glyphicon glyphicon-search"></i> |
| <input class="form-control" name="q" placeholder="Search" type="text"/> |
| </div> |
| <input name="check_keywords" type="hidden" value="yes"> |
| <input name="area" type="hidden" value="default"/> |
| </input></form> |
| <div id="search-preview"></div> |
| </div> |
| <div id="searchIcon"> |
| <span aria-hidden="true" class="glyphicon glyphicon-search"></span> |
| </div> |
| <!-- <div id="lang-select-wrap"> --> |
| <!-- <label id="lang-select-label"> --> |
| <!-- <\!-- <i class="fa fa-globe"></i> -\-> --> |
| <!-- <span></span> --> |
| <!-- </label> --> |
| <!-- <select id="lang-select"> --> |
| <!-- <option value="en">Eng</option> --> |
| <!-- <option value="zh">中文</option> --> |
| <!-- </select> --> |
| <!-- </div> --> |
| <!-- <a id="mobile-nav-toggle"> |
| <span class="mobile-nav-toggle-bar"></span> |
| <span class="mobile-nav-toggle-bar"></span> |
| <span class="mobile-nav-toggle-bar"></span> |
| </a> --> |
| </div> |
| </div> |
| </div> |
| <script type="text/javascript"> |
| $('body').css('background', 'white'); |
| </script> |
| <div class="container"> |
| <div class="row"> |
| <div aria-label="main navigation" class="sphinxsidebar leftsidebar" role="navigation"> |
| <div class="sphinxsidebarwrapper"> |
| <ul> |
| <li class="toctree-l1"><a class="reference internal" href="../../api/index.html">MXNet APIs</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../architecture/index.html">MXNet Architecture</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../community/index.html">MXNet Community</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../faq/index.html">MXNet FAQ</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../gluon/index.html">About Gluon</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../install/index.html">Installing MXNet</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../install/index.html#nvidia-jetson-tx-family">Nvidia Jetson TX family</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../install/index.html#source-download">Source Download</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../../model_zoo/index.html">MXNet Model Zoo</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../index.html">Tutorials</a></li> |
| </ul> |
| </div> |
| </div> |
| <div class="content"> |
| <div class="page-tracker"></div> |
| <!--- Licensed to the Apache Software Foundation (ASF) under one --> |
| <!--- or more contributor license agreements. See the NOTICE file --> |
| <!--- distributed with this work for additional information --> |
| <!--- regarding copyright ownership. The ASF licenses this file --> |
| <!--- to you under the Apache License, Version 2.0 (the --> |
| <!--- "License"); you may not use this file except in compliance --> |
| <!--- with the License. You may obtain a copy of the License at --><!--- http://www.apache.org/licenses/LICENSE-2.0 --><!--- Unless required by applicable law or agreed to in writing, --> |
| <!--- software distributed under the License is distributed on an --> |
| <!--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY --> |
| <!--- KIND, either express or implied. See the License for the --> |
| <!--- specific language governing permissions and limitations --> |
| <!--- under the License. --><div class="section" id="creating-custom-operators-with-numpy"> |
| <span id="creating-custom-operators-with-numpy"></span><h1>Creating custom operators with numpy<a class="headerlink" href="#creating-custom-operators-with-numpy" title="Permalink to this headline">¶</a></h1> |
| <p>In this tutorial, we will learn how to build custom operators with numpy in python. We will go through two examples:</p> |
| <ul class="simple"> |
| <li>Custom operator without any <code class="docutils literal"><span class="pre">Parameter</span></code>s</li> |
| <li>Custom operator with <code class="docutils literal"><span class="pre">Parameter</span></code>s</li> |
| </ul> |
| <p>Custom operator in python is easy to develop and good for prototyping, but may hurt performance. If you find it to be a bottleneck, please consider moving to a C++ based implementation in the backend.</p> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span> |
| <span class="kn">import</span> <span class="nn">mxnet</span> <span class="kn">as</span> <span class="nn">mx</span> |
| <span class="kn">from</span> <span class="nn">mxnet</span> <span class="kn">import</span> <span class="n">gluon</span><span class="p">,</span> <span class="n">autograd</span> |
| <span class="kn">import</span> <span class="nn">os</span> |
| </pre></div> |
| </div> |
| <div class="section" id="parameter-less-operators"> |
| <span id="parameter-less-operators"></span><h2>Parameter-less operators<a class="headerlink" href="#parameter-less-operators" title="Permalink to this headline">¶</a></h2> |
| <p>This operator implements the standard sigmoid activation function. This is only for illustration purposes, in real life you would use the built-in operator <code class="docutils literal"><span class="pre">mx.nd.relu</span></code>.</p> |
| <div class="section" id="forward-backward-implementation"> |
| <span id="forward-backward-implementation"></span><h3>Forward & backward implementation<a class="headerlink" href="#forward-backward-implementation" title="Permalink to this headline">¶</a></h3> |
| <p>First we implement the forward and backward computation by sub-classing <code class="docutils literal"><span class="pre">mx.operator.CustomOp</span></code>:</p> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Sigmoid</span><span class="p">(</span><span class="n">mx</span><span class="o">.</span><span class="n">operator</span><span class="o">.</span><span class="n">CustomOp</span><span class="p">):</span> |
| <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">is_train</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">in_data</span><span class="p">,</span> <span class="n">out_data</span><span class="p">,</span> <span class="n">aux</span><span class="p">):</span> |
| <span class="sd">"""Implements forward computation.</span> |
| |
| <span class="sd"> is_train : bool, whether forwarding for training or testing.</span> |
| <span class="sd"> req : list of {'null', 'write', 'inplace', 'add'}, how to assign to out_data. 'null' means skip assignment, etc.</span> |
| <span class="sd"> in_data : list of NDArray, input data.</span> |
| <span class="sd"> out_data : list of NDArray, pre-allocated output buffers.</span> |
| <span class="sd"> aux : list of NDArray, mutable auxiliary states. Usually not used.</span> |
| <span class="sd"> """</span> |
| <span class="n">x</span> <span class="o">=</span> <span class="n">in_data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">asnumpy</span><span class="p">()</span> |
| <span class="n">y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">/</span> <span class="p">(</span><span class="mf">1.0</span> <span class="o">+</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="n">x</span><span class="p">))</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">assign</span><span class="p">(</span><span class="n">out_data</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">req</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">y</span><span class="p">))</span> |
| |
| <span class="k">def</span> <span class="nf">backward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">out_grad</span><span class="p">,</span> <span class="n">in_data</span><span class="p">,</span> <span class="n">out_data</span><span class="p">,</span> <span class="n">in_grad</span><span class="p">,</span> <span class="n">aux</span><span class="p">):</span> |
| <span class="sd">"""Implements backward computation</span> |
| |
| <span class="sd"> req : list of {'null', 'write', 'inplace', 'add'}, how to assign to in_grad</span> |
| <span class="sd"> out_grad : list of NDArray, gradient w.r.t. output data.</span> |
| <span class="sd"> in_grad : list of NDArray, gradient w.r.t. input data. This is the output buffer.</span> |
| <span class="sd"> """</span> |
| <span class="n">y</span> <span class="o">=</span> <span class="n">out_data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">asnumpy</span><span class="p">()</span> |
| <span class="n">dy</span> <span class="o">=</span> <span class="n">out_grad</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">asnumpy</span><span class="p">()</span> |
| <span class="n">dx</span> <span class="o">=</span> <span class="n">dy</span><span class="o">*</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">-</span> <span class="n">y</span><span class="p">)</span><span class="o">*</span><span class="n">y</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">assign</span><span class="p">(</span><span class="n">in_grad</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">req</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">dx</span><span class="p">))</span> |
| </pre></div> |
| </div> |
| </div> |
| <div class="section" id="register-custom-operator"> |
| <span id="register-custom-operator"></span><h3>Register custom operator<a class="headerlink" href="#register-custom-operator" title="Permalink to this headline">¶</a></h3> |
| <p>Then we need to register the custom op and describe it’s properties like input and output shapes so that mxnet can recognize it. This is done by sub-classing <code class="docutils literal"><span class="pre">mx.operator.CustomOpProp</span></code>:</p> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="nd">@mx.operator.register</span><span class="p">(</span><span class="s2">"sigmoid"</span><span class="p">)</span> <span class="c1"># register with name "sigmoid"</span> |
| <span class="k">class</span> <span class="nc">SigmoidProp</span><span class="p">(</span><span class="n">mx</span><span class="o">.</span><span class="n">operator</span><span class="o">.</span><span class="n">CustomOpProp</span><span class="p">):</span> |
| <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="nb">super</span><span class="p">(</span><span class="n">SigmoidProp</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span> |
| |
| <span class="k">def</span> <span class="nf">list_arguments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="c1"># this can be omitted if you only have 1 input.</span> |
| <span class="k">return</span> <span class="p">[</span><span class="s1">'data'</span><span class="p">]</span> |
| |
| <span class="k">def</span> <span class="nf">list_outputs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="c1"># this can be omitted if you only have 1 output.</span> |
| <span class="k">return</span> <span class="p">[</span><span class="s1">'output'</span><span class="p">]</span> |
| |
| <span class="k">def</span> <span class="nf">infer_shape</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">in_shapes</span><span class="p">):</span> |
| <span class="sd">"""Calculate output shapes from input shapes. This can be</span> |
| <span class="sd"> omited if all your inputs and outputs have the same shape.</span> |
| |
| <span class="sd"> in_shapes : list of shape. Shape is described by a tuple of int.</span> |
| <span class="sd"> """</span> |
| <span class="n">data_shape</span> <span class="o">=</span> <span class="n">in_shapes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> |
| <span class="n">output_shape</span> <span class="o">=</span> <span class="n">data_shape</span> |
| <span class="c1"># return 3 lists representing inputs shapes, outputs shapes, and aux data shapes.</span> |
| <span class="k">return</span> <span class="p">(</span><span class="n">data_shape</span><span class="p">,),</span> <span class="p">(</span><span class="n">output_shape</span><span class="p">,),</span> <span class="p">()</span> |
| |
| <span class="k">def</span> <span class="nf">create_operator</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">in_shapes</span><span class="p">,</span> <span class="n">in_dtypes</span><span class="p">):</span> |
| <span class="c1"># create and return the CustomOp class.</span> |
| <span class="k">return</span> <span class="n">Sigmoid</span><span class="p">()</span> |
| </pre></div> |
| </div> |
| </div> |
| <div class="section" id="example-usage"> |
| <span id="example-usage"></span><h3>Example Usage<a class="headerlink" href="#example-usage" title="Permalink to this headline">¶</a></h3> |
| <p>We can now use this operator by calling <code class="docutils literal"><span class="pre">mx.nd.Custom</span></code>:</p> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span> |
| <span class="c1"># attach gradient buffer to x for autograd</span> |
| <span class="n">x</span><span class="o">.</span><span class="n">attach_grad</span><span class="p">()</span> |
| <span class="c1"># forward in a record() section to save computation graph for backward</span> |
| <span class="c1"># see autograd tutorial to learn more.</span> |
| <span class="k">with</span> <span class="n">autograd</span><span class="o">.</span><span class="n">record</span><span class="p">():</span> |
| <span class="n">y</span> <span class="o">=</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">Custom</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">op_type</span><span class="o">=</span><span class="s1">'sigmoid'</span><span class="p">)</span> |
| <span class="k">print</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> |
| </pre></div> |
| </div> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="c1"># call backward computation</span> |
| <span class="n">y</span><span class="o">.</span><span class="n">backward</span><span class="p">()</span> |
| <span class="c1"># gradient is now saved to the grad buffer we attached previously</span> |
| <span class="k">print</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">grad</span><span class="p">)</span> |
| </pre></div> |
| </div> |
| </div> |
| </div> |
| <div class="section" id="parametrized-operator"> |
| <span id="parametrized-operator"></span><h2>Parametrized Operator<a class="headerlink" href="#parametrized-operator" title="Permalink to this headline">¶</a></h2> |
| <p>In the second use case we implement an operator with learnable weights. We implement the dense (or fully connected) layer that has one input, one output, and two learnable parameters: weight and bias.</p> |
| <p>The dense operator performs a dot product between data and weight, then add bias to it.</p> |
| <div class="section" id="forward-backward-implementation"> |
| <span id="id1"></span><h3>Forward & backward implementation<a class="headerlink" href="#forward-backward-implementation" title="Permalink to this headline">¶</a></h3> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Dense</span><span class="p">(</span><span class="n">mx</span><span class="o">.</span><span class="n">operator</span><span class="o">.</span><span class="n">CustomOp</span><span class="p">):</span> |
| <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bias</span><span class="p">):</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_bias</span> <span class="o">=</span> <span class="n">bias</span> |
| |
| <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">is_train</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">in_data</span><span class="p">,</span> <span class="n">out_data</span><span class="p">,</span> <span class="n">aux</span><span class="p">):</span> |
| <span class="n">x</span> <span class="o">=</span> <span class="n">in_data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">asnumpy</span><span class="p">()</span> |
| <span class="n">weight</span> <span class="o">=</span> <span class="n">in_data</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">asnumpy</span><span class="p">()</span> |
| <span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">weight</span><span class="o">.</span><span class="n">T</span><span class="p">)</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bias</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">assign</span><span class="p">(</span><span class="n">out_data</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">req</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">y</span><span class="p">))</span> |
| |
| <span class="k">def</span> <span class="nf">backward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">req</span><span class="p">,</span> <span class="n">out_grad</span><span class="p">,</span> <span class="n">in_data</span><span class="p">,</span> <span class="n">out_data</span><span class="p">,</span> <span class="n">in_grad</span><span class="p">,</span> <span class="n">aux</span><span class="p">):</span> |
| <span class="n">x</span> <span class="o">=</span> <span class="n">in_data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">asnumpy</span><span class="p">()</span> |
| <span class="n">dy</span> <span class="o">=</span> <span class="n">out_grad</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">asnumpy</span><span class="p">()</span> |
| <span class="n">dx</span> <span class="o">=</span> <span class="n">dy</span><span class="o">.</span><span class="n">T</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">assign</span><span class="p">(</span><span class="n">in_grad</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">req</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">dx</span><span class="p">))</span> |
| </pre></div> |
| </div> |
| </div> |
| <div class="section" id="registration"> |
| <span id="registration"></span><h3>Registration<a class="headerlink" href="#registration" title="Permalink to this headline">¶</a></h3> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="nd">@mx.operator.register</span><span class="p">(</span><span class="s2">"dense"</span><span class="p">)</span> <span class="c1"># register with name "sigmoid"</span> |
| <span class="k">class</span> <span class="nc">DenseProp</span><span class="p">(</span><span class="n">mx</span><span class="o">.</span><span class="n">operator</span><span class="o">.</span><span class="n">CustomOpProp</span><span class="p">):</span> |
| <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bias</span><span class="p">):</span> |
| <span class="nb">super</span><span class="p">(</span><span class="n">DenseProp</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span> |
| <span class="c1"># we use constant bias here to illustrate how to pass arguments</span> |
| <span class="c1"># to operators. All arguments are in string format so you need</span> |
| <span class="c1"># to convert them back to the type you want.</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_bias</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">bias</span><span class="p">)</span> |
| |
| <span class="k">def</span> <span class="nf">list_arguments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="k">return</span> <span class="p">[</span><span class="s1">'data'</span><span class="p">,</span> <span class="s1">'weight'</span><span class="p">]</span> |
| |
| <span class="k">def</span> <span class="nf">list_outputs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> |
| <span class="c1"># this can be omitted if you only have 1 output.</span> |
| <span class="k">return</span> <span class="p">[</span><span class="s1">'output'</span><span class="p">]</span> |
| |
| <span class="k">def</span> <span class="nf">infer_shape</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">in_shapes</span><span class="p">):</span> |
| <span class="n">data_shape</span> <span class="o">=</span> <span class="n">in_shapes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> |
| <span class="n">weight_shape</span> <span class="o">=</span> <span class="n">in_shapes</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> |
| <span class="n">output_shape</span> <span class="o">=</span> <span class="p">(</span><span class="n">data_shape</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">weight_shape</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> |
| <span class="c1"># return 3 lists representing inputs shapes, outputs shapes, and aux data shapes.</span> |
| <span class="k">return</span> <span class="p">(</span><span class="n">data_shape</span><span class="p">,</span> <span class="n">weight_shape</span><span class="p">),</span> <span class="p">(</span><span class="n">output_shape</span><span class="p">,),</span> <span class="p">()</span> |
| |
| <span class="k">def</span> <span class="nf">create_operator</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">in_shapes</span><span class="p">,</span> <span class="n">in_dtypes</span><span class="p">):</span> |
| <span class="c1"># create and return the CustomOp class.</span> |
| <span class="k">return</span> <span class="n">Dense</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_bias</span><span class="p">)</span> |
| </pre></div> |
| </div> |
| </div> |
| <div class="section" id="use-customop-together-with-block"> |
| <span id="use-customop-together-with-block"></span><h3>Use CustomOp together with Block<a class="headerlink" href="#use-customop-together-with-block" title="Permalink to this headline">¶</a></h3> |
| <p>Parameterized CustomOp are usually used together with Blocks, which holds the parameter.</p> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">DenseBlock</span><span class="p">(</span><span class="n">mx</span><span class="o">.</span><span class="n">gluon</span><span class="o">.</span><span class="n">Block</span><span class="p">):</span> |
| <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">in_channels</span><span class="p">,</span> <span class="n">channels</span><span class="p">,</span> <span class="n">bias</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> |
| <span class="nb">super</span><span class="p">(</span><span class="n">DenseBlock</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">_bias</span> <span class="o">=</span> <span class="n">bias</span> |
| <span class="bp">self</span><span class="o">.</span><span class="n">weight</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'weight'</span><span class="p">,</span> <span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="n">channels</span><span class="p">,</span> <span class="n">in_channels</span><span class="p">))</span> |
| |
| <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span> |
| <span class="n">ctx</span> <span class="o">=</span> <span class="n">x</span><span class="o">.</span><span class="n">context</span> |
| <span class="k">return</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">Custom</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">weight</span><span class="o">.</span><span class="n">data</span><span class="p">(</span><span class="n">ctx</span><span class="p">),</span> <span class="n">bias</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_bias</span><span class="p">,</span> <span class="n">op_type</span><span class="o">=</span><span class="s1">'dense'</span><span class="p">)</span> |
| </pre></div> |
| </div> |
| </div> |
| <div class="section" id="example-usage"> |
| <span id="id2"></span><h3>Example usage<a class="headerlink" href="#example-usage" title="Permalink to this headline">¶</a></h3> |
| <div class="highlight-python"><div class="highlight"><pre><span></span><span class="n">dense</span> <span class="o">=</span> <span class="n">DenseBlock</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">)</span> |
| <span class="n">dense</span><span class="o">.</span><span class="n">initialize</span><span class="p">()</span> |
| <span class="n">x</span> <span class="o">=</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="n">shape</span><span class="o">=</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span> |
| <span class="n">y</span> <span class="o">=</span> <span class="n">dense</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> |
| <span class="k">print</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> |
| </pre></div> |
| </div> |
| </div> |
| </div> |
| <div class="section" id="using-custom-operators-with-fork"> |
| <span id="using-custom-operators-with-fork"></span><h2>Using custom operators with fork<a class="headerlink" href="#using-custom-operators-with-fork" title="Permalink to this headline">¶</a></h2> |
| <p>In Linux systems, the default method in multiprocessing to create process is by using fork. If there are unfinished async custom operations when forking, the program will be blocked because of python GIL. Always use sync calls like <code class="docutils literal"><span class="pre">wait_to_read</span></code> or <code class="docutils literal"><span class="pre">waitall</span></code> before calling fork.</p> |
| <div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span> |
| <span class="n">y</span> <span class="o">=</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">Custom</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">op_type</span><span class="o">=</span><span class="s1">'sigmoid'</span><span class="p">)</span> |
| <span class="c1"># unfinished async sigmoid operation will cause blocking</span> |
| <span class="n">os</span><span class="o">.</span><span class="n">fork</span><span class="p">()</span> |
| </pre></div> |
| </div> |
| <p>Correctly handling this will make mxnet depend upon libpython, so the workaround now is to ensure that all custom operations are executed before forking process.</p> |
| <div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">array</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span> |
| <span class="n">y</span> <span class="o">=</span> <span class="n">mx</span><span class="o">.</span><span class="n">nd</span><span class="o">.</span><span class="n">Custom</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">op_type</span><span class="o">=</span><span class="s1">'sigmoid'</span><span class="p">)</span> |
| <span class="c1"># force execution by reading y</span> |
| <span class="nb">print</span><span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">asnumpy</span><span class="p">())</span> |
| <span class="n">os</span><span class="o">.</span><span class="n">fork</span><span class="p">()</span> |
| </pre></div> |
| </div> |
| <div class="btn-group" role="group"> |
| <div class="download-btn"><a download="customop.ipynb" href="customop.ipynb"><span class="glyphicon glyphicon-download-alt"></span> customop.ipynb</a></div></div></div> |
| </div> |
| </div> |
| </div> |
| <div aria-label="main navigation" class="sphinxsidebar rightsidebar" role="navigation"> |
| <div class="sphinxsidebarwrapper"> |
| <h3><a href="../../index.html">Table Of Contents</a></h3> |
| <ul> |
| <li><a class="reference internal" href="#">Creating custom operators with numpy</a><ul> |
| <li><a class="reference internal" href="#parameter-less-operators">Parameter-less operators</a><ul> |
| <li><a class="reference internal" href="#forward-backward-implementation">Forward & backward implementation</a></li> |
| <li><a class="reference internal" href="#register-custom-operator">Register custom operator</a></li> |
| <li><a class="reference internal" href="#example-usage">Example Usage</a></li> |
| </ul> |
| </li> |
| <li><a class="reference internal" href="#parametrized-operator">Parametrized Operator</a><ul> |
| <li><a class="reference internal" href="#forward-backward-implementation">Forward & backward implementation</a></li> |
| <li><a class="reference internal" href="#registration">Registration</a></li> |
| <li><a class="reference internal" href="#use-customop-together-with-block">Use CustomOp together with Block</a></li> |
| <li><a class="reference internal" href="#example-usage">Example usage</a></li> |
| </ul> |
| </li> |
| <li><a class="reference internal" href="#using-custom-operators-with-fork">Using custom operators with fork</a></li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div><div class="footer"> |
| <div class="section-disclaimer"> |
| <div class="container"> |
| <div> |
| <img height="60" src="https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/image/apache_incubator_logo.png"/> |
| <p> |
| Apache MXNet is an effort undergoing incubation at The Apache Software Foundation (ASF), <strong>sponsored by the <i>Apache Incubator</i></strong>. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF. |
| </p> |
| <p> |
| "Copyright © 2017-2018, The Apache Software Foundation |
| Apache MXNet, MXNet, Apache, the Apache feather, and the Apache MXNet project logo are either registered trademarks or trademarks of the Apache Software Foundation." |
| </p> |
| </div> |
| </div> |
| </div> |
| </div> <!-- pagename != index --> |
| </div> |
| <script crossorigin="anonymous" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> |
| <script src="../../_static/js/sidebar.js" type="text/javascript"></script> |
| <script src="../../_static/js/search.js" type="text/javascript"></script> |
| <script src="../../_static/js/navbar.js" type="text/javascript"></script> |
| <script src="../../_static/js/clipboard.min.js" type="text/javascript"></script> |
| <script src="../../_static/js/copycode.js" type="text/javascript"></script> |
| <script src="../../_static/js/page.js" type="text/javascript"></script> |
| <script src="../../_static/js/docversion.js" type="text/javascript"></script> |
| <script type="text/javascript"> |
| $('body').ready(function () { |
| $('body').css('visibility', 'visible'); |
| }); |
| </script> |
| </body> |
| </html> |