blob: f7ff55641d4dae8f1e5029b33a2bcda3b6c7dcfe [file] [log] [blame]
<!DOCTYPE html>
<!---
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.
-->
<html lang=" en"><head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/image/mxnet-icon.png" rel="icon" type="image/png"><!-- Begin Jekyll SEO tag v2.6.1 -->
<title>C++ API inference tutorial | Apache MXNet</title>
<meta name="generator" content="Jekyll v4.0.0" />
<meta property="og:title" content="C++ API inference tutorial" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="A flexible and efficient library for deep learning." />
<meta property="og:description" content="A flexible and efficient library for deep learning." />
<link rel="canonical" href="https://mxnet.apache.org/versions/master/api/cpp/docs/tutorials/cpp_inference.html" />
<meta property="og:url" content="https://mxnet.apache.org/versions/master/api/cpp/docs/tutorials/cpp_inference.html" />
<meta property="og:site_name" content="Apache MXNet" />
<script type="application/ld+json">
{"url":"https://mxnet.apache.org/versions/master/api/cpp/docs/tutorials/cpp_inference.html","headline":"C++ API inference tutorial","description":"A flexible and efficient library for deep learning.","@type":"WebPage","@context":"https://schema.org"}</script>
<!-- End Jekyll SEO tag -->
<script src="https://medium-widget.pixelpoint.io/widget.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
<link rel="stylesheet" href="/versions/master/assets/main.css"><link type="application/atom+xml" rel="alternate" href="https://mxnet.apache.org/versions/master/feed.xml" title="Apache MXNet" /><script>
if(!(window.doNotTrack === "1" || navigator.doNotTrack === "1" || navigator.doNotTrack === "yes" || navigator.msDoNotTrack === "1")) {
(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 src="/versions/master/assets/js/jquery-3.3.1.min.js"></script><script src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js" defer></script>
<script src="/versions/master/assets/js/globalSearch.js" defer></script>
<script src="/versions/master/assets/js/clipboard.js" defer></script>
<script src="/versions/master/assets/js/copycode.js" defer></script></head>
<body><header class="site-header" role="banner">
<script>
$(document).ready(function () {
// HEADER OPACITY LOGIC
function opacity_header() {
var value = "rgba(4,140,204," + ($(window).scrollTop() / 300 + 0.4) + ")"
$('.site-header').css("background-color", value)
}
$(window).scroll(function () {
opacity_header()
})
opacity_header();
// MENU SELECTOR LOGIC
$('.page-link').each( function () {
if (window.location.href.includes(this.href)) {
$(this).addClass("page-current");
}
});
})
</script>
<div class="wrapper">
<a class="site-title" rel="author" href="/versions/master/"><img
src="/versions/master/assets/img/mxnet_logo.png" class="site-header-logo"></a>
<nav class="site-nav">
<input type="checkbox" id="nav-trigger" class="nav-trigger"/>
<label for="nav-trigger">
<span class="menu-icon">
<svg viewBox="0 0 18 15" width="18px" height="15px">
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
</svg>
</span>
</label>
<div class="gs-search-border">
<div id="gs-search-icon"></div>
<form id="global-search-form">
<input id="global-search" type="text" title="Search" placeholder="Search" />
<div id="global-search-dropdown-container">
<button class="gs-current-version btn" type="button" data-toggle="dropdown">
<span id="gs-current-version-label">master</span>
<svg class="gs-dropdown-caret" viewBox="0 0 32 32" class="icon icon-caret-bottom" aria-hidden="true">
<path class="dropdown-caret-path" d="M24 11.305l-7.997 11.39L8 11.305z"></path>
</svg>
</button>
<ul class="gs-opt-group gs-version-dropdown">
<li class="gs-opt gs-versions active">master</li>
<li class="gs-opt gs-versions">1.8.0</li>
<li class="gs-opt gs-versions">1.7.0</li>
<li class="gs-opt gs-versions">1.6.0</li>
<li class="gs-opt gs-versions">1.5.0</li>
<li class="gs-opt gs-versions">1.4.1</li>
<li class="gs-opt gs-versions">1.3.1</li>
<li class="gs-opt gs-versions">1.2.1</li>
<li class="gs-opt gs-versions">1.1.0</li>
<li class="gs-opt gs-versions">1.0.0</li>
<li class="gs-opt gs-versions">0.12.1</li>
<li class="gs-opt gs-versions">0.11.0</li>
</ul>
</div>
<span id="global-search-close">x</span>
</form>
</div>
<div class="trigger">
<div id="global-search-mobile-border">
<div id="gs-search-icon-mobile"></div>
<input id="global-search-mobile" placeholder="Search..." type="text"/>
<div id="global-search-dropdown-container-mobile">
<button class="gs-current-version-mobile btn" type="button" data-toggle="dropdown">
<svg class="gs-dropdown-caret" viewBox="0 0 32 32" class="icon icon-caret-bottom" aria-hidden="true">
<path class="dropdown-caret-path" d="M24 11.305l-7.997 11.39L8 11.305z"></path>
</svg>
</button>
<ul class="gs-opt-group gs-version-dropdown-mobile">
<li class="gs-opt gs-versions active">master</li>
<li class="gs-opt gs-versions">1.8.0</li>
<li class="gs-opt gs-versions">1.7.0</li>
<li class="gs-opt gs-versions">1.6.0</li>
<li class="gs-opt gs-versions">1.5.0</li>
<li class="gs-opt gs-versions">1.4.1</li>
<li class="gs-opt gs-versions">1.3.1</li>
<li class="gs-opt gs-versions">1.2.1</li>
<li class="gs-opt gs-versions">1.1.0</li>
<li class="gs-opt gs-versions">1.0.0</li>
<li class="gs-opt gs-versions">0.12.1</li>
<li class="gs-opt gs-versions">0.11.0</li>
</ul>
</div>
</div>
<a class="page-link" href="/versions/master/get_started">Get Started</a>
<a class="page-link" href="/versions/master/blog">Blog</a>
<a class="page-link" href="/versions/master/features">Features</a>
<a class="page-link" href="/versions/master/ecosystem">Ecosystem</a>
<a class="page-link" href="/versions/master/api">Docs & Tutorials</a>
<a class="page-link" href="https://github.com/apache/incubator-mxnet">GitHub</a>
<div class="dropdown">
<span class="dropdown-header">master
<svg class="dropdown-caret" viewBox="0 0 32 32" class="icon icon-caret-bottom" aria-hidden="true"><path class="dropdown-caret-path" d="M24 11.305l-7.997 11.39L8 11.305z"></path></svg>
</span>
<div class="dropdown-content">
<a class="dropdown-option-active" href="/">master</a>
<a href="/versions/1.8.0/">1.8.0</a>
<a href="/versions/1.7.0/">1.7.0</a>
<a href="/versions/1.6.0/">1.6.0</a>
<a href="/versions/1.5.0/">1.5.0</a>
<a href="/versions/1.4.1/">1.4.1</a>
<a href="/versions/1.3.1/">1.3.1</a>
<a href="/versions/1.2.1/">1.2.1</a>
<a href="/versions/1.1.0/">1.1.0</a>
<a href="/versions/1.0.0/">1.0.0</a>
<a href="/versions/0.12.1/">0.12.1</a>
<a href="/versions/0.11.0/">0.11.0</a>
</div>
</div>
</div>
</nav>
</div>
</header>
<main class="page-content" aria-label="Content">
<script>
</script>
<article class="post">
<header class="post-header wrapper">
<h1 class="post-title">C++ API inference tutorial</h1>
<h3></h3><a style="float:left; margin-top:20px" href="/versions/master/get_started" class="btn btn-action">Get Started
<span class="span-accented"></span></a></header>
<div class="post-content">
<div class="wrapper">
<div class="row">
<div class="col-3 docs-side-bar">
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<div class="docs-card docs-side">
<ul>
<div class="docs-action-btn">
<a href="/versions/master/api/cpp.html"> <img src="/versions/master/assets/img/compass.svg"
class="docs-logo-docs">C/C++ Guide <span
class="span-accented"></span></a>
</div>
<div class="docs-action-btn">
<a href="/versions/master/api/cpp/docs/tutorials"> <img
src="/versions/master/assets/img/video-tutorial.svg" class="docs-logo-docs">C/C++
Tutorials <span class="span-accented"></span></a>
</div>
<div class="docs-action-btn">
<a href="/versions/master/api/cpp/docs/api"> <img src="/versions/master/assets/img/api.svg"
class="docs-logo-docs">C/C++ API Reference
<span class="span-accented"></span></a>
</div>
<!-- Let's show the list of tutorials -->
<br>
<h3>Tutorials</h3>
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<li><a href="/versions/master/api/cpp/docs/tutorials/basics.html">Basics</a></li>
<!-- page-category -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<li><a href="/versions/master/api/cpp/docs/tutorials/multi_threaded_inference.html">Multi Threaded Inference</a></li>
<!-- page-category -->
<!-- resource-p -->
<li><a href="/versions/master/api/cpp/docs/tutorials/cpp_inference.html">C++ API inference tutorial</a></li>
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<li><a href="/versions/master/api/cpp/docs/tutorials/subgraph_api.html">Subgraph API</a></li>
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- page-category -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- page -->
</ul>
</div>
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- resource-p -->
<!-- page -->
</ul>
</div>
<div class="col-9">
<!--- 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. -->
<h1 id="c-api-inference-tutorial">C++ API inference tutorial</h1>
<h2 id="overview">Overview</h2>
<p>MXNet provides various useful tools and interfaces for deploying your model for inference. For example, you can use <a href="https://github.com/awslabs/mxnet-model-server">MXNet Model Server</a> to start a service and host your trained model easily.
Besides that, you can also use MXNet’s different language APIs to integrate your model with your existing service. We provide <a href="/api/python/docs/api/">Python</a>, <a href="/api/java/docs/api/#package">Java</a>, <a href="/api/scala/docs/api">Scala</a>, and <a href="/api/cpp/docs/api/">C++</a> APIs.
We will focus on the MXNet C++ API. We have slightly modified the code in <a href="https://github.com/apache/incubator-mxnet/tree/master/cpp-package/example/inference">C++ Inference Example</a> for our use case.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>To complete this tutorial, you need to:</p>
<ul>
<li>Complete the training part of <a href="/api/python/docs/tutorials/getting-started/gluon_from_experiment_to_deployment.html">Gluon end to end tutorial</a>.</li>
<li>Learn the basics about <a href="/api/cpp">MXNet C++ API</a>.</li>
</ul>
<h2 id="setup-the-mxnet-c-api">Setup the MXNet C++ API</h2>
<p>To use the C++ API in MXNet, you need to build MXNet from source with C++ package. Please follow the <a href="/get_started/ubuntu_setup.html">built from source guide</a>, and <a href="/api/cpp">C++ Package documentation</a>.
The summary of those two documents is that you need to build MXNet from source with <code class="highlighter-rouge">USE_CPP_PACKAGE</code> flag set to 1. For example: <code class="highlighter-rouge">make -j USE_CPP_PACKAGE=1</code>.</p>
<h2 id="load-the-model-and-run-inference">Load the model and run inference</h2>
<p>After you complete <a href="/api/python/docs/tutorials/getting-started/gluon_from_experiment_to_deployment.html">the previous tutorial</a>, you will get the following output files:</p>
<ol>
<li>Model Architecture stored in <code class="highlighter-rouge">flower-recognition-symbol.json</code></li>
<li>Model parameter values stored in <code class="highlighter-rouge">flower-recognition-0040.params</code> (<code class="highlighter-rouge">0040</code> is for 40 epochs we ran)</li>
<li>Label names stored in <code class="highlighter-rouge">synset.txt</code></li>
<li>Mean and standard deviation values stored in <code class="highlighter-rouge">mean_std_224</code> for image normalization.</li>
</ol>
<p>Now we need to write the C++ code to load them and run prediction on a test image.
The full code is available in the <a href="https://github.com/apache/incubator-mxnet/tree/master/cpp-package/example/inference">C++ Inference Example</a>, we will walk you through it and point out the necessary changes to make for our use case.</p>
<h3 id="write-a-predictor-using-the-mxnet-c-api">Write a predictor using the MXNet C++ API</h3>
<p>In general, the C++ inference code should follow the 4 steps below. We can do that using a Predictor class.</p>
<ol>
<li>Load the pre-trained model</li>
<li>Load the parameters of pre-trained model</li>
<li>Load the image to be classified in to NDArray and apply image transformation we did in training</li>
<li>Run the forward pass and predict the class of the input image</li>
</ol>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Predictor</span> <span class="p">{</span>
<span class="nl">public:</span>
<span class="n">Predictor</span><span class="p">()</span> <span class="p">{}</span>
<span class="n">Predictor</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">model_json_file</span><span class="p">,</span>
<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">model_params_file</span><span class="p">,</span>
<span class="k">const</span> <span class="n">Shape</span><span class="o">&amp;</span> <span class="n">input_shape</span><span class="p">,</span>
<span class="kt">bool</span> <span class="n">gpu_context_type</span> <span class="o">=</span> <span class="nb">false</span><span class="p">,</span>
<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">synset_file</span> <span class="o">=</span> <span class="s">""</span><span class="p">,</span>
<span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">mean_image_file</span> <span class="o">=</span> <span class="s">""</span><span class="p">);</span>
<span class="kt">void</span> <span class="n">PredictImage</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">image_file</span><span class="p">);</span>
<span class="o">~</span><span class="n">Predictor</span><span class="p">();</span>
<span class="nl">private:</span>
<span class="kt">void</span> <span class="n">LoadModel</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">model_json_file</span><span class="p">);</span>
<span class="kt">void</span> <span class="n">LoadParameters</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">model_parameters_file</span><span class="p">);</span>
<span class="kt">void</span> <span class="n">LoadSynset</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">synset_file</span><span class="p">);</span>
<span class="n">NDArray</span> <span class="n">LoadInputImage</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">image_file</span><span class="p">);</span>
<span class="kt">void</span> <span class="n">LoadMeanImageData</span><span class="p">();</span>
<span class="kt">void</span> <span class="n">LoadDefaultMeanImageData</span><span class="p">();</span>
<span class="kt">void</span> <span class="n">NormalizeInput</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">mean_image_file</span><span class="p">);</span>
<span class="kr">inline</span> <span class="kt">bool</span> <span class="n">FileExists</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">name</span><span class="p">)</span> <span class="p">{</span>
<span class="k">struct</span> <span class="n">stat</span> <span class="n">buffer</span><span class="p">;</span>
<span class="k">return</span> <span class="p">(</span><span class="n">stat</span><span class="p">(</span><span class="n">name</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="o">&amp;</span><span class="n">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">NDArray</span> <span class="n">mean_img</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">NDArray</span><span class="o">&gt;</span> <span class="n">args_map</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">NDArray</span><span class="o">&gt;</span> <span class="n">aux_map</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</span> <span class="n">output_labels</span><span class="p">;</span>
<span class="n">Symbol</span> <span class="n">net</span><span class="p">;</span>
<span class="n">Executor</span> <span class="o">*</span><span class="n">executor</span><span class="p">;</span>
<span class="n">Shape</span> <span class="n">input_shape</span><span class="p">;</span>
<span class="n">NDArray</span> <span class="n">mean_image_data</span><span class="p">;</span>
<span class="n">NDArray</span> <span class="n">std_dev_image_data</span><span class="p">;</span>
<span class="n">Context</span> <span class="n">global_ctx</span> <span class="o">=</span> <span class="n">Context</span><span class="o">::</span><span class="n">cpu</span><span class="p">();</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">mean_image_file</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>
<h3 id="load-the-model-synset-file-and-normalization-values">Load the model, synset file, and normalization values</h3>
<p>In the Predictor constructor, you need to provide paths to saved json and param files. After that, add the following methods <code class="highlighter-rouge">LoadModel</code> and <code class="highlighter-rouge">LoadParameters</code> to load the network and its parameters. This part is the same as <a href="https://github.com/apache/incubator-mxnet/blob/master/cpp-package/example/inference/imagenet_inference.cpp">the example</a>.</p>
<p>Next, we need to load synset file, and normalization values. We have made the following change since our synset file contains flower names and we used both mean and standard deviation for image normalization.</p>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*
* The following function loads the synset file.
* This information will be used later to report the label of input image.
*/</span>
<span class="kt">void</span> <span class="n">Predictor</span><span class="o">::</span><span class="n">LoadSynset</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">synset_file</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">FileExists</span><span class="p">(</span><span class="n">synset_file</span><span class="p">))</span> <span class="p">{</span>
<span class="n">LG</span> <span class="o">&lt;&lt;</span> <span class="s">"Synset file "</span> <span class="o">&lt;&lt;</span> <span class="n">synset_file</span> <span class="o">&lt;&lt;</span> <span class="s">" does not exist"</span><span class="p">;</span>
<span class="k">throw</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span><span class="p">(</span><span class="s">"Synset file does not exist"</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">LG</span> <span class="o">&lt;&lt;</span> <span class="s">"Loading the synset file."</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">ifstream</span> <span class="n">fi</span><span class="p">(</span><span class="n">synset_file</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">fi</span><span class="p">.</span><span class="n">is_open</span><span class="p">())</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cerr</span> <span class="o">&lt;&lt;</span> <span class="s">"Error opening synset file "</span> <span class="o">&lt;&lt;</span> <span class="n">synset_file</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="k">throw</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span><span class="p">(</span><span class="s">"Error in opening the synset file."</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">lemma</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="n">getline</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">lemma</span><span class="p">))</span> <span class="p">{</span>
<span class="n">output_labels</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">lemma</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">fi</span><span class="p">.</span><span class="n">close</span><span class="p">();</span>
<span class="p">}</span>
<span class="cm">/*
* The following function loads the mean and standard deviation values.
* This data will be used for normalizing the image before running the forward
* pass.
* The output data has the same shape as that of the input image data.
*/</span>
<span class="kt">void</span> <span class="n">Predictor</span><span class="o">::</span><span class="n">LoadMeanImageData</span><span class="p">()</span> <span class="p">{</span>
<span class="n">LG</span> <span class="o">&lt;&lt;</span> <span class="s">"Load the mean image data that will be used to normalize "</span>
<span class="o">&lt;&lt;</span> <span class="s">"the image before running forward pass."</span><span class="p">;</span>
<span class="n">mean_image_data</span> <span class="o">=</span> <span class="n">NDArray</span><span class="p">(</span><span class="n">input_shape</span><span class="p">,</span> <span class="n">global_ctx</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
<span class="n">mean_image_data</span><span class="p">.</span><span class="n">SyncCopyFromCPU</span><span class="p">(</span>
<span class="n">NDArray</span><span class="o">::</span><span class="n">LoadToMap</span><span class="p">(</span><span class="n">mean_image_file</span><span class="p">)[</span><span class="s">"mean_img"</span><span class="p">].</span><span class="n">GetData</span><span class="p">(),</span>
<span class="n">input_shape</span><span class="p">.</span><span class="n">Size</span><span class="p">());</span>
<span class="n">NDArray</span><span class="o">::</span><span class="n">WaitAll</span><span class="p">();</span>
<span class="n">std_dev_image_data</span> <span class="o">=</span> <span class="n">NDArray</span><span class="p">(</span><span class="n">input_shape</span><span class="p">,</span> <span class="n">global_ctx</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
<span class="n">std_dev_image_data</span><span class="p">.</span><span class="n">SyncCopyFromCPU</span><span class="p">(</span>
<span class="n">NDArray</span><span class="o">::</span><span class="n">LoadToMap</span><span class="p">(</span><span class="n">mean_image_file</span><span class="p">)[</span><span class="s">"std_img"</span><span class="p">].</span><span class="n">GetData</span><span class="p">(),</span>
<span class="n">input_shape</span><span class="p">.</span><span class="n">Size</span><span class="p">());</span>
<span class="n">NDArray</span><span class="o">::</span><span class="n">WaitAll</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="load-input-image">Load input image</h3>
<p>Now let’s add a method to load the input image we want to predict and converts it to NDArray for prediction.</p>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">NDArray</span> <span class="n">Predictor</span><span class="o">::</span><span class="n">LoadInputImage</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">image_file</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">FileExists</span><span class="p">(</span><span class="n">image_file</span><span class="p">))</span> <span class="p">{</span>
<span class="n">LG</span> <span class="o">&lt;&lt;</span> <span class="s">"Image file "</span> <span class="o">&lt;&lt;</span> <span class="n">image_file</span> <span class="o">&lt;&lt;</span> <span class="s">" does not exist"</span><span class="p">;</span>
<span class="k">throw</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span><span class="p">(</span><span class="s">"Image file does not exist"</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">LG</span> <span class="o">&lt;&lt;</span> <span class="s">"Loading the image "</span> <span class="o">&lt;&lt;</span> <span class="n">image_file</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span> <span class="n">array</span><span class="p">;</span>
<span class="n">cv</span><span class="o">::</span><span class="n">Mat</span> <span class="n">mat</span> <span class="o">=</span> <span class="n">cv</span><span class="o">::</span><span class="n">imread</span><span class="p">(</span><span class="n">image_file</span><span class="p">);</span>
<span class="cm">/*resize pictures to (224, 224) according to the pretrained model*/</span>
<span class="kt">int</span> <span class="n">height</span> <span class="o">=</span> <span class="n">input_shape</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="kt">int</span> <span class="n">width</span> <span class="o">=</span> <span class="n">input_shape</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
<span class="kt">int</span> <span class="n">channels</span> <span class="o">=</span> <span class="n">input_shape</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="n">cv</span><span class="o">::</span><span class="n">resize</span><span class="p">(</span><span class="n">mat</span><span class="p">,</span> <span class="n">mat</span><span class="p">,</span> <span class="n">cv</span><span class="o">::</span><span class="n">Size</span><span class="p">(</span><span class="n">height</span><span class="p">,</span> <span class="n">width</span><span class="p">));</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">c</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">c</span> <span class="o">&lt;</span> <span class="n">channels</span><span class="p">;</span> <span class="o">++</span><span class="n">c</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">height</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">width</span><span class="p">;</span> <span class="o">++</span><span class="n">j</span><span class="p">)</span> <span class="p">{</span>
<span class="n">array</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span><span class="p">(</span><span class="n">mat</span><span class="p">.</span><span class="n">data</span><span class="p">[(</span><span class="n">i</span> <span class="o">*</span> <span class="n">height</span> <span class="o">+</span> <span class="n">j</span><span class="p">)</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">c</span><span class="p">]));</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">NDArray</span> <span class="n">image_data</span> <span class="o">=</span> <span class="n">NDArray</span><span class="p">(</span><span class="n">input_shape</span><span class="p">,</span> <span class="n">global_ctx</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
<span class="n">image_data</span><span class="p">.</span><span class="n">SyncCopyFromCPU</span><span class="p">(</span><span class="n">array</span><span class="p">.</span><span class="n">data</span><span class="p">(),</span> <span class="n">input_shape</span><span class="p">.</span><span class="n">Size</span><span class="p">());</span>
<span class="n">NDArray</span><span class="o">::</span><span class="n">WaitAll</span><span class="p">();</span>
<span class="k">return</span> <span class="n">image_data</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="predict-the-image">Predict the image</h3>
<p>Finally, let’s run the inference. It’s basically using MXNet executor to do a forward pass. To run predictions on multiple images, you can load the images in a list of NDArrays and run prediction in batches. Note that the Predictor class may not be thread safe. Calling it in multi-threaded environments was not tested. To utilize multi-threaded prediction, you need to use the C predict API. Please follow the <a href="https://github.com/apache/incubator-mxnet/tree/master/example/image-classification/predict-cpp">C predict example</a>.</p>
<p>An additional step is to normalize the image NDArrays values to <code class="highlighter-rouge">(0, 1)</code> and apply mean and standard deviation we just loaded.</p>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*
* The following function runs the forward pass on the model.
* The executor is created in the constructor.
*
*/</span>
<span class="kt">void</span> <span class="n">Predictor</span><span class="o">::</span><span class="n">PredictImage</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">image_file</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Load the input image</span>
<span class="n">NDArray</span> <span class="n">image_data</span> <span class="o">=</span> <span class="n">LoadInputImage</span><span class="p">(</span><span class="n">image_file</span><span class="p">);</span>
<span class="c1">// Normalize the image</span>
<span class="n">image_data</span><span class="p">.</span><span class="n">Slice</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="o">/=</span> <span class="mf">255.0</span><span class="p">;</span>
<span class="n">image_data</span> <span class="o">-=</span> <span class="n">mean_image_data</span><span class="p">;</span>
<span class="n">image_data</span> <span class="o">/=</span> <span class="n">std_dev_image_data</span><span class="p">;</span>
<span class="n">LG</span> <span class="o">&lt;&lt;</span> <span class="s">"Running the forward pass on model to predict the image"</span><span class="p">;</span>
<span class="cm">/*
* The executor-&gt;arg_arrays represent the arguments to the model.
*
* Copying the image_data that contains the NDArray of input image
* to the arg map of the executor. The input is stored with the key "data" in the map.
*
*/</span>
<span class="n">image_data</span><span class="p">.</span><span class="n">CopyTo</span><span class="p">(</span><span class="o">&amp;</span><span class="p">(</span><span class="n">executor</span><span class="o">-&gt;</span><span class="n">arg_dict</span><span class="p">()[</span><span class="s">"data"</span><span class="p">]));</span>
<span class="n">NDArray</span><span class="o">::</span><span class="n">WaitAll</span><span class="p">();</span>
<span class="c1">// Run the forward pass.</span>
<span class="n">executor</span><span class="o">-&gt;</span><span class="n">Forward</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span>
<span class="c1">// The output is available in executor-&gt;outputs.</span>
<span class="k">auto</span> <span class="n">array</span> <span class="o">=</span> <span class="n">executor</span><span class="o">-&gt;</span><span class="n">outputs</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Copy</span><span class="p">(</span><span class="n">global_ctx</span><span class="p">);</span>
<span class="n">NDArray</span><span class="o">::</span><span class="n">WaitAll</span><span class="p">();</span>
<span class="cm">/*
* Find out the maximum accuracy and the index associated with that accuracy.
* This is done by using the argmax operator on NDArray.
*/</span>
<span class="k">auto</span> <span class="n">predicted</span> <span class="o">=</span> <span class="n">array</span><span class="p">.</span><span class="n">ArgmaxChannel</span><span class="p">();</span>
<span class="n">NDArray</span><span class="o">::</span><span class="n">WaitAll</span><span class="p">();</span>
<span class="kt">int</span> <span class="n">best_idx</span> <span class="o">=</span> <span class="n">predicted</span><span class="p">.</span><span class="n">At</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="kt">float</span> <span class="n">best_accuracy</span> <span class="o">=</span> <span class="n">array</span><span class="p">.</span><span class="n">At</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">best_idx</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">output_labels</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span> <span class="p">{</span>
<span class="n">LG</span> <span class="o">&lt;&lt;</span> <span class="s">"The model predicts the highest accuracy of "</span> <span class="o">&lt;&lt;</span> <span class="n">best_accuracy</span> <span class="o">&lt;&lt;</span> <span class="s">" at index "</span>
<span class="o">&lt;&lt;</span> <span class="n">best_idx</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">LG</span> <span class="o">&lt;&lt;</span> <span class="s">"The model predicts the input image to be a ["</span> <span class="o">&lt;&lt;</span> <span class="n">output_labels</span><span class="p">[</span><span class="n">best_idx</span><span class="p">]</span>
<span class="o">&lt;&lt;</span> <span class="s">" ] with Accuracy = "</span> <span class="o">&lt;&lt;</span> <span class="n">best_accuracy</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="compile-and-run-the-inference-code">Compile and run the inference code</h3>
<p>You can find the <a href="https://github.com/apache/incubator-mxnet/tree/master/cpp-package/example/inference">full code for the inference example</a> in the <code class="highlighter-rouge">cpp-package</code> folder of the project
, and to compile it use this <a href="https://github.com/apache/incubator-mxnet/blob/master/cpp-package/example/inference/Makefile">Makefile</a>.</p>
<p>Make a copy of the example code, rename it to <code class="highlighter-rouge">flower_inference</code> and apply the changes we mentioned above. Now you will be able to compile and run inference. Run <code class="highlighter-rouge">make all</code>. Once this is complete, run inference with the following parameters. Remember to set your <code class="highlighter-rouge">LD_LIBRARY_PATH</code> to point to MXNet library if you have not done so.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make all
<span class="nb">export </span><span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span><span class="nv">$LD_LIBRARY_PATH</span><span class="o">=</span>:path/to/incubator-mxnet/lib
./flower_inference <span class="nt">--symbol</span> flower-recognition-symbol.json <span class="nt">--params</span> flower-recognition-0040.params <span class="nt">--synset</span> synset.txt <span class="nt">--mean</span> mean_std_224.nd <span class="nt">--image</span> ./data/test/lotus/image_01832.jpg
</code></pre></div></div>
<p>Then it will predict your image:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>17:38:51] resnet.cpp:150: Loading the model from flower-recognition-symbol.json
<span class="o">[</span>17:38:51] resnet.cpp:163: Loading the model parameters from flower-recognition-0040.params
<span class="o">[</span>17:38:52] resnet.cpp:190: Loading the synset file.
<span class="o">[</span>17:38:52] resnet.cpp:211: Load the mean image data that will be used to normalize the image before running forward pass.
<span class="o">[</span>17:38:52] resnet.cpp:263: Loading the image ./data/test/lotus/image_01832.jpg
<span class="o">[</span>17:38:52] resnet.cpp:299: Running the forward pass on model to predict the image
<span class="o">[</span>17:38:52] resnet.cpp:331: The model predicts the input image to be a <span class="o">[</span>lotus <span class="o">]</span> with Accuracy <span class="o">=</span> 8.63046
</code></pre></div></div>
<h2 id="whats-next">What’s next</h2>
<p>Now you can explore more ways to run inference and deploy your models:</p>
<ol>
<li><a href="https://github.com/apache/incubator-mxnet/tree/master/scala-package/examples/src/main/java/org/apache/mxnetexamples/javaapi/infer">Java Inference examples</a></li>
<li><a href="https://github.com/apache/incubator-mxnet/tree/master/scala-package/examples/src/main/scala/org/apache/mxnetexamples/infer">Scala Inference examples</a></li>
<li><a href="/api/python/docs/tutorials/packages/onnx/inference_on_onnx_model.html">ONNX model inference examples</a></li>
<li><a href="https://github.com/awslabs/mxnet-model-server/tree/master/examples">MXNet Model Server Examples</a></li>
</ol>
<h2 id="references">References</h2>
<ol>
<li><a href="/api/python/docs/tutorials/getting-started/gluon_from_experiment_to_deployment.html">Gluon end to end tutorial</a></li>
<li><a href="https://github.com/apache/incubator-mxnet/blob/master/cpp-package/example/inference/">Gluon C++ inference example</a></li>
<li><a href="https://github.com/apache/incubator-mxnet/tree/master/cpp-package">Gluon C++ package</a></li>
</ol>
</div>
</div>
</div>
</div>
</article>
</main><footer class="site-footer h-card">
<div class="wrapper">
<div class="row">
<div class="col-4">
<h4 class="footer-category-title">Resources</h4>
<ul class="contact-list">
<li><a href="/versions/master/community#stay-connected">Mailing lists</a></li>
<li><a href="https://discuss.mxnet.io">MXNet Discuss forum</a></li>
<li><a href="/versions/master/community#github-issues">Github Issues</a></li>
<li><a href="https://github.com/apache/incubator-mxnet/projects">Projects</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/MXNET/Apache+MXNet+Home">Developer Wiki</a></li>
<li><a href="/versions/master/community">Contribute To MXNet</a></li>
</ul>
</div>
<div class="col-4"><ul class="social-media-list"><li><a href="https://github.com/apache/incubator-mxnet"><svg class="svg-icon"><use xlink:href="/versions/master/assets/minima-social-icons.svg#github"></use></svg> <span class="username">apache/incubator-mxnet</span></a></li><li><a href="https://www.twitter.com/apachemxnet"><svg class="svg-icon"><use xlink:href="/versions/master/assets/minima-social-icons.svg#twitter"></use></svg> <span class="username">apachemxnet</span></a></li><li><a href="https://youtube.com/apachemxnet"><svg class="svg-icon"><use xlink:href="/versions/master/assets/minima-social-icons.svg#youtube"></use></svg> <span class="username">apachemxnet</span></a></li></ul>
</div>
<div class="col-4 footer-text">
<p>A flexible and efficient library for deep learning.</p>
</div>
</div>
</div>
</footer>
<footer class="site-footer2">
<div class="wrapper">
<div class="row">
<div class="col-3">
<img src="/versions/master/assets/img/apache_incubator_logo.png" class="footer-logo col-2">
</div>
<div class="footer-bottom-warning col-9">
<p>Apache MXNet is an effort undergoing incubation at The Apache Software Foundation (ASF), <span
style="font-weight:bold">sponsored by the <i>Apache Incubator</i></span>. 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>
</footer>
</body>
</html>