You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by se...@apache.org on 2018/08/08 16:38:42 UTC

[incubator-mxnet] branch master updated: MXNET-776 [Perl] Better documentation/bug fixes. (#12038)

This is an automated email from the ASF dual-hosted git repository.

sergeykolychev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git


The following commit(s) were added to refs/heads/master by this push:
     new 5bf77bb  MXNET-776 [Perl] Better documentation/bug fixes. (#12038)
5bf77bb is described below

commit 5bf77bbe9e1c1f8bb6529b8207000f25f10c41a8
Author: Sergey Kolychev <se...@gmail.com>
AuthorDate: Wed Aug 8 09:38:32 2018 -0700

    MXNET-776 [Perl] Better documentation/bug fixes. (#12038)
    
    * MXNET-776
    1) Several new metric classes.
    2) Improved documentation.
    3) Bugfixes.
    
    * added links and fixed a typo.
---
 docs/tutorials/index.md                            |  11 +
 perl-package/AI-MXNet-Gluon-Contrib/Changes        |   6 +
 perl-package/AI-MXNet-Gluon-Contrib/META.json      |   2 +-
 perl-package/AI-MXNet-Gluon-Contrib/META.yml       |   2 +-
 perl-package/AI-MXNet-Gluon-Contrib/Makefile.PL    |   2 +-
 perl-package/AI-MXNet-Gluon-Contrib/README         |   2 +-
 .../lib/AI/MXNet/Gluon/Contrib.pm                  |   7 +-
 .../lib/AI/MXNet/Gluon/Contrib/NN/BasicLayers.pm   |   7 +
 perl-package/AI-MXNet-Gluon-ModelZoo/Changes       |   3 +
 perl-package/AI-MXNet-Gluon-ModelZoo/META.json     |   2 +-
 perl-package/AI-MXNet-Gluon-ModelZoo/META.yml      |   2 +-
 perl-package/AI-MXNet-Gluon-ModelZoo/Makefile.PL   |   2 +-
 perl-package/AI-MXNet-Gluon-ModelZoo/README        |   2 +-
 .../lib/AI/MXNet/Gluon/ModelZoo.pm                 |   2 +-
 .../lib/AI/MXNet/Gluon/ModelZoo/ModelStore.pm      |   8 +-
 perl-package/AI-MXNet/Changes                      |   6 +
 perl-package/AI-MXNet/META.json                    |   4 +-
 perl-package/AI-MXNet/META.yml                     |   4 +-
 perl-package/AI-MXNet/Makefile.PL                  |   2 +-
 perl-package/AI-MXNet/README                       |   2 +-
 perl-package/AI-MXNet/lib/AI/MXNet.pm              | 107 ++++-
 perl-package/AI-MXNet/lib/AI/MXNet/AutoGrad.pm     |  80 ++--
 perl-package/AI-MXNet/lib/AI/MXNet/Base.pm         |   2 +-
 perl-package/AI-MXNet/lib/AI/MXNet/CachedOp.pm     |   5 +
 perl-package/AI-MXNet/lib/AI/MXNet/Callback.pm     |  37 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Context.pm      |   7 +
 perl-package/AI-MXNet/lib/AI/MXNet/Contrib.pm      |  26 ++
 .../AI-MXNet/lib/AI/MXNet/Contrib/NDArray.pm       |  10 +
 .../AI-MXNet/lib/AI/MXNet/Contrib/Symbol.pm        |  26 ++
 perl-package/AI-MXNet/lib/AI/MXNet/CudaModule.pm   |  23 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Engine.pm       |  21 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Executor.pm     |  44 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Gluon.pm        | 102 +++++
 perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Block.pm  |  44 +-
 .../AI-MXNet/lib/AI/MXNet/Gluon/Parameter.pm       |   3 +-
 perl-package/AI-MXNet/lib/AI/MXNet/IO.pm           |  25 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Image.pm        |  24 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Initializer.pm  |  20 +-
 perl-package/AI-MXNet/lib/AI/MXNet/KVStore.pm      |  68 ++-
 .../AI-MXNet/lib/AI/MXNet/KVStoreServer.pm         |   4 +-
 perl-package/AI-MXNet/lib/AI/MXNet/LRScheduler.pm  |  10 +-
 perl-package/AI-MXNet/lib/AI/MXNet/LinAlg.pm       |  48 +++
 perl-package/AI-MXNet/lib/AI/MXNet/Metric.pm       | 472 ++++++++++++++++++---
 perl-package/AI-MXNet/lib/AI/MXNet/Module.pm       |  38 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Monitor.pm      |   8 +-
 perl-package/AI-MXNet/lib/AI/MXNet/NDArray.pm      |  64 +--
 .../AI-MXNet/lib/AI/MXNet/NDArray/Sparse.pm        |   3 -
 perl-package/AI-MXNet/lib/AI/MXNet/Optimizer.pm    | 162 ++++---
 perl-package/AI-MXNet/lib/AI/MXNet/RNN/Cell.pm     |   2 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Symbol.pm       |   7 +-
 perl-package/AI-MXNet/lib/AI/MXNet/Symbol/Base.pm  |   2 +-
 .../AI-MXNet/lib/AI/MXNet/Symbol/NameManager.pm    |   6 +-
 perl-package/AI-MXNet/t/test_gluon.t               |   2 +-
 perl-package/AI-MXNetCAPI/Changes                  |   3 +
 perl-package/AI-MXNetCAPI/META.json                |   2 +-
 perl-package/AI-MXNetCAPI/META.yml                 |   2 +-
 perl-package/AI-MXNetCAPI/README                   |   2 +-
 perl-package/AI-MXNetCAPI/lib/AI/MXNetCAPI.pm      |   2 +-
 perl-package/AI-MXNetCAPI/mxnet_typemaps.i         |   2 +-
 59 files changed, 1211 insertions(+), 382 deletions(-)

diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md
index 57bfec7..ae08514 100644
--- a/docs/tutorials/index.md
+++ b/docs/tutorials/index.md
@@ -154,6 +154,17 @@ Select API:&nbsp;
 
 <hr>
 
+## Perl Tutorials
+
+* Getting Started
+    * [Machine learning in Perl](http://blogs.perl.org/users/sergey_kolychev/2017/02/machine-learning-in-perl.html)
+    * [Calculator and Robo-Shakespeare](http://blogs.perl.org/users/sergey_kolychev/2017/04/machine-learning-in-perl-part2-a-calculator-handwritten-digits-and-roboshakespeare.html)
+* Gluon
+    * [DCGAN](http://blogs.perl.org/users/sergey_kolychev/2017/10/machine-learning-in-perl-part3-deep-convolutional-generative-adversarial-network.html)
+    * [Image classification and Style transfer](http://blogs.perl.org/users/sergey_kolychev/2018/07/machine-learning-in-perl-kyuubi-goes-to-a-modelzoo-during-the-starry-night.html)
+
+<hr>
+
 ## Contributing Tutorials
 
 We really appreciate contributions, and tutorials are a great way to share your knowledge and help the community. After you have followed [these steps](https://github.com/apache/incubator-mxnet/tree/master/example#contributing), please submit a pull request on Github.
diff --git a/perl-package/AI-MXNet-Gluon-Contrib/Changes b/perl-package/AI-MXNet-Gluon-Contrib/Changes
index 7b3b27a..81e55aa 100644
--- a/perl-package/AI-MXNet-Gluon-Contrib/Changes
+++ b/perl-package/AI-MXNet-Gluon-Contrib/Changes
@@ -1,5 +1,11 @@
 Revision history for Perl extension AI::MXNet::Gluon::Contrib
 
+1.32    Sun Jul 15 12:12:15 PDT 2018
+        - Missing POD fixes.
+
+1.31    Sat Jul 14 08:33:21 PDT 2018
+        - Fixed CPAN indexing issue.
+
 1.3     Tue Jul 10 21:19:13 PDT 2018
         - Initial release
 
diff --git a/perl-package/AI-MXNet-Gluon-Contrib/META.json b/perl-package/AI-MXNet-Gluon-Contrib/META.json
index 52c3230..ec65bb0 100644
--- a/perl-package/AI-MXNet-Gluon-Contrib/META.json
+++ b/perl-package/AI-MXNet-Gluon-Contrib/META.json
@@ -38,5 +38,5 @@
       }
    },
    "release_status" : "stable",
-   "version" : "1.3"
+   "version" : "1.32"
 }
diff --git a/perl-package/AI-MXNet-Gluon-Contrib/META.yml b/perl-package/AI-MXNet-Gluon-Contrib/META.yml
index b059f0f..aaa194d 100644
--- a/perl-package/AI-MXNet-Gluon-Contrib/META.yml
+++ b/perl-package/AI-MXNet-Gluon-Contrib/META.yml
@@ -18,4 +18,4 @@ no_index:
     - inc
 requires:
   AI::MXNet: '1.31'
-version: '1.3'
+version: '1.32'
diff --git a/perl-package/AI-MXNet-Gluon-Contrib/Makefile.PL b/perl-package/AI-MXNet-Gluon-Contrib/Makefile.PL
index b27d59b..6c58d6e 100644
--- a/perl-package/AI-MXNet-Gluon-Contrib/Makefile.PL
+++ b/perl-package/AI-MXNet-Gluon-Contrib/Makefile.PL
@@ -39,7 +39,7 @@ my %WriteMakefileArgs = (
     "AI::MXNet" => "1.31",
   },
   "TEST_REQUIRES" => {},
-  "VERSION" => "1.3",
+  "VERSION" => "1.32",
   "test" => {
     "TESTS" => "t/*.t"
   }
diff --git a/perl-package/AI-MXNet-Gluon-Contrib/README b/perl-package/AI-MXNet-Gluon-Contrib/README
index 1481c3e..6c0efcc 100644
--- a/perl-package/AI-MXNet-Gluon-Contrib/README
+++ b/perl-package/AI-MXNet-Gluon-Contrib/README
@@ -1,5 +1,5 @@
 This archive contains the distribution AI-MXNet-Gluon-Contrib,
-version 1.3:
+version 1.32:
 
   Perl interface to MXNet Gluon Contib modules, a collection of supplemental Gluon blocks.
 
diff --git a/perl-package/AI-MXNet-Gluon-Contrib/lib/AI/MXNet/Gluon/Contrib.pm b/perl-package/AI-MXNet-Gluon-Contrib/lib/AI/MXNet/Gluon/Contrib.pm
index f88fb8a..029bc4b 100644
--- a/perl-package/AI-MXNet-Gluon-Contrib/lib/AI/MXNet/Gluon/Contrib.pm
+++ b/perl-package/AI-MXNet-Gluon-Contrib/lib/AI/MXNet/Gluon/Contrib.pm
@@ -15,10 +15,15 @@
 # specific language governing permissions and limitations
 # under the License.
 
+package AI::MXNet::Gluon::Contrib;
 use strict;
 use warnings;
 use AI::MXNet;
 use AI::MXNet::Gluon::Contrib::NN::BasicLayers;
-our $VERSION = '1.3';
+our $VERSION = '1.32';
+=head1 NAME 
+
+    AI::MXNet::Gluon::Contrib - A collection of supplemental Gluon blocks.
+=cut
 
 1;
\ No newline at end of file
diff --git a/perl-package/AI-MXNet-Gluon-Contrib/lib/AI/MXNet/Gluon/Contrib/NN/BasicLayers.pm b/perl-package/AI-MXNet-Gluon-Contrib/lib/AI/MXNet/Gluon/Contrib/NN/BasicLayers.pm
index 455284e..5f57e03 100644
--- a/perl-package/AI-MXNet-Gluon-Contrib/lib/AI/MXNet/Gluon/Contrib/NN/BasicLayers.pm
+++ b/perl-package/AI-MXNet-Gluon-Contrib/lib/AI/MXNet/Gluon/Contrib/NN/BasicLayers.pm
@@ -17,6 +17,13 @@
 
 use strict;
 use warnings;
+package AI::MXNet::Gluon::Contrib::NN::BasicLayers;
+
+=head1 NAME 
+
+    AI::MXNet::Gluon::Contrib::NN::BasicLayers - An additional collection of Gluon's building blocks.
+=cut
+
 use AI::MXNet::Function::Parameters;
 package AI::MXNet::Gluon::NN::Concurrent;
 use AI::MXNet::Gluon::Mouse;
diff --git a/perl-package/AI-MXNet-Gluon-ModelZoo/Changes b/perl-package/AI-MXNet-Gluon-ModelZoo/Changes
index c233f92..377dff5 100644
--- a/perl-package/AI-MXNet-Gluon-ModelZoo/Changes
+++ b/perl-package/AI-MXNet-Gluon-ModelZoo/Changes
@@ -1,5 +1,8 @@
 Revision history for Perl extension AI::MXNet::Gluon::ModelZoo
 
+1.32    Sun Aug  5 14:25:31 PDT 2018
+        - Updated vgg16/19 models
+
 1.3     Tue Jul 10 21:19:13 PDT 2018
         - Initial release
 
diff --git a/perl-package/AI-MXNet-Gluon-ModelZoo/META.json b/perl-package/AI-MXNet-Gluon-ModelZoo/META.json
index c0e1ad3..9ea969e 100644
--- a/perl-package/AI-MXNet-Gluon-ModelZoo/META.json
+++ b/perl-package/AI-MXNet-Gluon-ModelZoo/META.json
@@ -39,5 +39,5 @@
       }
    },
    "release_status" : "stable",
-   "version" : "1.3"
+   "version" : "1.32"
 }
diff --git a/perl-package/AI-MXNet-Gluon-ModelZoo/META.yml b/perl-package/AI-MXNet-Gluon-ModelZoo/META.yml
index 2493af6..a04484a 100644
--- a/perl-package/AI-MXNet-Gluon-ModelZoo/META.yml
+++ b/perl-package/AI-MXNet-Gluon-ModelZoo/META.yml
@@ -19,4 +19,4 @@ no_index:
 requires:
   AI::MXNet: '1.31'
   AI::MXNet::Gluon::Contrib: '1.3'
-version: '1.3'
+version: '1.32'
diff --git a/perl-package/AI-MXNet-Gluon-ModelZoo/Makefile.PL b/perl-package/AI-MXNet-Gluon-ModelZoo/Makefile.PL
index 8427aef..d15dfce 100644
--- a/perl-package/AI-MXNet-Gluon-ModelZoo/Makefile.PL
+++ b/perl-package/AI-MXNet-Gluon-ModelZoo/Makefile.PL
@@ -40,7 +40,7 @@ my %WriteMakefileArgs = (
     "AI::MXNet::Gluon::Contrib" => "1.3"
   },
   "TEST_REQUIRES" => {},
-  "VERSION" => "1.3",
+  "VERSION" => "1.32",
   "test" => {
     "TESTS" => "t/*.t"
   }
diff --git a/perl-package/AI-MXNet-Gluon-ModelZoo/README b/perl-package/AI-MXNet-Gluon-ModelZoo/README
index d6d6972..6b8e04b 100644
--- a/perl-package/AI-MXNet-Gluon-ModelZoo/README
+++ b/perl-package/AI-MXNet-Gluon-ModelZoo/README
@@ -1,5 +1,5 @@
 This archive contains the distribution AI-MXNet-Gluon-ModelZoo,
-version 1.3:
+version 1.32:
 
   Perl interface to MXNet Gluon ModelZoo, a collection of pretrained machine learning models for computer vision.
 
diff --git a/perl-package/AI-MXNet-Gluon-ModelZoo/lib/AI/MXNet/Gluon/ModelZoo.pm b/perl-package/AI-MXNet-Gluon-ModelZoo/lib/AI/MXNet/Gluon/ModelZoo.pm
index 64ccd46..c9e6e77 100644
--- a/perl-package/AI-MXNet-Gluon-ModelZoo/lib/AI/MXNet/Gluon/ModelZoo.pm
+++ b/perl-package/AI-MXNet-Gluon-ModelZoo/lib/AI/MXNet/Gluon/ModelZoo.pm
@@ -26,7 +26,7 @@ use AI::MXNet::Gluon::ModelZoo::Vision;
 use Exporter;
 use base qw(Exporter);
 @AI::MXNet::Gluon::ModelZoo::EXPORT_OK = qw(get_model);
-our $VERSION = '1.3';
+our $VERSION = '1.32';
 
 =head1 NAME
 
diff --git a/perl-package/AI-MXNet-Gluon-ModelZoo/lib/AI/MXNet/Gluon/ModelZoo/ModelStore.pm b/perl-package/AI-MXNet-Gluon-ModelZoo/lib/AI/MXNet/Gluon/ModelZoo/ModelStore.pm
index 9269ee7..bb258b4 100644
--- a/perl-package/AI-MXNet-Gluon-ModelZoo/lib/AI/MXNet/Gluon/ModelZoo/ModelStore.pm
+++ b/perl-package/AI-MXNet-Gluon-ModelZoo/lib/AI/MXNet/Gluon/ModelZoo/ModelStore.pm
@@ -60,10 +60,10 @@ my %_model_sha1 = map { $_->[1] => $_->[0] } (
     ['ee79a8098a91fbe05b7a973fed2017a6117723a8', 'vgg11_bn'],
     ['6bc5de58a05a5e2e7f493e2d75a580d83efde38c', 'vgg13'],
     ['7d97a06c3c7a1aecc88b6e7385c2b373a249e95e', 'vgg13_bn'],
-    ['649467530119c0f78c4859999e264e7bf14471a9', 'vgg16'],
-    ['6b9dbe6194e5bfed30fd7a7c9a71f7e5a276cb14', 'vgg16_bn'],
-    ['f713436691eee9a20d70a145ce0d53ed24bf7399', 'vgg19'],
-    ['9730961c9cea43fd7eeefb00d792e386c45847d6', 'vgg19_bn']
+    ['e660d4569ccb679ec68f1fd3cce07a387252a90a', 'vgg16'],
+    ['7f01cf050d357127a73826045c245041b0df7363', 'vgg16_bn'],
+    ['ad2f660d101905472b83590b59708b71ea22b2e5', 'vgg19'],
+    ['f360b758e856f1074a85abd5fd873ed1d98297c3', 'vgg19_bn']
 );
 
 my $apache_repo_url = 'http://apache-mxnet.s3-accelerate.dualstack.amazonaws.com/';
diff --git a/perl-package/AI-MXNet/Changes b/perl-package/AI-MXNet/Changes
index b522759..8b9463e 100644
--- a/perl-package/AI-MXNet/Changes
+++ b/perl-package/AI-MXNet/Changes
@@ -1,4 +1,10 @@
 Revision history for Perl extension AI::MXNet
+
+1.32    Sun Aug  5 14:25:31 PDT 2018
+        - Several new metric classes
+        - Expanded documentation
+        - Bugfixes.
+
 1.31    Tue Jul 10 21:19:13 PDT 2018
         - Memory leak fix for Gluon API
         - Added summary function for Gluon models
diff --git a/perl-package/AI-MXNet/META.json b/perl-package/AI-MXNet/META.json
index a43f77d..7d0ab96 100644
--- a/perl-package/AI-MXNet/META.json
+++ b/perl-package/AI-MXNet/META.json
@@ -30,7 +30,7 @@
       },
       "runtime" : {
          "requires" : {
-            "AI::MXNetCAPI" : "1.3",
+            "AI::MXNetCAPI" : "1.32",
             "AI::NNVMCAPI" : "1.3",
             "Function::Parameters" : "1.0705",
             "Hash::Ordered" : "0.012",
@@ -45,5 +45,5 @@
       }
    },
    "release_status" : "stable",
-   "version" : "1.31"
+   "version" : "1.32"
 }
diff --git a/perl-package/AI-MXNet/META.yml b/perl-package/AI-MXNet/META.yml
index 642f370..ee5d677 100644
--- a/perl-package/AI-MXNet/META.yml
+++ b/perl-package/AI-MXNet/META.yml
@@ -17,7 +17,7 @@ no_index:
     - t
     - inc
 requires:
-  AI::MXNetCAPI: '1.3'
+  AI::MXNetCAPI: '1.32'
   AI::NNVMCAPI: '1.3'
   Function::Parameters: '1.0705'
   Hash::Ordered: '0.012'
@@ -25,4 +25,4 @@ requires:
   Mouse: v2.1.0
   PDL: '2.007'
   PDL::CCS: '1.23.4'
-version: '1.31'
+version: '1.32'
diff --git a/perl-package/AI-MXNet/Makefile.PL b/perl-package/AI-MXNet/Makefile.PL
index f8f0d9c..59036d9 100644
--- a/perl-package/AI-MXNet/Makefile.PL
+++ b/perl-package/AI-MXNet/Makefile.PL
@@ -46,7 +46,7 @@ my %WriteMakefileArgs = (
     "GraphViz" => "2.14"
   },
   "TEST_REQUIRES" => {},
-  "VERSION" => "1.31",
+  "VERSION" => "1.32",
   "test" => {
     "TESTS" => "t/*.t"
   }
diff --git a/perl-package/AI-MXNet/README b/perl-package/AI-MXNet/README
index e34970a..2f1010a 100644
--- a/perl-package/AI-MXNet/README
+++ b/perl-package/AI-MXNet/README
@@ -1,5 +1,5 @@
 This archive contains the distribution AI-MXNet,
-version 1.31:
+version 1.32:
 
   Perl interface to MXNet machine learning library
 
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet.pm b/perl-package/AI-MXNet/lib/AI/MXNet.pm
index 4e40fd7..651ca92 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet.pm
@@ -51,7 +51,7 @@ use AI::MXNet::Gluon;
 use AI::MXNet::NDArray::Sparse;
 use AI::MXNet::Symbol::Sparse;
 use AI::MXNet::Engine;
-our $VERSION = '1.31';
+our $VERSION = '1.32';
 
 sub import
 {
@@ -132,7 +132,7 @@ AI::MXNet - Perl interface to MXNet machine learning library
 
     ## Convolutional NN for recognizing hand-written digits in MNIST dataset
     ## It's considered "Hello, World" for Neural Networks
-    ## For more info about the MNIST problem please refer to http://neuralnetworksanddeeplearning.com/chap1.html
+    ## For more info about the MNIST problem please refer to L<http://neuralnetworksanddeeplearning.com/chap1.html>
 
     use strict;
     use warnings;
@@ -187,9 +187,104 @@ AI::MXNet - Perl interface to MXNet machine learning library
     my $res = $mod->score($val_dataiter, mx->metric->create('acc'));
     ok($res->{accuracy} > 0.8);
 
+    ## Gluon MNIST example
+
+    my $net = nn->Sequential();
+    $net->name_scope(sub {
+        $net->add(nn->Dense(128, activation=>'relu'));
+        $net->add(nn->Dense(64, activation=>'relu'));
+        $net->add(nn->Dense(10));
+    });
+    $net->hybridize;
+
+    # data
+    sub transformer
+    {
+        my ($data, $label) = @_;
+        $data = $data->reshape([-1])->astype('float32')/255;
+        return ($data, $label);
+    }
+    my $train_data = gluon->data->DataLoader(
+        gluon->data->vision->MNIST('./data', train=>1, transform => \&transformer),
+        batch_size=>$batch_size, shuffle=>1, last_batch=>'discard'
+    );
+
+    ## training
+    sub train
+    {
+        my ($epochs, $ctx) = @_;
+        # Collect all parameters from net and its children, then initialize them.
+        $net->initialize(mx->init->Xavier(magnitude=>2.24), ctx=>$ctx);
+        # Trainer is for updating parameters with gradient.
+        my $trainer = gluon->Trainer($net->collect_params(), 'sgd', { learning_rate => $lr, momentum => $momentum });
+        my $metric = mx->metric->Accuracy();
+        my $loss = gluon->loss->SoftmaxCrossEntropyLoss();
+
+        for my $epoch (0..$epochs-1)
+        {
+            # reset data iterator and metric at begining of epoch.
+            $metric->reset();
+            enumerate(sub {
+                my ($i, $d) = @_;
+                my ($data, $label) = @$d;
+                $data = $data->as_in_context($ctx);
+                $label = $label->as_in_context($ctx);
+                # Start recording computation graph with record() section.
+                # Recorded graphs can then be differentiated with backward.
+                my $output;
+                autograd->record(sub {
+                    $output = $net->($data);
+                    my $L = $loss->($output, $label);
+                    $L->backward;
+                });
+                # take a gradient step with batch_size equal to data.shape[0]
+                $trainer->step($data->shape->[0]);
+                # update metric at last.
+                $metric->update([$label], [$output]);
+
+                if($i % $log_interval == 0 and $i > 0)
+                {
+                    my ($name, $acc) = $metric->get();
+                    print "[Epoch $epoch Batch $i] Training: $name=$acc\n";
+                }
+            }, \@{ $train_data });
+
+            my ($name, $acc) = $metric->get();
+            print "[Epoch $epoch] Training: $name=$acc\n";
+
+            my ($val_name, $val_acc) = test($ctx);
+            print "[Epoch $epoch] Validation: $val_name=$val_acc\n"
+        }
+        $net->save_parameters('mnist.params');
+    }
+
+    train($epochs, $cuda ? mx->gpu(0) : mx->cpu);
+
 =head1 DESCRIPTION
 
     Perl interface to MXNet machine learning library.
+    MXNet supports the Perl programming language. 
+    The MXNet Perl package brings flexible and efficient GPU computing and 
+    state-of-art deep learning to Perl.
+    It enables you to write seamless tensor/matrix computation with multiple GPUs in Perl.
+    It also lets you construct and customize the state-of-art deep learning models in Perl,
+    and apply them to tasks, such as image classification and data science challenges.
+
+    One important thing to internalize is that Perl interface is written to be as close as possible to the Python’s API,
+    so most, if not all of Python’s documentation and examples should just work in Perl after making few changes 
+    in order to make the code a bit more Perlish. In nutshell just add $ sigils and replace . = \n with -> => ; 
+    and in 99% of cases that’s all that is needed there.
+    In addition please refer to very detailed L<MXNet Python API Documentation|http://mxnet.io/api/python/index.html>.
+
+    AI::MXNet supports new imperative PyTorch like Gluon MXNet interface.
+    Please get acquainted with this new interface at L<Deep Learning - The Straight Dope|https://gluon.mxnet.io/>.
+
+    For specific Perl Gluon usage please refer to Perl examples and tests directories on github,
+    but be assured that the Python and Perl usage are extremely close in order to make the use 
+    of the Python Gluon docs and examples as easy as possible.
+
+    AI::MXNet is seamlessly glued with L<PDL|https://metacpan.org/pod/PDL>, the C++ level state can be easily initialized from PDL
+    and the results can be transferred to PDL objects in order to allow you to use all the glory and power of the PDL!
 
 =head1 BUGS AND INCOMPATIBILITIES
 
@@ -198,9 +293,9 @@ AI::MXNet - Perl interface to MXNet machine learning library
 
 =head1 SEE ALSO
 
-    http://mxnet.io/
-    https://github.com/dmlc/mxnet/tree/master/perl-package
-    Function::Parameters, Mouse
+    L<http://mxnet.io/>
+    L<https://github.com/dmlc/mxnet/tree/master/perl-package>
+    L<Function::Parameters|https://metacpan.org/pod/Function::Parameters>, L<Mouse|https://metacpan.org/pod/Mouse>
 
 =head1 AUTHOR
 
@@ -208,6 +303,6 @@ AI::MXNet - Perl interface to MXNet machine learning library
 
 =head1 COPYRIGHT & LICENSE
 
-    This library is licensed under Apache 2.0 license https://www.apache.org/licenses/LICENSE-2.0
+    This library is licensed under Apache 2.0 license L<https://www.apache.org/licenses/LICENSE-2.0>
 
 =cut
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/AutoGrad.pm b/perl-package/AI-MXNet/lib/AI/MXNet/AutoGrad.pm
index 160cd96..c1e5f06 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/AutoGrad.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/AutoGrad.pm
@@ -46,16 +46,38 @@ EOP
     AI::MXNet::AutoGrad - Autograd for NDArray.
 =cut
 
+=head1 DESCRIPTION
+
+    Auto gradients differentiation for dynamic graphs, primarily used with Gluon.
+
+=cut
+
+=head1 SYNOPSIS
+
+    use AI::MXNet qw(mx);
+    my $x = mx->nd->ones([1]);
+    $x->attach_grad;
+    my $z;
+    mx->autograd->record(sub {
+        $z = mx->nd->elemwise_add($x->exp, $x);
+    });
+    my $dx = mx->autograd->grad($z, $x, create_graph=>1);
+    ok(abs($dx->asscalar - 3.71828175) < 1e-7);
+    $dx->backward;
+    ok(abs($x->grad->asscalar - 2.71828175) < 1e-7);
+
+=cut
+
 =head2 set_is_training
 
     Set status to training/not training. When training, graph will be constructed
-    for gradient computation. Operators will also run with ctx.is_train=True. For example,
+    for gradient computation. Operators will also run with $is_train=1. For example,
     Dropout will drop inputs randomly when is_train=True while simply passing through
-    if is_train=False.
+    if $is_train=0.
 
     Parameters
     ----------
-    is_train: bool
+    $is_train: Bool
 
     Returns
     -------
@@ -75,7 +97,7 @@ method set_is_training(Bool $is_train)
 
     Parameters
     ----------
-    is_recoding: bool
+    $is_recoding: Bool
 
     Returns
     -------
@@ -163,9 +185,9 @@ method mark_variables(
         Output NDArray(s)
     :$head_grads=: Maybe[AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray|Undef]]
         Gradients with respect to heads.
-    :$retain_graph=0: bool, optional
+    :$retain_graph=0: Bool, optional
         Whether to retain graph.
-    :$train_mode=1: bool, optional
+    :$train_mode=1: Bool, optional
         Whether to do backward for training or predicting.
 =cut
 method backward(
@@ -196,11 +218,11 @@ method backward(
 
     Parameters
     ----------
-    outputs: array ref of NDArray
+    outputs: ArrayRef[AI::MXNet::NDArray]
 
     Returns
     -------
-    gradients: array ref of NDArray
+    gradients: ArrayRef[AI::MXNet::NDArray]
 =cut
 
 
@@ -215,14 +237,14 @@ method compute_gradient(ArrayRef[AI::MXNet::NDArray] $outputs)
 
     Parameters
     ----------
-    func: a perl sub
+    $func: CodeRef
         The forward (loss) function.
-    argnum: an int or a array ref of int
+    $argnum: Maybe[Int|ArrayRef[Int]]
         The index of argument to calculate gradient for.
 
     Returns
     -------
-    grad_and_loss_func: a perl sub
+    grad_and_loss_func: CodeRef
         A function that would compute both the gradient of arguments and loss value.
 =cut
 
@@ -256,29 +278,29 @@ method grad_and_loss(CodeRef $func, Maybe[Int|ArrayRef[Int]] $argnum=)
     returned as new NDArrays instead of stored into `variable.grad`.
     Supports recording gradient graph for computing higher order gradients.
 
-    .. Note: Currently only a very limited set of operators support higher order
+    Note: Currently only a very limited set of operators support higher order
     gradients.
 
     Parameters
     ----------
-    $heads: NDArray or array ref of NDArray
+    $heads: AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray]
         Output NDArray(s)
-    $variables: NDArray or list of NDArray
+    $variables: AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray]
         Input variables to compute gradients for.
-    :$head_grads=: NDArray or list of NDArray or undef
+    :$head_grads=: Maybe[AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray|Undef]]
         Gradients with respect to heads.
-    :$retain_graph=: bool
+    :$retain_graph=: Bool
         Whether to keep computation graph to differentiate again, instead
         of clearing history and release memory. Defaults to the same value
         as create_graph.
-    :$create_graph=0: bool
-        Whether to record gradient graph for computing higher order
-    $train_mode=1: bool, optional
+    :$create_graph=0: Bool
+        Whether to record gradient graph for computing of higher order gradients.
+    $train_mode=1: Bool, optional
         Whether to do backward for training or prediction.
 
     Returns
     -------
-    NDArray or list of NDArray:
+    AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray]:
         Gradients with respect to variables.
 
     Examples
@@ -349,7 +371,7 @@ method grad(
     Executes $sub within an autograd training scope context.
     Parameters
     ----------
-    CodeRef $sub: a perl sub
+    $sub: CodeRef
 =cut
 
 method train_mode(CodeRef $sub)
@@ -365,7 +387,7 @@ method train_mode(CodeRef $sub)
     Executes $sub within an autograd predicting scope context.
     Parameters
     ----------
-    CodeRef $sub: a perl sub
+    $sub: CodeRef
 =cut
 
 method predict_mode(CodeRef $sub)
@@ -382,8 +404,8 @@ method predict_mode(CodeRef $sub)
     and captures code that needs gradients to be calculated.
     Parameters
     ----------
-    CodeRef $sub: a perl sub
-    Maybe[Bool] :$train_mode=1
+    $sub: CodeRef
+    :$train_mode=1 : Maybe[Bool]
 =cut
 
 method record(CodeRef $sub, Maybe[Bool] :$train_mode=1)
@@ -409,8 +431,8 @@ method record(CodeRef $sub, Maybe[Bool] :$train_mode=1)
     and captures code that needs gradients to be calculated.
     Parameters
     ----------
-    CodeRef $sub: a perl sub
-    Maybe[Bool] :$train_mode=0
+    $sub: CodeRef
+    :$train_mode=0 : Maybe[Bool]
 =cut
 
 method pause(CodeRef $sub, Maybe[Bool] :$train_mode=0)
@@ -436,11 +458,11 @@ method pause(CodeRef $sub, Maybe[Bool] :$train_mode=0)
 
     Parameters
     ----------
-    x : NDArray
-        Array representing the head of computation graph.
+    $x : AI::MXNet::NDArray
+        AI::MXNet::NDArray representing the head of computation graph.
     Returns
     -------
-    Symbol
+    AI::MXNet::Symbol
         The retrieved Symbol.
 =cut
 
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Base.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Base.pm
index f7daea2..3f6bd83 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Base.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Base.pm
@@ -21,7 +21,7 @@ use warnings;
 use PDL;
 use PDL::Types ();
 use PDL::CCS::Nd;
-use AI::MXNetCAPI 1.3;
+use AI::MXNetCAPI 1.32;
 use AI::NNVMCAPI 1.3;
 use AI::MXNet::Types;
 use Time::HiRes;
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/CachedOp.pm b/perl-package/AI-MXNet/lib/AI/MXNet/CachedOp.pm
index 27ec6dc..7e73ded 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/CachedOp.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/CachedOp.pm
@@ -22,6 +22,11 @@ package AI::MXNet::CachedOp;
     AI::MXNet::CachedOp - A wrapper around CachedOpHandle
 =cut
 
+=head1 DESCRIPTION
+
+    Internal module, used as a part of AI::MXNet::Gluon::HybridBlock.
+=cut
+
 use strict;
 use warnings;
 use AI::MXNet::Base;
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Callback.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Callback.pm
index da33097..b2a0b29 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Callback.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Callback.pm
@@ -25,7 +25,38 @@ use overload "&{}" => sub { my $self = shift; sub { $self->call(@_) } };
 
 =head1 NAME
 
-    AI::MXNet::Callback - A collection of predefined callback functions
+    AI::MXNet::Callback - A collection of predefined callback functions.
+=cut
+
+=head1 DESCRIPTION
+
+    A collection of predefined callback functions, mainly to be used in AI::MXNet::Module::Base::fit.
+=cut
+
+=head1 SYNOPSIS
+
+    my $model = mx->mod->Module(
+        symbol  => $net,
+        context => $contexts
+    );
+    $model->fit(
+        $data_iter,
+        eval_metric         => mx->metric->Perplexity,
+        kvstore             => $kv_store,
+        optimizer           => $optimizer,
+        optimizer_params    => {
+            learning_rate => $lr,
+            momentum      => $mom,
+            wd            => $wd,
+            clip_gradient => 5,
+            rescale_grad  => 1/$batch_size,
+            lr_scheduler  => AI::MXNet::FactorScheduler->new(step => 1000, factor => 0.99)
+        },
+        initializer         => mx->init->Xavier(factor_type => "in", magnitude => 2.34),
+        num_epoch           => $num_epoch,
+        batch_end_callback  => mx->callback->Speedometer($batch_size, $disp_batches),
+        ($chkp_epoch ? (epoch_end_callback  => [mx->callback->module_checkpoint($model, $chkp_prefix, $chkp_epoch), \&sample]) : ())
+    );
 =cut
 
 =head2 module_checkpoint
@@ -36,9 +67,9 @@ use overload "&{}" => sub { my $self = shift; sub { $self->call(@_) } };
     ----------
     $mod : subclass of AI::MXNet::Module::Base
         The module to checkpoint.
-    $prefix : str
+    $prefix : Str
         The file prefix to checkpoint to
-    $period=1 : int
+    $period=1 : Int
         How many epochs to wait before checkpointing. Default is 1.
     $save_optimizer_states=0 : Bool
         Whether to save optimizer states for later training.
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Context.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Context.pm
index e116e6e7..826e7ba 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Context.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Context.pm
@@ -78,6 +78,13 @@ use overload
     This class governs the device context of AI::MXNet::NDArray objects.
 =cut
 
+=head1 SYNOPSIS
+
+    use AI::MXNet qw(mx);
+    print nd->array([[1,2],[3,4]], ctx => mx->cpu)->aspdl;
+    my $arr_gpu = nd->random->uniform(shape => [10, 10], ctx => mx->gpu(0));
+=cut
+
 =head2
 
     Constructing a context.
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Contrib.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Contrib.pm
index 9f6a0ab..c470aca 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Contrib.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Contrib.pm
@@ -21,6 +21,32 @@ use warnings;
 use AI::MXNet::Contrib::Symbol;
 use AI::MXNet::Contrib::NDArray;
 
+=head1 NAME
+
+    AI::MXNet::Contrib - An interface to experimental operators defined in C++ space.
+=cut
+
+=head1 SYNOPSIS
+
+    my $embed;
+    if($sparse_embedding)
+    {
+        my $embed_weight = mx->sym->Variable('embed_weight', stype=>'row_sparse');
+        $embed = mx->sym->contrib->SparseEmbedding(
+            data=>$data, input_dim=>$num_words,
+            weight=>$embed_weight, output_dim=>$num_embed,
+            name=>'embed'
+        );
+    }
+    else
+    {
+        $embed = mx->sym->Embedding(
+            data=>$data, input_dim=>$num_words,
+            output_dim=>$num_embed, name=>'embed'
+        );
+    }
+=cut
+
 sub sym    { 'AI::MXNet::Contrib::Symbol'  }
 sub symbol { 'AI::MXNet::Contrib::Symbol'  }
 sub nd     { 'AI::MXNet::Contrib::NDArray' }
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Contrib/NDArray.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Contrib/NDArray.pm
index 0c1547e..574ecc4 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Contrib/NDArray.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Contrib/NDArray.pm
@@ -21,4 +21,14 @@ use warnings;
 use parent 'AI::MXNet::AutoLoad';
 sub config { ('contrib', 'AI::MXNet::NDArray') }
 
+=head1 NAME
+
+    AI::MXNet::Contrib::NDArray - An interface to experimental NDArray operators defined in C++ space.
+=cut
+
+=head1 SYNOPSIS
+
+    mx->contrib->ndarray->fft(nd->random->normal(0, 1, [3, 4], ctx => mx->gpu));
+=cut
+
 1;
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Contrib/Symbol.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Contrib/Symbol.pm
index d84f831..d5a041a 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Contrib/Symbol.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Contrib/Symbol.pm
@@ -21,4 +21,30 @@ use warnings;
 use parent 'AI::MXNet::AutoLoad';
 sub config { ('contrib', 'AI::MXNet::Symbol') }
 
+=head1 NAME
+
+    AI::MXNet::Contrib - An interface to experimental symbol operators defined in C++ space.
+=cut
+
+=head1 SYNOPSIS
+
+    my $embed;
+    if($sparse_embedding)
+    {
+        my $embed_weight = mx->sym->Variable('embed_weight', stype=>'row_sparse');
+        $embed = mx->sym->contrib->SparseEmbedding(
+            data=>$data, input_dim=>$num_words,
+            weight=>$embed_weight, output_dim=>$num_embed,
+            name=>'embed'
+        );
+    }
+    else
+    {
+        $embed = mx->sym->Embedding(
+            data=>$data, input_dim=>$num_words,
+            output_dim=>$num_embed, name=>'embed'
+        );
+    }
+=cut
+
 1;
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/CudaModule.pm b/perl-package/AI-MXNet/lib/AI/MXNet/CudaModule.pm
index 5fa66b2..b3272fe 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/CudaModule.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/CudaModule.pm
@@ -34,6 +34,11 @@ our %DTYPE_CPP_TO_STR = qw(
     int64_t  int64
 );
 
+=head1 NAME
+
+    AI::MXNet::CudaModule - Interface to runtime cuda kernel compile module.
+=cut
+
 =head1 DESCRIPTION
 
     Interface to runtime cuda kernel compile module.
@@ -81,12 +86,12 @@ our %DTYPE_CPP_TO_STR = qw(
 
     Parameters
     ----------
-    source : str
+    source : Str
         Complete source code.
-    options : array ref of str
+    options : Str|ArrayRef[Str]
         Compiler flags. For example, use "-I/usr/local/cuda/include" to
         add cuda headers to include path.
-    exports : array ref of str
+    exports : Str|ArrayRef[Str]
         Export kernel names.
 =cut
 
@@ -124,9 +129,9 @@ sub DEMOLISH
 
         Parameters
         ----------
-        name : str
+        $name : Str
             String name of the kernel.
-        signature : str
+        $signature : Str
             Function signature for the kernel. For example, if a kernel is
             declared as::
 
@@ -196,7 +201,7 @@ use AI::MXNet::Base;
 
 =head1 NAME
 
-    AI::MXNet::CudaKernel
+    AI::MXNet::CudaKernel - Constructs CUDA kernel.
 =cut
 
 =head1 DESCRIPTION
@@ -228,15 +233,15 @@ sub DEMOLISH
 
         Parameters
         ----------
-        $args : array ref of NDArray or numbers
+        $args : ArrayRef[AI::MXNet::NDArray|Num]
             List of arguments for kernel. NDArrays are expected for pointer
             types (e.g. `float*`, `double*`) while numbers are expected for
             non-pointer types (e.g. `int`, `float`).
         $ctx : AI::MXNet::Context
             The context to launch kernel on. Must be GPU context.
-        $grid_dims : array ref of 3 integers
+        $grid_dims : array ref of 3 integers (CudaKernelShape)
             Grid dimensions for CUDA kernel.
-        $block_dims : array ref of 3 integers
+        $block_dims : array ref of 3 integers (CudaKernelShape)
             Block dimensions for CUDA kernel.
         $shared_mem=0 : integer, optional
             Size of dynamically allocated shared memory. Defaults to 0.
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Engine.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Engine.pm
index c4ee262..1d73e55 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Engine.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Engine.pm
@@ -20,9 +20,28 @@ use strict;
 use warnings;
 use AI::MXNet::Function::Parameters;
 use AI::MXNet::Base;
+
 =head1 NAME
 
-    AI::MXNet::Engine - Engine properties management.
+    AI::MXNet::Engine - Allows management of properties of the MXNet's engine.
+=cut
+
+=head1 SYNOPSIS
+
+    my $x;
+    mx->engine->bulk(10, sub {
+        $x = mx->nd->ones([10]);
+        $x *= 2;
+        $x += 1;
+        $x->wait_to_read();
+        $x += 1;
+        ok(($x->aspdl == 4)->all);
+        for my $i (1..100)
+        {
+            $x += 1;
+        }
+    });
+    ok(($x->aspdl == 104)->all);
 =cut
 
 =head2 set_bulk_size
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Executor.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Executor.pm
index edcaabe..573abbf 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Executor.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Executor.pm
@@ -32,7 +32,6 @@ has '_symbol'           => (is => 'rw', init_arg => 'symbol',    isa => 'AI::MXN
 has '_ctx'              => (is => 'rw', init_arg => 'ctx',       isa => 'AI::MXNet::Context' );
 has '_grad_req'         => (is => 'rw', init_arg => 'grad_req',  isa => 'Maybe[Str|ArrayRef[Str]|HashRef[Str]]');
 has '_group2ctx'        => (is => 'rw', init_arg => 'group2ctx', isa => 'Maybe[HashRef[AI::MXNet::Context]]');
-has '_monitor_callback' => (is => 'rw', isa => 'CodeRef');
 has [qw/_arg_dict
         _grad_dict
         _aux_dict
@@ -42,6 +41,18 @@ has [qw/_arg_dict
 =head1 NAME
 
     AI::MXNet::Executor - The actual executing object of MXNet.
+=cut
+
+=head1 SYNOPSIS
+
+    my $executor = $sym->bind(
+        ctx       => mx->Context('cpu'),
+        args      => [$lhs_arr, $rhs_arr],
+        args_grad => [$lhs_grad, $rhs_grad]
+    );
+    $executor->forward(1);
+    print $executor->outputs->[0]->aspdl;
+=cut
 
 =head2 new
 
@@ -138,7 +149,7 @@ method _get_outputs()
 
     Parameters
     ----------
-    $is_train=0: bool, optional
+    $is_train=0: Bool, optional
         whether this forward is for evaluation purpose. If True,
         a backward call is expected to follow. Otherwise following
         backward is invalid.
@@ -200,12 +211,12 @@ method forward(Int $is_train=0, %kwargs)
 
     Parameters
     ----------
-    out_grads : NDArray or an array ref of NDArrays or hash ref of NDArrays, optional.
+    $out_grads : NDArray or an array ref of NDArrays or hash ref of NDArrays, optional.
         The gradient on the outputs to be propagated back.
         This parameter is only needed when bind is called
         on outputs that are not a loss function.
 
-    is_train : bool, default 1
+    $is_train : Bool, default 1
         Whether this backward is for training or inference. Note that in rare
         cases you want to call backward with is_train=0 to get gradient
         during inference.
@@ -241,17 +252,16 @@ method backward(
 
     Parameters
     ----------
-    callback : subref
+    $callback : CodeRef
         Takes a string and an NDArrayHandle.
 =cut
 
 method set_monitor_callback(CodeRef $callback)
 {
-    $self->_monitor_callback($callback);
     check_call(
         AI::MXNetCAPI::ExecutorSetMonitorCallback(
             $self->handle,
-            $self->_monitor_callback
+            $callback
         )
     );
 }
@@ -262,7 +272,7 @@ method set_monitor_callback(CodeRef $callback)
 
     Returns
     -------
-    arg_dict : HashRef[AI::MXNet::NDArray]
+    $arg_dict : HashRef[AI::MXNet::NDArray]
         The map that maps a name of the arguments to the NDArrays.
 =cut
 
@@ -285,7 +295,7 @@ method arg_dict()
 
     Returns
     -------
-    grad_dict : HashRef[AI::MXNet::NDArray]
+    $grad_dict : HashRef[AI::MXNet::NDArray]
         The map that maps a name of the arguments to the gradient NDArrays.
 =cut
 
@@ -308,7 +318,7 @@ method grad_dict()
 
     Returns
     -------
-    aux_dict : HashRef[AI::MXNet::NDArray]
+    $aux_dict : HashRef[AI::MXNet::NDArray]
         The map that maps a name of the auxiliary states to the NDArrays.
 =cut
 
@@ -331,7 +341,7 @@ method aux_dict()
 
     Returns
     -------
-    output_dict : HashRef[AI::MXNet::NDArray]
+    $output_dict : HashRef[AI::MXNet::NDArray]
         The map that maps a name of the outputs to the NDArrays.
 =cut
 
@@ -354,13 +364,13 @@ method output_dict()
 
     Parameters
     ----------
-    arg_params : HashRef[AI::MXNet::NDArray]
+    $arg_params : HashRef[AI::MXNet::NDArray]
         Parameters, hash ref of name to NDArray of arguments
 
-    aux_params : Maybe[HashRef[AI::MXNet::NDArray]], optional
+    $aux_params= : Maybe[HashRef[AI::MXNet::NDArray]], optional
         Parameters, hash ref of name to NDArray of auxiliary states.
 
-    allow_extra_params : boolean, optional
+    $allow_extra_params= : Bool, optional
         Whether to allow extra parameters that are not needed by symbol
         If this is True, no error will be thrown when arg_params or aux_params
         contain extra parameters that is not needed by the executor.
@@ -415,9 +425,9 @@ method copy_params_from(
     ----------
     $kwargs : HashRef[Shape]
         new shape for arguments.
-    :$partial_shaping : bool
+    :$partial_shaping : Bool
         Whether to allow changing the shape of unspecified arguments.
-    :$allow_up_sizing : bool
+    :$allow_up_sizing : Bool
         Whether to allow allocating new ndarrays that's larger than the original.
 
     Returns
@@ -501,7 +511,7 @@ method reshape(HashRef[Shape] $kwargs, Int :$partial_shaping=0, Int :$allow_up_s
 
     Returns
     -------
-    debug_str : string
+    $debug_str : Str
         Debug string of the executor.
 =cut
 
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Gluon.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Gluon.pm
index 7f92378..92c8386 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Gluon.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Gluon.pm
@@ -57,4 +57,106 @@ sub data { 'AI::MXNet::Gluon::Data' }
 sub utils { 'AI::MXNet::Gluon::Utils' }
 sub model_zoo { require AI::MXNet::Gluon::ModelZoo; 'AI::MXNet::Gluon::ModelZoo' }
 
+=head1 NAME
+
+    AI::MXNet::Gluon - High-level interface for MXNet.
+=cut
+
+=head1 DESCRIPTION
+
+    The AI::MXNet::Gluon package is a high-level interface for MXNet designed to be easy to use,
+    while keeping most of the flexibility of a low level API.
+    AI::MXNet::Gluon supports both imperative and symbolic programming,
+    making it easy to train complex models imperatively in Perl.
+
+    Based on the the Gluon API specification,
+    the Gluon API in Apache MXNet provides a clear, concise, and simple API for deep learning.
+    It makes it easy to prototype, build, and train deep learning models without sacrificing training speed.
+
+    Advantages.
+
+    Simple, Easy-to-Understand Code: Gluon offers a full set of plug-and-play neural network building blocks,
+    including predefined layers, optimizers, and initializers.
+
+    Flexible, Imperative Structure: Gluon does not require the neural network model to be rigidly defined,
+    but rather brings the training algorithm and model closer together to provide flexibility in the development process.
+
+    Dynamic Graphs: Gluon enables developers to define neural network models that are dynamic,
+    meaning they can be built on the fly, with any structure, and using any of Perl’s native control flow.
+
+    High Performance: Gluon provides all of the above benefits without impacting the training speed that the underlying engine provides.
+
+
+    Simple, Easy-to-Understand Code
+    Use plug-and-play neural network building blocks, including predefined layers, optimizers, and initializers:
+
+    use AI::MXNet qw(mx);
+    use AI::MXNet::Gluon qw(gluon);
+
+    my $net = gluon->nn->Sequential;
+    # When instantiated, Sequential stores a chain of neural network layers.
+    # Once presented with data, Sequential executes each layer in turn, using
+    # the output of one layer as the input for the next
+    $net->name_scope(sub {
+        $net->add(gluon->nn->Dense(256, activation=>"relu")); # 1st layer (256 nodes)
+        $net->add(gluon->nn->Dense(256, activation=>"relu")); # 2nd hidden layer
+        $net->add(gluon->nn->Dense($num_outputs));
+    });
+
+    Flexible, Imperative Structure.
+
+    Prototype, build, and train neural networks in fully imperative manner using the AI::MXNet::MXNet package and the Gluon trainer method:
+
+    use AI::MXNet::Base; # provides helpers, such as zip, enumerate, etc.
+    use AI::MXNet::AutoGrad qw(autograd);
+    my $epochs = 10;
+
+    for(1..$epochs)
+    {
+        for(zip($train_data))
+        {
+            my ($data, $label) = @$_;
+            autograd->record(sub {
+                my $output = $net->($data); # the forward iteration
+                my $loss = gluon->loss->softmax_cross_entropy($output, $label);
+                $loss->backward;
+            });
+            $trainer->step($data->shape->[0]); ## batch size
+        }
+    }
+
+    Dynamic Graphs.
+
+    Build neural networks on the fly for use cases where neural networks must change in size and shape during model training:
+
+    use AI::MXNet::Function::Parameters;
+
+    method forward(GluonClass $F, GluonInput $inputs, GluonInput :$tree)
+    {
+        my $children_outputs = [
+            map { $self->forward($F, $inputs, $_) @{ $tree->children }
+        ];
+        #Recursively builds the neural network based on each input sentence’s
+        #syntactic structure during the model definition and training process
+        ...
+    }
+
+    High Performance
+
+    Easily cache the neural network to achieve high performance by defining your neural network with HybridSequential
+    and calling the hybridize method:
+
+    use AI::MXNet::Gluon::NN qw(nn);
+
+    my $net = nn->HybridSequential;
+    $net->name_scope(sub {
+        $net->add(nn->Dense(256, activation=>"relu"));
+        $net->add(nn->Dense(128, activation=>"relu"));
+        $net->add(nn->Dense(2));
+    });
+
+    $net->hybridize();
+    See more at L<Python docs|http://mxnet.incubator.apache.org/api/python/gluon/gluon.html>
+=cut
+
 1;
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Block.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Block.pm
index be819ac..1b35e78 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Block.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Block.pm
@@ -855,20 +855,20 @@ package AI::MXNet::Gluon::HybridBlock;
 
 =head2 DESCRIPTION
 
-    `HybridBlock` supports forwarding with both Symbol and NDArray.
+    HybridBlock supports forwarding with both Symbol and NDArray.
 
-    Forward computation in `HybridBlock` must be static to work with `Symbol`s,
-    i.e. you cannot call `.asnumpy()`, `.shape`, `.dtype`, etc on tensors.
+    Forward computation in HybridBlock must be static to work with Symbols,
+    i.e. you cannot call aspdl, shape, dtype, etc on tensors.
     Also, you cannot use branching or loop logic that bases on non-constant
     expressions like random numbers or intermediate results, since they change
     the graph structure for each iteration.
 
-    Before activating with `hybridize()`, `HybridBlock` works just like normal
-    `Block`. After activation, `HybridBlock` will create a symbolic graph
+    Before activating with hybridize(), HybridBlock works just like normal
+    Block. After activation, HybridBlock will create a symbolic graph
     representing the forward computation and cache it. On subsequent forwards,
-    the cached graph will be used instead of `hybrid_forward`.
+    the cached graph will be used instead of hybrid_forward.
 
-    Refer `Hybrid tutorial <http://mxnet.io/tutorials/gluon/hybrid.html>`_ to see
+    Refer Hybrid tutorial L<http://mxnet.io/tutorials/gluon/hybrid.html> to see
     the end-to-end usage.
 =cut
 
@@ -1141,7 +1141,7 @@ method _call_cached_op(@args)
 =head2 forward
 
         Defines the forward computation. Arguments can be either
-        `NDArray` or `Symbol`.
+        NDArray or Symbol
 =cut
 
 method forward($x, @args)
@@ -1225,12 +1225,12 @@ method hybrid_forward($F, $x, @args)
         or the C++ interface.
 
         When there are only one input, it will have name 'data'. When there
-        Are more than one inputs, they will be named as `data0`, `data1`, etc.
+        Are more than one inputs, they will be named as 'data0', 'data1', etc.
 
         Parameters
         ----------
         $path : str
-            Path to save model. Two files `path-symbol.json` and `path-xxxx.params`
+            Path to save model. Two files 'path-symbol.json' and 'path-xxxx.params'
             will be created, where xxxx is the 4 digits epoch number.
         :$epoch=0 : Int
             Epoch number of saved model.
@@ -1298,20 +1298,20 @@ extends 'AI::MXNet::Gluon::HybridBlock';
 
     Examples
     --------
-    >>> # To extract the feature from fc1 and fc2 layers of AlexNet:
-    >>> alexnet = gluon.model_zoo.vision.alexnet(pretrained=True, ctx=mx.cpu(),
-                                                 prefix='model_')
-    >>> inputs = mx.sym.var('data')
-    >>> out = alexnet(inputs)
-    >>> internals = out.get_internals()
-    >>> print(internals.list_outputs())
+    >>> # To extract the feature from fc1 and fc2 layers of AlexNet
+    >>> $alexnet = gluon->model_zoo->vision->alexnet(pretrained=>1, ctx=>mx->cpu(),
+                                                 prefix=>'model_');
+    >>> $inputs = mx->sym->var('data');
+    >>> $out = $alexnet->($inputs);
+    >>> $internals = $out->get_internals()
+    >>> print($internals->list_outputs())
     ['data', ..., 'model_dense0_relu_fwd_output', ..., 'model_dense1_relu_fwd_output', ...]
-    >>> outputs = [internals['model_dense0_relu_fwd_output'],
-                   internals['model_dense1_relu_fwd_output']]
+    >>> $outputs = [$internals->slice('model_dense0_relu_fwd_output'),
+                   $internals->slice('model_dense1_relu_fwd_output')];
     >>> # Create SymbolBlock that shares parameters with alexnet
-    >>> feat_model = gluon.SymbolBlock(outputs, inputs, params=alexnet.collect_params())
-    >>> x = mx.nd.random_normal(shape=(16, 3, 224, 224))
-    >>> print(feat_model(x))
+    >>> $feat_model = gluon->SymbolBlock($outputs, $inputs, params=>$alexnet->collect_params());
+    >>> $x = mx->nd->random_normal(shape=>[16, 3, 224, 224]);
+    >>> print($feat_model->($x));
 =cut
 
 has [qw/outputs inputs/] => (is => 'rw', isa => 'AI::MXNet::Symbol|ArrayRef[AI::MXNet::Symbol]');
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Parameter.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Parameter.pm
index c39d5d4..475c2a9 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Parameter.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Gluon/Parameter.pm
@@ -934,7 +934,6 @@ use overload
         my $content = join("\n", map { AI::MXNet::Base::_indent("   $_", 2) } $self->values);
         return "$name(\n$content\n)";
     },
-    '%{}'  => sub { my %tmp = shift->_params->as_list; \%tmp },
     '@{}'  => sub { my @tmp = shift->_params->as_list; \@tmp },
     fallback => 1;
 
@@ -1316,7 +1315,7 @@ method load(
             );
             next;
         }
-        $self->{ $name }->_load_init($arg_dict{$name}, $ctx);
+        $self->_params->get($name)->_load_init($arg_dict{$name}, $ctx);
     }
 }
 
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/IO.pm b/perl-package/AI-MXNet/lib/AI/MXNet/IO.pm
index fc3f960..297ceb8 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/IO.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/IO.pm
@@ -24,7 +24,15 @@ use Scalar::Util qw/blessed/;
 
 =head1 NAME
 
-    AI::MXNet::IO - NDArray interface of mxnet.
+    AI::MXNet::IO - Data loading interface of MXNet
+=cut
+
+=head1 DESCRIPTION
+
+    This document summarizes supported data formats and iterator APIs to read the data including
+    mx->io              Data iterators for common data formats.
+    mx->recordio        Data iterators for the RecordIO data format.
+    mx->image           Image Iterators and image augmentation functions.
 =cut
 
 # Convert data into canonical form.
@@ -626,6 +634,21 @@ extends 'AI::MXNet::DataIter';
     AI::MXNet::MXDataIter - A data iterator pre-built in C++ layer of MXNet.
 =cut
 
+=head1 DESCRIPTION
+
+    Here are the list of currently available predefined iterators, for more custom iterators
+    please check out the examples directory.
+    Also please refer to the L<Python docs|http://mxnet.incubator.apache.org/api/python/io/io.html>
+    mx->io->CSVIter                     Returns the CSV file iterator.
+    mx->io->LibSVMIter                  Returns the LibSVM iterator which returns data with csr storage type.
+    mx->io->ImageRecordIter             Iterates on image RecordIO files
+    mx->io->ImageRecordUInt8Iter        Iterating on image RecordIO files
+    mx->io->MNISTIter                   Iterating on the MNIST dataset.
+    mx->recordio->MXRecordIO            Reads/writes RecordIO data format, supporting sequential read and write.
+    mx->recordio->MXIndexedRecordIO     Reads/writes RecordIO data format, supporting random access.
+    mx->image->ImageIter                Image data iterator with a large number of augmentation choices.
+=cut
+
 has 'handle'           => (is => 'ro', isa => 'DataIterHandle', required => 1);
 has '_debug_skip_load' => (is => 'rw', isa => 'Int', default => 0);
 has '_debug_at_begin'  => (is => 'rw', isa => 'Int', default => 0);
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Image.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Image.pm
index 4f670b0..9c7fa12 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Image.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Image.pm
@@ -622,18 +622,18 @@ method CastAug()
 =cut
 
 method CreateAugmenter(
-Shape          :$data_shape,
-Bool           :$resize=0,
-Bool           :$rand_crop=0,
-Bool           :$rand_resize=0,
-Bool           :$rand_mirror=0,
-Maybe[Num|PDL] :$mean=,
-Maybe[Num|PDL] :$std=,
-Num            :$brightness=0,
-Num            :$contrast=0,
-Num            :$saturation=0,
-Num            :$pca_noise=0,
-Int            :$inter_method=2
+    Shape          :$data_shape,
+    Bool           :$resize=0,
+    Bool           :$rand_crop=0,
+    Bool           :$rand_resize=0,
+    Bool           :$rand_mirror=0,
+    Maybe[Num|PDL] :$mean=,
+    Maybe[Num|PDL] :$std=,
+    Num            :$brightness=0,
+    Num            :$contrast=0,
+    Num            :$saturation=0,
+    Num            :$pca_noise=0,
+    Int            :$inter_method=2
 )
 {
     my @auglist;
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Initializer.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Initializer.pm
index 7c481ef..fe8dce3 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Initializer.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Initializer.pm
@@ -73,6 +73,24 @@ has '_print_func' => (is => 'rw', isa => 'CodeRef', lazy => 1,
 
     AI::MXNet::Initializer - Base class for all Initializers
 
+=head1 DESCRIPTION
+
+    The base class AI::MXNet::Initializer defines the default behaviors to initialize various parameters,
+    such as set bias to 1, except for the weight. Other classes then define how to initialize the weights.
+    Currently following classes are available:
+    mx->init->Uniform    Initializes weights with random values uniformly sampled from a given range.
+    mx->init->Normal     Initializes weights with random values sampled from a normal distribution with a mean of zero and standard deviation of sigma.
+    mx->init->Load       Initializes variables by loading data from file or dict.
+    mx->init->Mixed      Initialize parameters using multiple initializers.
+    mx->init->Zero       Initializes weights to zero.
+    mx->init->One        Initializes weights to one.
+    mx->init->Constant   Initializes the weights to a given value.
+    mx->init->Orthogonal Initialize weight as orthogonal matrix.
+    mx->init->Xavier     Returns an initializer performing “Xavier” initialization for weights.
+    mx->init->MSRAPrelu  Initialize the weight according to a MSRA paper.
+    mx->init->Bilinear   Initialize weight for upsampling layers.
+    mx->init->FusedRNN   Initialize parameters for fused rnn layers.
+
 =head2 register
 
     Register an initializer class to the AI::MXNet::Initializer factory.
@@ -372,7 +390,7 @@ method call(Str $name, AI::MXNet::NDArray $arr)
 
 =head1 NAME
 
-    AI::MXNet::Mixed - A container for multiple initializer patterns.
+    AI::MXNet::Mixed - A container with multiple initializer patterns.
 =cut
 
 =head2 new
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/KVStore.pm b/perl-package/AI-MXNet/lib/AI/MXNet/KVStore.pm
index de66d91..bb6631f 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/KVStore.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/KVStore.pm
@@ -37,7 +37,6 @@ use AI::MXNet::Function::Parameters;
 
 has 'handle' => (is => 'ro', isa => 'KVStoreHandle', required => 1);
 has '_updater' => (is => 'rw',  isa => 'AI::MXNet::Updater');
-has '_updater_func' => (is => 'rw', isa => 'CodeRef');
 
 sub DEMOLISH
 {
@@ -53,9 +52,9 @@ sub DEMOLISH
 
     Parameters
     ----------
-    key : str or an array ref of str
+    $key : Str|ArrayRef[Str]
         The keys.
-    value : NDArray or an array ref of NDArray objects
+    $value : AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray]|ArrayRef[ArrayRef[AI::MXNet::NDArray]]
         The values.
 
     Examples
@@ -100,9 +99,9 @@ method init(
 
     Parameters
     ----------
-    key : str or array ref of str
-    value : NDArray or array ref of NDArray or array ref of array refs of NDArray
-    priority : int, optional
+    $key : Str|ArrayRef[Str]
+    $value : AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray]|ArrayRef[ArrayRef[AI::MXNet::NDArray]]
+    :$priority=0 : Int, optional
         The priority of the push operation.
         The higher the priority, the faster this action is likely
         to be executed before other push actions.
@@ -171,12 +170,12 @@ method push(
 
     Parameters
     ----------
-    key : str or array ref of str
+    $key : Str|ArrayRef[Str]
         Keys
-    out: NDArray or array ref of NDArray or array ref of array refs of NDArray
+    :$out: AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray]|ArrayRef[ArrayRef[AI::MXNet::NDArray]]
         According values
 
-    priority : int, optional
+    :$priority=0 : Int, optional
         The priority of the push operation.
         The higher the priority, the faster this action is likely
         to be executed before other push actions.
@@ -241,18 +240,18 @@ method pull(
 
         Parameters
         ----------
-        key : str, int, or sequence of str or int
+        $key : Str|ArrayRef[Str] $key
             Keys.
 
-        out: AI::MXNet::NDArray::RowSparse or array ref of AI::MXNet::NDArray::RowSparse or array ref of array ref of AI::MXNet::NDArray::RowSparse
+        :$out: AI::MXNet::NDArray::RowSparse|ArrayRef[AI::MXNet::NDArray::RowSparse]|ArrayRef[ArrayRef[AI::MXNet::NDArray::RowSparse]]
             Values corresponding to the keys. The stype is expected to be row_sparse
 
-        priority : int, optional
+        :$priority=0 : Int, optional
             The priority of the pull operation.
             Higher priority pull operations are likely to be executed before
             other pull actions.
 
-        row_ids : AI::MXNet::NDArray or array ref of AI::MXNet::NDArray
+        :$row_ids : AI::MXNet::NDArray|ArrayRef[AI::MXNet::NDArray]|ArrayRef[ArrayRef[AI::MXNet::NDArray]]
             The row_ids for which to pull for each value. Each row_id is an 1D NDArray
             whose values don't have to be unique nor sorted.
 
@@ -364,7 +363,7 @@ method row_sparse_pull(
 
         Parameters
         ----------
-        compression_params : HashRef
+        $compression_params : HashRef[Str]
             A dictionary specifying the type and parameters for gradient compression.
             The key `type` in this dictionary is a
             required string argument and specifies the type of gradient compression.
@@ -401,7 +400,7 @@ method set_gradient_compression(HashRef[Str] $compression_params)
 
     Parameters
     ----------
-    optimizer : Optimizer
+    $optimizer : AI::MXNet::Optimizer
         the optimizer
 =cut
 
@@ -426,7 +425,7 @@ method set_optimizer(AI::MXNet::Optimizer $optimizer)
 
     Returns
     -------
-    type : str
+    $type : Str
         the string type
 =cut
 
@@ -441,7 +440,7 @@ method type()
 
     Returns
     -------
-    rank : int
+    $rank : Int
         The rank of this node, which is in [0, get_num_workers())
 =cut
 
@@ -456,7 +455,7 @@ method rank()
 
     Returns
     -------
-    size :int
+    $size : Int
         The number of worker nodes
 =cut
 
@@ -471,9 +470,9 @@ method num_workers()
 
     Parameters
     ----------
-    fname : str
+    $fname : Str
         Path to output states file.
-    dump_optimizer : bool, default False
+    :$dump_optimizer=0 : Bool, default False
             Whether to also save the optimizer itself. This would also save optimizer
             information such as learning rate and weight decay schedules.
 =cut
@@ -493,7 +492,7 @@ method save_optimizer_states(Str $fname, Bool :$dump_optimizer=0)
 
     Parameters
     ----------
-    fname : str
+    $fname : Str
         Path to input states file.
 =cut
 
@@ -517,7 +516,7 @@ method load_optimizer_states(Str $fname)
 
     Parameters
     ----------
-    updater : function
+    $updater : Undater
         the updater function
 
     Examples
@@ -540,20 +539,17 @@ method load_optimizer_states(Str $fname)
 
 method _set_updater(Updater $updater_func)
 {
-    $self->_updater_func(
-        sub {
-            my ($index, $input_handle, $storage_handle) = @_;
-            $updater_func->(
-                $index,
-                AI::MXNet::NDArray->_ndarray_cls($input_handle),
-                AI::MXNet::NDArray->_ndarray_cls($storage_handle)
-            );
-        }
-    );
     check_call(
         AI::MXNetCAPI::KVStoreSetUpdater(
             $self->handle,
-            $self->_updater_func
+            sub {
+                my ($index, $input_handle, $storage_handle) = @_;
+                $updater_func->(
+                    $index,
+                    AI::MXNet::NDArray->_ndarray_cls($input_handle),
+                    AI::MXNet::NDArray->_ndarray_cls($storage_handle)
+                );
+            }
         )
     );
 }
@@ -583,9 +579,9 @@ method _barrier()
 
     Parameters
     ----------
-    head : int
+    $head : Int
         the head of the command
-    body : str
+    $body : Str
         the body of the command
 =cut
 
@@ -606,7 +602,7 @@ method _send_command_to_servers(Int $head, Str $body)
 
     Parameters
     ----------
-    name : {'local'}
+    $name='local' : Str
     The type of KVStore
         - local works for multiple devices on a single machine (single process)
         - dist works for multi-machines (multiple processes)
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/KVStoreServer.pm b/perl-package/AI-MXNet/lib/AI/MXNet/KVStoreServer.pm
index 4c274b9..39e152a 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/KVStoreServer.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/KVStoreServer.pm
@@ -27,7 +27,7 @@ use AI::MXNet::Function::Parameters;
 
 =head1 NAME
 
-    AI::MXNet::KVStoreServer - The key-value store server
+    AI::MXNet::KVStoreServer - The key-value store server.
 =cut
 
 =head2 new
@@ -36,7 +36,7 @@ use AI::MXNet::Function::Parameters;
 
     Parameters
     ----------
-    kvstore : KVStore
+    kvstore : AI::MXNet::KVStore
 =cut
 
 has 'kvstore' => (is => 'ro', isa => 'AI::MXNet::KVStore', required => 1);
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/LRScheduler.pm b/perl-package/AI-MXNet/lib/AI/MXNet/LRScheduler.pm
index 27420f4..5575e37 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/LRScheduler.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/LRScheduler.pm
@@ -58,7 +58,7 @@ has 'base_lr' => (is => 'rw', isa => 'Num', default => 0.01);
 
     Parameters
     ----------
-    num_update: int
+    $num_update: Int
         the maximal number of updates applied to a weight.
 =cut
 
@@ -76,9 +76,9 @@ package AI::MXNet::FactorScheduler;
 
     Parameters
     ----------
-    step: int
+    step: Int
         schedule the learning rate update after n updates
-    factor: float
+    factor: Num
         the factor by which to reduce the learning rate.
 =cut
 use Mouse;
@@ -138,9 +138,9 @@ package AI::MXNet::MultiFactorScheduler;
 
     Parameters
     ----------
-    step: array ref of int
+    step: ArrayRef[Int]
         schedule learning rate after n updates
-    factor: float
+    factor: Num
         the factor for reducing the learning rate
 =cut
 
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/LinAlg.pm b/perl-package/AI-MXNet/lib/AI/MXNet/LinAlg.pm
index 9290e68..be1262f 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/LinAlg.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/LinAlg.pm
@@ -21,6 +21,54 @@ use warnings;
 use AI::MXNet::LinAlg::Symbol;
 use AI::MXNet::LinAlg::NDArray;
 
+=head1 NAME
+
+    AI::MXNet::LinAlg - Linear Algebra routines for NDArray and Symbol.
+=cut
+
+=head1 DESCRIPTION
+
+    The Linear Algebra API, provides imperative/symbolic linear algebra tensor operations on CPU/GPU.
+
+    mx->linalg-><sym|nd>->gemm  Performs general matrix multiplication and accumulation.
+    mx->linalg-><sym|nd>->gemm2 Performs general matrix multiplication.
+    mx->linalg-><sym|nd>->potrf Performs Cholesky factorization of a symmetric positive-definite matrix.
+    mx->linalg-><sym|nd>->potri Performs matrix inversion from a Cholesky factorization.
+    mx->linalg-><sym|nd>->trmm  Performs multiplication with a lower triangular matrix.
+    mx->linalg-><sym|nd>->trsm  Solves matrix equation involving a lower triangular matrix.
+    mx->linalg-><sym|nd>->sumlogdiag    Computes the sum of the logarithms of the diagonal elements of a square matrix.
+    mx->linalg-><sym|nd>->syrk  Multiplication of matrix with its transpose.
+    mx->linalg-><sym|nd>->gelqf LQ factorization for general matrix.
+    mx->linalg-><sym|nd>->syevd Eigendecomposition for symmetric matrix.
+    L<NDArray Python Docs|http://mxnet.incubator.apache.org/api/python/ndarray/linalg.html>
+    L<Symbol Python Docs|http://mxnet.incubator.apache.org/api/python/symbol/linalg.html>
+
+    Examples:
+
+    ## NDArray
+    my $A = mx->nd->array([[1.0, 1.0], [1.0, 1.0]]);
+    my $B = mx->nd->array([[1.0, 1.0], [1.0, 1.0], [1.0, 1.0]]);
+    ok(almost_equal(
+        mx->nd->linalg->gemm2($A, $B, transpose_b=>1, alpha=>2.0)->aspdl,
+        pdl([[4.0, 4.0, 4.0], [4.0, 4.0, 4.0]])
+    ));
+
+    ## Symbol
+    my $sym_gemm2 = mx->sym->linalg->gemm2(
+        mx->sym->var('A'),
+        mx->sym->var('B'),
+        transpose_b => 1,
+        alpha => 2.0
+    );
+    my $A = mx->nd->array([[1.0, 1.0], [1.0, 1.0]]);
+    my $B = mx->nd->array([[1.0, 1.0], [1.0, 1.0], [1.0, 1.0]]);
+    ok(almost_equal(
+        $sym_gemm2->eval(args => { A => $A, B => $B })->[0]->aspdl,
+        pdl([[4.0, 4.0, 4.0], [4.0, 4.0, 4.0]])
+    ));
+
+=cut
+
 sub sym    { 'AI::MXNet::LinAlg::Symbol'  }
 sub symbol { 'AI::MXNet::LinAlg::Symbol'  }
 sub nd     { 'AI::MXNet::LinAlg::NDArray' }
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Metric.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Metric.pm
index 3b9345d..b6e91ae 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Metric.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Metric.pm
@@ -24,7 +24,11 @@ use JSON::PP;
 
 =head1 NAME
 
-    AI::MXNet::Metric - Online evaluation metric module.
+    AI::MXNet::Metric - Evaluation Metric API.
+=head1 DESCRIPTION
+
+    This module hosts all the evaluation metrics available to evaluate the performance of a learned model.
+    L<Python Docs|http://mxnet.incubator.apache.org/api/python/metric/metric.html>
 =cut
 
 # Check to see if the two arrays are the same size.
@@ -61,11 +65,6 @@ func check_label_shapes(
     ) unless $pred_shape == $label_shape;
 }
 
-=head1 DESCRIPTION
-
-    Base class of all evaluation metrics.
-=cut
-
 package AI::MXNet::EvalMetric;
 use Mouse;
 use overload '""' => sub {
@@ -232,11 +231,41 @@ method get()
 # CLASSIFICATION METRICS
 ########################
 
+=head1 NAME
+
+    AI::MXNet::Accuracy - Computes accuracy classification score.
+=cut
+
+=head1 DESCRIPTION
+
+    The accuracy score is defined as
+
+    accuracy(y, y^) = (1/n) * sum(i=0..n−1) { y^(i)==y(i) }
+
+    Parameters:
+    axis (Int, default=1) – The axis that represents classes.
+    name (Str, default='accuracy') – Name of this metric instance for display.
+
+    pdl> use AI::MXNet qw(mx)
+    pdl> $predicts = [mx->nd->array([[0.3, 0.7], [0, 1.], [0.4, 0.6]])]
+    pdl> $labels   = [mx->nd->array([[0, 1, 1]])]
+    pdl> $acc = mx->metric->Accuracy()
+    pdl> $acc->update($labels, $predicts)
+    pdl> use Data::Dumper
+    pdl> print Dumper([$acc->get])
+    $VAR1 = [
+          'accuracy',
+          '0.666666666666667'
+    ];
+
+=cut
+
 package AI::MXNet::Accuracy;
 use Mouse;
 use AI::MXNet::Base;
 extends 'AI::MXNet::EvalMetric';
 has '+name'   => (default => 'accuracy');
+has 'axis'    => (is => 'ro', isa => 'Int', default => 1);
 
 method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray] $preds)
 {
@@ -245,22 +274,74 @@ method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray]
         my ($label, $pred_label) = @$_;
         if(join(',', @{$pred_label->shape}) ne join(',', @{$label->shape}))
         {
-            $pred_label = AI::MXNet::NDArray->argmax_channel($pred_label);
+            $pred_label = AI::MXNet::NDArray->argmax_channel($pred_label, { axis => $self->axis });
         }
-        AI::MXNet::Metric::check_label_shapes($label, $pred_label);
         my $sum = ($pred_label->aspdl->flat == $label->aspdl->flat)->sum;
         $self->sum_metric($self->sum_metric + $sum);
         $self->num_inst($self->num_inst + $pred_label->size);
     }
 }
 
+=head1 NAME
+
+    AI::MXNet::TopKAccuracy - Computes top k predictions accuracy.
+=cut
+
+=head1 DESCRIPTION
+
+    TopKAccuracy differs from Accuracy in that it considers the prediction
+    to be True as long as the ground truth label is in the top K predicated labels.
+
+    If top_k = 1, then TopKAccuracy is identical to Accuracy.
+
+    Parameters:	
+    top_k(Int, default 1) – Whether targets are in top k predictions.
+    name (Str, default 'top_k_accuracy') – Name of this metric instance for display.
+
+    use AI::MXNet qw(mx);
+    $top_k = 3;
+    $predicts = [mx->nd->array(
+      [[0.80342804, 0.5275223 , 0.11911147, 0.63968144, 0.09092526,
+        0.33222568, 0.42738095, 0.55438581, 0.62812652, 0.69739294],
+       [0.78994969, 0.13189035, 0.34277045, 0.20155961, 0.70732423,
+        0.03339926, 0.90925004, 0.40516066, 0.76043547, 0.47375838],
+       [0.28671892, 0.75129249, 0.09708994, 0.41235779, 0.28163896,
+        0.39027778, 0.87110921, 0.08124512, 0.55793117, 0.54753428],
+       [0.33220307, 0.97326881, 0.2862761 , 0.5082575 , 0.14795074,
+        0.19643398, 0.84082001, 0.0037532 , 0.78262101, 0.83347772],
+       [0.93790734, 0.97260166, 0.83282304, 0.06581761, 0.40379256,
+        0.37479349, 0.50750135, 0.97787696, 0.81899021, 0.18754124],
+       [0.69804812, 0.68261077, 0.99909815, 0.48263116, 0.73059268,
+        0.79518236, 0.26139168, 0.16107376, 0.69850315, 0.89950917],
+       [0.91515562, 0.31244902, 0.95412616, 0.7242641 , 0.02091039,
+        0.72554552, 0.58165923, 0.9545687 , 0.74233195, 0.19750339],
+       [0.94900651, 0.85836332, 0.44904621, 0.82365038, 0.99726878,
+        0.56413064, 0.5890016 , 0.42402702, 0.89548786, 0.44437266],
+       [0.57723744, 0.66019353, 0.30244304, 0.02295771, 0.83766937,
+        0.31953292, 0.37552193, 0.18172362, 0.83135182, 0.18487429],
+       [0.96968683, 0.69644561, 0.60566253, 0.49600661, 0.70888438,
+        0.26044186, 0.65267488, 0.62297362, 0.83609334, 0.3572364 ]]
+    )];
+    $labels = [mx->nd->array([2, 6, 9, 2, 3, 4, 7, 8, 9, 6])];
+    $acc = mx->metric->TopKAccuracy(top_k=>$top_k);
+    $acc->update($labels, $predicts);
+    use Data::Dumper;
+    print Dumper([$acc->get]);
+    $VAR1 = [
+          'top_k_accuracy_3',
+          '0.3'
+    ];
+
+
+=cut
+
 package AI::MXNet::TopKAccuracy;
 use Mouse;
 use List::Util qw/min/;
 use AI::MXNet::Base;
 extends 'AI::MXNet::EvalMetric';
 has '+name'   => (default => 'top_k_accuracy');
-has 'top_k' => (is => 'rw', isa => 'int', default => 1);
+has 'top_k' => (is => 'rw', isa => 'Int', default => 1);
 method python_constructor_arguments() { ['top_k'] }
 
 sub BUILD
@@ -302,71 +383,250 @@ method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray]
     }
 }
 
-# Calculate the F1 score of a binary classification problem.
-package AI::MXNet::F1;
-use Mouse;
-use AI::MXNet::Base;
-extends 'AI::MXNet::EvalMetric';
-has '+name'   => (default => 'f1');
-
-method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray] $preds)
-{
-    AI::MXNet::Metric::check_label_shapes($labels, $preds);
-    for(zip($labels, $preds)) {
-        my ($label, $pred_label) = @$_;
-        AI::MXNet::Metric::check_label_shapes($label, $pred_label);
-        $pred_label = $pred_label->aspdl->maximum_ind;
+package _BinaryClassificationMetrics {
+    use Mouse;
+    #Private container class for classification metric statistics. True/false positive and
+    # true/false negative counts are sufficient statistics for various classification metrics.
+    #This class provides the machinery to track those statistics across mini-batches of
+    #(label, prediction) pairs.
+    has [qw/true_positives
+            false_negatives
+            false_positives
+            true_negatives/] => (is => 'rw', isa => 'Int', default => 0);
+
+    method update_binary_stats(AI::MXNet::NDArray $label, AI::MXNet::NDArray $pred)
+    {
+        $pred = AI::MXNet::NDArray->argmax($pred, { axis => 1 })->aspdl;
         $label = $label->astype('int32')->aspdl;
-        confess("F1 currently only supports binary classification.")
-            if $label->uniq->shape->at(0) > 2;
-        my ($true_positives, $false_positives, $false_negatives) = (0,0,0);
-        for(zip($pred_label->unpdl, $label->unpdl)) {
-            my ($y_pred, $y_true) = @$_;
-            if($y_pred == 1 and $y_true == 1)
-            {
-                $true_positives += 1;
-            }
-            elsif($y_pred == 1 and $y_true == 0)
-            {
-                $false_positives += 1;
-            }
-            elsif($y_pred == 0 and $y_true == 1)
-            {
-                $false_negatives += 1;
-            }
+
+        AI::MXNet::Metric::check_label_shapes($label, $pred);
+        if($label->uniq->len > 2)
+        {
+            confess("Currently only support binary classification.");
         }
-        my $precision;
-        my $recall;
-        if($true_positives + $false_positives > 0)
+
+        my $pred_true = ($pred == 1);
+        my $pred_false = 1 - $pred_true;
+        my $label_true = ($label == 1);
+        my $label_false = 1 - $label_true;
+
+        $self->true_positives($self->true_positives + ($pred_true * $label_true)->sum);
+        $self->false_positives($self->false_positives + ($pred_true * $label_false)->sum);
+        $self->false_negatives($self->false_negatives + ($pred_false * $label_true)->sum);
+        $self->true_negatives($self->true_negatives + ($pred_false * $label_false)->sum);
+    }
+
+    method precision()
+    {
+        if($self->true_positives + $self->false_positives > 0)
         {
-            $precision = $true_positives / ($true_positives + $false_positives);
+            return $self->true_positives / ($self->true_positives + $self->false_positives);
         }
         else
         {
-            $precision = 0;
+            return 0;
         }
-        if($true_positives + $false_negatives > 0)
+    }
+
+    method recall()
+    {
+        if($self->true_positives + $self->false_negatives > 0)
         {
-            $recall = $true_positives / ($true_positives +  $false_negatives);
+            return $self->true_positives / ($self->true_positives + $self->false_negatives);
         }
         else
         {
-            $recall = 0;
+            return 0;
         }
-        my $f1_score;
-        if($precision + $recall > 0)
+    }
+
+    method fscore()
+    {
+        if($self->precision + $self->recall > 0)
         {
-            $f1_score = 2 * $precision * $recall / ($precision + $recall);
+            return 2 * $self->precision * $self->recall / ($self->precision + $self->recall);
         }
         else
         {
-            $f1_score = 0;
+            return 0;
+        }
+    }
+
+    method matthewscc()
+    {
+        if(not $self->total_examples)
+        {
+            return 0;
+        }
+        my @terms = (
+            $self->true_positives + $self->false_positives,
+            $self->true_positives + $self->false_negatives,
+            $self->true_negatives + $self->false_positives,
+            $self->true_negatives + $self->false_negatives
+        );
+        my $denom = 1;
+        for my $t (grep { $_ } @terms)
+        {
+            $denom *= $t;
+        }
+        return (($self->true_positives * $self->true_negatives) - ($self->false_positives * $self->false_negatives)) / sqrt($denom);
+    }
+
+    method total_examples()
+    {
+        return $self->false_negatives + $self->false_positives +
+               $self->true_negatives + $self->true_positives;
+    }
+
+    method reset_stats()
+    {
+        $self->false_positives(0);
+        $self->false_negatives(0);
+        $self->true_positives(0);
+        $self->true_negatives(0);
+    }
+};
+
+=head1 NAME
+
+    AI::MXNet::F1 - Calculate the F1 score of a binary classification problem.
+=cut
+
+=head1 DESCRIPTION
+
+    The F1 score is equivalent to harmonic mean of the precision and recall,
+    where the best value is 1.0 and the worst value is 0.0. The formula for F1 score is:
+
+    F1 = 2 * (precision * recall) / (precision + recall)
+    The formula for precision and recall is:
+
+    precision = true_positives / (true_positives + false_positives)
+    recall    = true_positives / (true_positives + false_negatives)
+    Note:
+
+    This F1 score only supports binary classification.
+
+    Parameters:
+    name (Str, default 'f1') – Name of this metric instance for display.
+    average (Str, default 'macro') –
+    Strategy to be used for aggregating across mini-batches.
+    “macro”: average the F1 scores for each batch. “micro”: compute a single F1 score across all batches.
+
+
+    $predicts = [mx.nd.array([[0.3, 0.7], [0., 1.], [0.4, 0.6]])];
+    $labels   = [mx.nd.array([0., 1., 1.])];
+    $f1 = mx->metric->F1();
+    $f1->update($labels, $predicts);
+    print $f1->get;
+    f1 0.8
+
+=cut
+
+package AI::MXNet::F1;
+use Mouse;
+use AI::MXNet::Base;
+extends 'AI::MXNet::EvalMetric';
+has '+name'   => (default => 'f1');
+has 'average' => (is => 'ro', isa => 'Str', default => 'macro');
+has 'metrics' => (is => 'rw', init_arg => undef, default => sub { _BinaryClassificationMetrics->new });
+has 'method'  => (is => 'ro', init_arg => undef, default => 'fscore');
+method python_constructor_arguments() { [qw/name average/] }
+
+method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray] $preds)
+{
+    my $method = $self->method;
+    AI::MXNet::Metric::check_label_shapes($labels, $preds);
+    for(zip($labels, $preds)) {
+        my ($label, $pred) = @$_;
+        $self->metrics->update_binary_stats($label, $pred);
+        if($self->average eq "macro")
+        {
+            $self->sum_metric($self->sum_metric + $self->metrics->$method);
+            $self->num_inst($self->num_inst + 1);
+            $self->metrics->reset_stats();
+        }
+        else
+        {
+            $self->sum_metric($self->metrics->fscore * $self->metrics->total_examples);
+            $self->num_inst($self->metrics->total_examples);
         }
-        $self->sum_metric($self->sum_metric + $f1_score);
-        $self->num_inst($self->num_inst + 1);
     }
 }
 
+method reset()
+{
+    $self->sum_metric(0);
+    $self->num_inst(0);
+    $self->metrics->reset_stats();
+}
+
+=head1 NAME
+
+    AI::MXNet::MCC - Computes the Matthews Correlation Coefficient of a binary classification problem.
+=cut
+
+=head1 DESCRIPTION
+
+    While slower to compute than F1 the MCC can give insight that F1 or Accuracy cannot.
+    For instance, if the network always predicts the same result
+    then the MCC will immeadiately show this. The MCC is also symetric with respect
+    to positive and negative categorization, however, there needs to be both
+    positive and negative examples in the labels or it will always return 0.
+    MCC of 0 is uncorrelated, 1 is completely correlated, and -1 is negatively correlated.
+
+        MCC = (TP * TN - FP * FN)/sqrt( (TP + FP)*( TP + FN )*( TN + FP )*( TN + FN ) )
+
+    where 0 terms in the denominator are replaced by 1.
+
+    This version of MCC only supports binary classification.
+
+    Parameters
+    ----------
+    name : str, 'mcc'
+        Name of this metric instance for display.
+    average : str, default 'macro'
+        Strategy to be used for aggregating across mini-batches.
+            "macro": average the MCC for each batch.
+            "micro": compute a single MCC across all batches.
+
+    Examples
+    --------
+    In this example the network almost always predicts positive
+    >>> $false_positives = 1000
+    >>> $false_negatives = 1
+    >>> $true_positives = 10000
+    >>> $true_negatives = 1
+    >>> $predicts = [mx->nd->array(
+        [
+            ([.3, .7])x$false_positives,
+            ([.7, .3])x$true_negatives,
+            ([.7, .3])x$false_negatives,
+            ([.3, .7])xtrue_positives
+        ]
+    )];
+    >>> $labels  = [mx->nd->array(
+        [
+            (0)x($false_positives + $true_negatives),
+            (1)x($false_negatives + $true_positives)
+        ]
+    )];
+    >>> $f1 = mx->metric->F1();
+    >>> $f1->update($labels, $predicts);
+    >>> $mcc = mx->metric->MCC()
+    >>> $mcc->update($labels, $predicts)
+    >>> print $f1->get();
+    f1 0.95233560306652054
+    >>> print $mcc->get();
+    mcc 0.01917751877733392
+
+=cut
+
+package AI::MXNet::MCC;
+use Mouse;
+extends 'AI::MXNet::F1';
+has '+name'   => (default => 'mcc');
+has '+method' => (default => 'matthewscc');
+
 package AI::MXNet::Perplexity;
 use Mouse;
 use AI::MXNet::Base;
@@ -385,12 +645,13 @@ around BUILDARGS => sub {
 
 =head1 NAME
 
-    AI::MXNet::Perplexity
+    AI::MXNet::Perplexity - Calculate perplexity.
 =cut
 
 =head1 DESCRIPTION
 
-    Calculate perplexity.
+    Perplexity is a measurement of how well a probability distribution or model predicts a sample.
+    A low perplexity indicates the model is good at predicting the sample.
 
     Parameters
     ----------
@@ -402,6 +663,14 @@ around BUILDARGS => sub {
         The axis from prediction that was used to
         compute softmax. By default uses the last
         axis.
+
+    $predicts = [mx->nd->array([[0.3, 0.7], [0, 1.], [0.4, 0.6]])];
+    $labels   = [mx->nd->array([0, 1, 1])];
+    $perp = mx->metric->Perplexity(ignore_label=>undef);
+    $perp->update($labels, $predicts);
+    print $perp->get()
+    Perplexity 1.77109762851559
+
 =cut
 
 method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray] $preds)
@@ -440,7 +709,21 @@ method get()
 # REGRESSION METRICS
 ####################
 
-# Calculate Mean Absolute Error loss
+=head1 NAME
+
+    AI::MXNet::MAE - Calculate Mean Absolute Error loss
+=head1 DESCRIPTION
+
+    >>> $predicts = [mx->nd->array([3, -0.5, 2, 7])->reshape([4,1])]
+    >>> $labels = [mx->nd->array([2.5, 0.0, 2, 8])->reshape([4,1])]
+    >>> $mean_absolute_error = mx->metric->MAE()
+    >>> $mean_absolute_error->update($labels, $predicts)
+    >>> print $mean_absolute_error->get()
+    ('mae', 0.5)
+
+=cut
+
+
 package AI::MXNet::MAE;
 use Mouse;
 use AI::MXNet::Base;
@@ -463,7 +746,20 @@ method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray]
     }
 }
 
-# Calculate Mean Squared Error loss
+=head1 NAME
+
+    AI::MXNet::MSE - Calculate Mean Squared Error loss
+=head1 DESCRIPTION
+
+    >>> $predicts = [mx->nd->array([3, -0.5, 2, 7])->reshape([4,1])]
+    >>> $labels = [mx->nd->array([2.5, 0.0, 2, 8])->reshape([4,1])]
+    >>> $mean_squared_error = mx->metric->MSE()
+    >>> $mean_squared_error->update($labels, $predicts)
+    >>> print $mean_squared_error->get()
+    ('mse', 0.375)
+
+=cut
+
 package AI::MXNet::MSE;
 use Mouse;
 use AI::MXNet::Base;
@@ -486,7 +782,20 @@ method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray]
     }
 }
 
-# Calculate Root Mean Squred Error loss
+=head1 NAME
+
+    AI::MXNet::RMSE - Calculate Root Mean Squred Error loss
+=head1 DESCRIPTION
+
+    >>> $predicts = [mx->nd->array([3, -0.5, 2, 7])->reshape([4,1])]
+    >>> $labels = [mx->nd->array([2.5, 0.0, 2, 8])->reshape([4,1])]
+    >>> $root_mean_squared_error = mx->metric->RMSE()
+    >>> $root_mean_squared_error->update($labels, $predicts)
+    >>> print $root_mean_squared_error->get()
+    'rmse', 0.612372457981
+
+=cut
+
 package AI::MXNet::RMSE;
 use Mouse;
 use AI::MXNet::Base;
@@ -509,6 +818,21 @@ method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray]
     }
 }
 
+
+=head1 NAME
+
+    AI::MXNet::CrossEntropy - Calculate Cross Entropy loss
+=head1 DESCRIPTION
+
+    >>> $predicts = [mx->nd->array([[0.3, 0.7], [0, 1.], [0.4, 0.6]])]
+    >>> $labels   = [mx->nd->array([0, 1, 1])]
+    >>> $ce = mx->metric->CrossEntropy()
+    >>> $ce->update($labels, $predicts)
+    >>> print $ce->get()
+    ('cross-entropy', 0.57159948348999023)
+
+=cut
+
 # Calculate Cross Entropy loss
 package AI::MXNet::CrossEntropy;
 use Mouse;
@@ -537,6 +861,26 @@ method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray]
     }
 }
 
+=head1 NAME
+
+    AI::MXNet::NegativeLogLikelihood - Computes the negative log-likelihood loss.
+=head1 DESCRIPTION
+
+    >>> $predicts = [mx->nd->array([[0.3, 0.7], [0, 1.], [0.4, 0.6]])]
+    >>> $labels   = [mx->nd->array([0, 1, 1])]
+    >>> $nll_loss = mx->metric->NegativeLogLikelihood
+    >>> $nll_loss->update($labels, $predicts)
+    >>> print $nll_loss->get()
+    ('cross-entropy', 0.57159948348999023)
+
+=cut
+
+package AI::MXNet::NegativeLogLikelihood;
+use Mouse;
+use AI::MXNet::Base;
+extends 'AI::MXNet::CrossEntropy';
+has '+name'   => (default => 'nll_loss');
+
 package AI::MXNet::PearsonCorrelation;
 use Mouse;
 use AI::MXNet::Base;
@@ -545,7 +889,7 @@ has '+name'   => (default => 'pearson-correlation');
 
 =head1 NAME
 
-    AI::MXNet::PearsonCorrelation
+    AI::MXNet::PearsonCorrelation - Computes Pearson correlation.
 =cut
 
 =head1 DESCRIPTION
@@ -594,7 +938,7 @@ has '+name'   => (default => 'loss');
 
 =head1 NAME
 
-    AI::MXNet::Loss
+    AI::MXNet::Loss - Dummy metric for directly printing loss.
 =cut
 
 =head1 DESCRIPTION
@@ -621,7 +965,7 @@ use Mouse;
 
 =head1 NAME
 
-    AI::MXNet::Confidence
+    AI::MXNet::Confidence - Accuracy by confidence buckets.
 =cut
 
 =head1 DESCRIPTION
@@ -717,7 +1061,7 @@ sub get
 
 =head1 NAME
 
-    AI::MXNet::CustomMetric
+    AI::MXNet::CustomMetric - Custom evaluation metric that takes a sub ref.
 =cut
 
 =head1 DESCRIPTION
@@ -779,7 +1123,9 @@ my %metrics = qw/
     accuracy            AI::MXNet::Accuracy
     ce                  AI::MXNet::CrossEntropy
     crossentropy        AI::MXNet::CrossEntropy
+    nll_loss            AI::MXNet::NegativeLogLikelihood
     f1                  AI::MXNet::F1
+    mcc                 AI::MXNet::MCC
     mae                 AI::MXNet::MAE
     mse                 AI::MXNet::MSE
     rmse                AI::MXNet::RMSE
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Module.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Module.pm
index 16c9a92..38c2ae6 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Module.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Module.pm
@@ -268,28 +268,28 @@ method BucketingModule(@args) { return AI::MXNet::Module::Bucketing->new(@args)
 
         Parameters
         ----------
-        prefix : str
+        $prefix : Str
             path prefix of saved model files. You should have
             "prefix-symbol.json", "prefix-xxxx.params", and
             optionally "prefix-xxxx.states", where xxxx is the
             epoch number.
-        epoch : int
+        $epoch : Int
             epoch to load.
-        load_optimizer_states : bool
+        $load_optimizer_states=0 : Bool
             whether to load optimizer states. Checkpoint needs
             to have been made with save_optimizer_states=True.
-        data_names : array ref of str
+        :$data_names : array ref of str
             Default is ['data'] for a typical model used in image classification.
-        label_names : array ref of str
+        :$label_names : array ref of str
             Default is ['softmax_label'] for a typical model used in image
             classification.
-        logger : Logger
+        :$logger : Logger
             Default is AI::MXNet::Logging.
-        context : Context or list of Context
+        :$context : Context or list of Context
             Default is cpu(0).
-        work_load_list : array ref of number
+        :$work_load_list : array ref of number
             Default is undef, indicating an uniform workload.
-        fixed_param_names: array ref of str
+        :$fixed_param_names: array ref of str
             Default is undef, indicating no network parameters are fixed.
 =cut
 
@@ -319,11 +319,11 @@ method load(
 
     Parameters
     ----------
-    prefix : str
+    $prefix : Str
         The file prefix to checkpoint to
-    epoch : int
+    $epoch : Int
         The current epoch number
-    save_optimizer_states : bool
+    $save_optimizer_states=0 : Bool
         Whether to save optimizer states for later training
 =cut
 
@@ -348,16 +348,16 @@ method save_checkpoint(Str $prefix, Int $epoch, Bool $save_optimizer_states=0)
 
     Parameters
     ----------
-    prefix : str
+    $prefix : Str
         Prefix of model name.
-    epoch : int
+    $epoch : Int
         The epoch number of the model.
-    symbol : AI::MXNet::Symbol
+    $symbol : AI::MXNet::Symbol
         The input symbol
-    arg_params : hash ref of str to AI::MXNet::NDArray
-        Model parameter, hash ref of name to AI::MXNet::NDArray of net's weights.
-    aux_params : hash ref of str to NDArray
-        Model parameter, hash ref of name to AI::MXNet::NDArray of net's auxiliary states.
+    $arg_params : HashRef[AI::MXNet::NDArray]
+        Model's parameters, hash ref of name to AI::MXNet::NDArray of net's weights.
+    $aux_params : HashRef[AI::MXNet::NDArray]
+        Model's parameters, hash ref of name to AI::MXNet::NDArray of net's auxiliary states.
     Notes
     -----
     - prefix-symbol.json will be saved for symbol.
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Monitor.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Monitor.pm
index 0e46c31..76fdfd2 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Monitor.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Monitor.pm
@@ -30,13 +30,13 @@ use AI::MXNet::Base;
 
     Parameters
     ----------
-    interval : int
+    interval : Int
         Number of batches between printing.
-    stat_func : function
+    stat_func : CodeRef
         a function that computes statistics of tensors.
         Takes a NDArray and returns a NDArray. defaults to mean
         absolute value |x|/size(x).
-    pattern : str
+    pattern : Str
         A regular expression specifying which tensors to monitor.
         Only tensors with names that match name_pattern will be included.
         For example, '.*weight|.*output' will print all weights and outputs;
@@ -94,7 +94,7 @@ has 'stat_helper'          => (
 
     Parameters
     ----------
-    exe : AI::MXNet::Executor
+    $exe : AI::MXNet::Executor
         the Executor (returned by $symbol->bind) to install to.
 =cut
 
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/NDArray.pm b/perl-package/AI-MXNet/lib/AI/MXNet/NDArray.pm
index 3177a37..8739531 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/NDArray.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/NDArray.pm
@@ -22,6 +22,41 @@ package AI::MXNet::NDArray;
     AI::MXNet::NDArray - Multidimensional tensor object of MXNet.
 =cut
 
+=head1 DESCRIPTION
+
+    AI::MXNet::NDArray - Imperative tensor operations on CPU/GPU
+    In AI::MXNet, NDArray is the core data structure for all mathematical computations.
+    An NDArray represents a multidimensional, fixed-size homogenous array.
+    If you’re familiar with the PDL, you might notice some similarities.
+    However, NDArray is row-major, unlike the PDL that is column-major.
+    Like the PDL, MXNet’s NDArray enables imperative computation.
+
+    Some NDArray advandages compared to PDL:
+    MXNet’s NDArray supports fast execution on a wide range of hardware configurations, including CPU, GPU, and multi-GPU machines.
+    MXNet also scales to distributed systems in the cloud.
+    MXNet’s NDArray executes code lazily, allowing it to automatically parallelize multiple operations across the available hardware.
+
+    An NDArray is a multidimensional array of numbers with the same type.
+    We could represent the coordinates of a point in 3D space, e.g. [2, 1, 6] as a 1D array with shape (3).
+    Similarly, we could represent a 2D array.
+    Below, we present an array with length 2 along the first axis and length 3 along the second axis.
+
+    [[0, 1, 2]
+     [3, 4, 5]]
+    Note that here the use of “dimension” is overloaded. When we say a 2D array, we mean an array with 2 axes, not an array with two components.
+
+    Each NDArray supports some important attributes that you’ll often want to query:
+
+    $ndarray->shape: The dimensions of the array.
+    It is an array ref of integers indicating the length of the array along each axis.
+    For a matrix with $n rows and $m columns, its shape will be [$n, $m].
+    $ndarray->dtype: A string describing the type of its elements.
+    Dtype (defined in AI::MXNet::Types) is one of (float32 float64 float16 uint8 int8 int32 int64)
+    $ndarray->size: The total number of components in the array - equal to the product of the components of its shape.
+    $ndarray->context: The device on which this array is stored, represented by an object of AI::MXNet::Context class, e.g. cpu() or gpu(1).
+
+=cut
+
 use strict;
 use warnings;
 use AI::MXNet::Base;
@@ -693,35 +728,6 @@ method onehot_encode(AI::MXNet::NDArray $indices, AI::MXNet::NDArray $out)
     return __PACKAGE__->_onehot_encode($indices, $out, { out => $out });
 }
 
-=head2 _ufunc_helper(lhs, rhs, fn_array, lfn_scalar, rfn_scalar):
-
-    Helper function for element-wise operation
-    The function will perform numpy-like broadcasting if needed and call different functions
-
-    Parameters
-    ----------
-    lhs : NDArray or numeric value
-        left hand side operand
-
-    rhs : NDArray or numeric value
-        right hand side operand
-
-    fn_array : function
-        function to be called if both lhs and rhs are of NDArray type
-
-    lfn_scalar : function
-        function to be called if lhs is NDArray while rhs is numeric value
-
-    rfn_scalar : function
-        function to be called if lhs is numeric value while rhs is NDArray;
-        if none is provided, then the function is commutative, so rfn_scalar is equal to lfn_scalar
-
-    Returns
-    -------
-    out: NDArray
-        result array
-=cut
-
 sub  _ufunc_helper
 {
     my ($lhs, $rhs, $fn_array, $lfn_scalar, $rfn_scalar, $reverse) = @_;
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/NDArray/Sparse.pm b/perl-package/AI-MXNet/lib/AI/MXNet/NDArray/Sparse.pm
index bb5171c..e0257fd 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/NDArray/Sparse.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/NDArray/Sparse.pm
@@ -356,9 +356,6 @@ extends 'AI::MXNet::NDArray::Sparse';
     csr_matrix: Several ways to construct a CSRNDArray
 =cut
 
-#    def __reduce__(self):
-#        return CSRNDArray, (None,), super(CSRNDArray, self).__getstate__()
-
 use overload '+=' => sub { ($_[0] + $_[1])->copyto($_[0]) },
              '-=' => sub { ($_[0] - $_[1])->copyto($_[0]) },
              '*=' => sub { ($_[0] * $_[1])->copyto($_[0]) },
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Optimizer.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Optimizer.pm
index fd13164..ad0e455 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Optimizer.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Optimizer.pm
@@ -63,14 +63,14 @@ method register()
 
         Parameters
         ----------
-        name: str
+        $name: Str
             Name of required optimizer. Should be the name
             of a subclass of Optimizer. Case insensitive.
 
-        rescale_grad : float
+        :$rescale_grad : Num
             Rescaling factor on gradient. Normally should be 1/batch_size.
 
-        kwargs: dict
+        %kwargs: Hash
             Parameters for optimizer
 
         Returns
@@ -290,25 +290,25 @@ method _get_wd(Index $index)
 
     Parameters
     ----------
-    learning_rate : float, optional
+    learning_rate : Num, optional
         learning_rate of SGD
 
-    momentum : float, optional
+    momentum : Num, optional
        momentum value
 
-    wd : float, optional
+    wd : Num, optional
         L2 regularization coefficient add to all the weights
 
-    rescale_grad : float, optional
+    rescale_grad : Num, optional
         rescaling factor of gradient. Normally should be 1/batch_size.
 
-    clip_gradient : float, optional
+    clip_gradient : Num, optional
         clip gradient in range [-clip_gradient, clip_gradient]
 
-    param_idx2name : hash of string/int to float, optional
+    param_idx2name : hash ref of Str/Int to Num, optional
         special treat weight decay in parameter ends with bias, gamma, and beta
 
-    multi_precision: bool, optional
+    multi_precision: Bool, optional
         Flag to control the internal precision of the optimizer.
         False results in using the same precision as the weights (default),
         True makes internal 32-bit copy of the weights and applies gradients
@@ -438,18 +438,15 @@ __PACKAGE__->register;
 
     See the original paper at: https://jeremybernste.in/projects/amazon/signum.pdf
 
-    For details of the update algorithm see
-    :class:`~mxnet.ndarray.signsgd_update` and :class:`~mxnet.ndarray.signum_update`.
-
     This optimizer accepts the following parameters in addition to those accepted
-    by :class:`.Optimizer`.
+    by AI::MXNet::Optimizer
 
     Parameters
     ----------
-    momentum : float, optional
+    momentum : Num, optional
        The momentum value.
-    wd_lh : float, optional
-       The amount of decoupled weight decay regularization, see details in the original paper at:\
+    wd_lh : Num, optional
+       The amount of decoupled weight decay regularization, see details in the original paper at:
        https://arxiv.org/abs/1711.05101
 =cut
 
@@ -536,11 +533,11 @@ __PACKAGE__->register;
 
     Parameters
     ----------
-    beta1 : float, optional
+    beta1 : Num, optional
         0 < beta1 < 1. Generally close to 0.5.
-    beta2 : float, optional
+    beta2 : Num, optional
         0 < beta2 < 1. Generally close to 1.
-    epsilon : float, optional
+    epsilon : Num, optional
         Small value to avoid division by 0.
 =cut
 
@@ -604,12 +601,12 @@ __PACKAGE__->register;
 
     Parameters
     ----------
-    momentum : float, optional
+    momentum : Num, optional
        The momentum value.
-    multi_precision: bool, optional
+    multi_precision: Bool, optional
        Flag to control the internal precision of the optimizer.
-       ``False`` results in using the same precision as the weights (default),
-       ``True`` makes internal 32-bit copy of the weights and applies gradients
+       0 results in using the same precision as the weights (default),
+       1 makes internal 32-bit copy of the weights and applies gradients
                 in 32-bit precision even if actual weights used in the model have lower precision.`<
                 Turning this on can improve convergence and accuracy when training with float16.
     warmup_strategy: string ('linear', 'power2', 'sqrt'. , 'lars'   default : 'linear')
@@ -896,26 +893,26 @@ extends 'AI::MXNet::Optimizer';
 
     Parameters
     ----------
-    learning_rate : float, optional
+    learning_rate : Num, optional
         learning_rate of SGD
 
-    momentum : float, optional
+    momentum : Num, optional
        momentum value
 
-    lamda : float, optional
+    lamda : NUm, optional
        scale DC value
 
-    wd : float, optional
+    wd : Num, optional
         L2 regularization coefficient add to all the weights
 
-    rescale_grad : float, optional
+    rescale_grad : Num, optional
         rescaling factor of gradient. Normally should be 1/batch_size.
 
-    clip_gradient : float, optional
+    clip_gradient : Num, optional
         clip gradient in range [-clip_gradient, clip_gradient]
 
-    param_idx2name : hash ref of string/int to float, optional
-        special treat weight decay in parameter ends with bias, gamma, and beta
+    param_idx2name : hash ref of Str/Int to Num, optional
+        special threating of weight decay for parameters that end with bias, gamma, and beta
 =cut
 has 'momentum'        => (is => 'ro', isa => 'Num', default => 0);
 has 'lamda'           => (is => 'ro', isa => 'Num', default => 0.04);
@@ -1091,16 +1088,16 @@ __PACKAGE__->register;
 
     Parameters
     ----------
-    learning_rate : float, optional
+    learning_rate : Num, optional
         learning_rate of SGD
 
-    wd : float, optional
+    wd : Num, optional
         L2 regularization coefficient add to all the weights
 
-    rescale_grad : float, optional
+    rescale_grad : Num, optional
         rescaling factor of gradient. Normally should be 1/batch_size.
 
-    clip_gradient : float, optional
+    clip_gradient : Num, optional
         clip gradient in range [-clip_gradient, clip_gradient]
 =cut
 
@@ -1158,29 +1155,26 @@ __PACKAGE__->register;
        *Adam: A Method for Stochastic Optimization*,
        http://arxiv.org/abs/1412.6980
 
-    the code in this class was adapted from
-    https://github.com/mila-udem/blocks/blob/master/blocks/algorithms/__init__.py#L765
-
     Parameters
     ----------
-    learning_rate : float, optional
+    learning_rate : Num, optional
         Step size.
         Default value is set to 0.001.
-    beta1 : float, optional
+    beta1 : Num, optional
         Exponential decay rate for the first moment estimates.
         Default value is set to 0.9.
-    beta2 : float, optional
+    beta2 : Num, optional
         Exponential decay rate for the second moment estimates.
         Default value is set to 0.999.
-    epsilon : float, optional
+    epsilon : Num, optional
         Default value is set to 1e-8.
 
-    wd : float, optional
+    wd : NUm, optional
         L2 regularization coefficient add to all the weights
-    rescale_grad : float, optional
+    rescale_grad : Num, optional
         rescaling factor of gradient. Normally should be 1/batch_size.
 
-    clip_gradient : float, optional
+    clip_gradient : Num, optional
         clip gradient in range [-clip_gradient, clip_gradient]
 =cut
 package AI::MXNet::Adam;
@@ -1271,21 +1265,21 @@ __PACKAGE__->register;
 
     Parameters
     ----------
-    learning_rate : float, optional
+    learning_rate : Num, optional
         Step size.
         Default value is set to 0.05.
 
-    wd : float, optional
+    wd : Num, optional
         L2 regularization coefficient add to all the weights
 
-    rescale_grad : float, optional
+    rescale_grad : Num, optional
         rescaling factor of gradient. Normally should be 1/batch_size.
 
-    eps: float, optional
+    eps: Num, optional
         A small float number to make the updating processing stable
         Default value is set to 1e-7.
 
-    clip_gradient : float, optional
+    clip_gradient : Num, optional
         clip gradient in range [-clip_gradient, clip_gradient]
 =cut
 package AI::MXNet::AdaGrad;
@@ -1361,27 +1355,27 @@ __PACKAGE__->register;
 
     Parameters
     ----------
-    learning_rate : float, optional
+    learning_rate : Num, optional
         Step size.
         Default value is set to 0.001.
-    gamma1: float, optional
+    gamma1: Num, optional
         decay factor of moving average for gradient^2.
         Default value is set to 0.9.
-    gamma2: float, optional
+    gamma2: Num, optional
         "momentum" factor.
         Default value if set to 0.9.
         Only used if centered=True
-    epsilon : float, optional
+    epsilon : Num, optional
         Default value is set to 1e-8.
-    centered : bool, optional
+    centered : Bool, optional
         Use Graves or Tielemans & Hintons version of RMSProp
-    wd : float, optional
+    wd : Num, optional
         L2 regularization coefficient add to all the weights
-    rescale_grad : float, optional
+    rescale_grad : Num, optional
         rescaling factor of gradient.
-    clip_gradient : float, optional
+    clip_gradient : Num, optional
         clip gradient in range [-clip_gradient, clip_gradient]
-    clip_weights : float, optional
+    clip_weights : Num, optional
         clip weights in range [-clip_weights, clip_weights]
 =cut
 
@@ -1508,15 +1502,15 @@ __PACKAGE__->register;
 
     Parameters
     ----------
-    rho: float
+    rho: Num
         Decay rate for both squared gradients and delta x
-    epsilon : float
+    epsilon : Num
         The constant as described in the thesis
-    wd : float
+    wd : Num
         L2 regularization coefficient add to all the weights
-    rescale_grad : float, optional
+    rescale_grad : Num, optional
         rescaling factor of gradient. Normally should be 1/batch_size.
-    clip_gradient : float, optional
+    clip_gradient : Num, optional
         clip gradient in range [-clip_gradient, clip_gradient]
 =cut
 package AI::MXNet::AdaDelta;
@@ -1614,18 +1608,14 @@ package AI::MXNet::Ftrl;
     Referenced from *Ad Click Prediction: a View from the Trenches*, available at
     http://dl.acm.org/citation.cfm?id=2488200.
 
-    eta :
-        .. math::
-           \\eta_{t,i} = \\frac{learningrate}{\\beta+\\sqrt{\\sum_{s=1}^tg_{s,i}^2}}
-
-    The optimizer updates the weight by::
+    The optimizer updates the weight by:
 
         rescaled_grad = clip(grad * rescale_grad, clip_gradient)
         z += rescaled_grad - (sqrt(n + rescaled_grad**2) - sqrt(n)) * weight / learning_rate
         n += rescaled_grad**2
         w = (sign(z) * lamda1 - z) / ((beta + sqrt(n)) / learning_rate + wd) * (abs(z) > lamda1)
 
-    If the storage types of weight, state and grad are all ``row_sparse``, \
+    If the storage types of weight, state and grad are all row_sparse,
     **sparse updates** are applied by::
 
         for row in grad.indices:
@@ -1641,18 +1631,16 @@ package AI::MXNet::Ftrl;
     provides slightly different semantics than the original update, and
     may lead to different empirical results.
 
-    For details of the update algorithm, see :class:`~mxnet.ndarray.ftrl_update`.
-
     This optimizer accepts the following parameters in addition to those accepted
-    by :class:`.Optimizer`.
+    by AI::MXNet::Optimizer
 
     Parameters
     ----------
-    lamda1 : float, optional
+    lamda1 : Num, optional
         L1 regularization coefficient.
-    learning_rate : float, optional
+    learning_rate : Num, optional
         The initial learning rate.
-    beta : float, optional
+    beta : Num, optional
         Per-coordinate learning rate correlation parameter.
 =cut
 
@@ -1720,9 +1708,9 @@ package AI::MXNet::Adamax;
 
     Parameters
     ----------
-    beta1 : float, optional
+    beta1 : Num, optional
         Exponential decay rate for the first moment estimates.
-    beta2 : float, optional
+    beta2 : Num, optional
         Exponential decay rate for the second moment estimates.
 =cut
 
@@ -1798,17 +1786,17 @@ package AI::MXNet::Nadam;
     at http://cs229.stanford.edu/proj2015/054_report.pdf.
 
     This optimizer accepts the following parameters in addition to those accepted
-    AI::MXNet::Optimizer.
+    by AI::MXNet::Optimizer.
 
     Parameters
     ----------
-    beta1 : float, optional
+    beta1 : Num, optional
         Exponential decay rate for the first moment estimates.
-    beta2 : float, optional
+    beta2 : Num, optional
         Exponential decay rate for the second moment estimates.
-    epsilon : float, optional
+    epsilon : Num, optional
         Small value to avoid division by 0.
-    schedule_decay : float, optional
+    schedule_decay : Num, optional
         Exponential decay rate for the momentum schedule
 =cut
 
@@ -1879,7 +1867,11 @@ method update(
 
 __PACKAGE__->register;
 
-# updater for kvstore
+=head1 NAME
+
+    AI::MXNet::Updater - Updater for kvstore
+=cut
+
 package AI::MXNet::Updater;
 use Mouse;
 use Storable qw(thaw freeze);
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/RNN/Cell.pm b/perl-package/AI-MXNet/lib/AI/MXNet/RNN/Cell.pm
index f2d8b53..9dd88cb 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/RNN/Cell.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/RNN/Cell.pm
@@ -21,7 +21,7 @@ use AI::MXNet::Function::Parameters;
 
 =head1 NAME
 
-    AI::MXNet::RNN::Params
+    AI::MXNet::RNN::Params - A container for holding variables.
 =cut
 
 =head1 DESCRIPTION
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Symbol.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Symbol.pm
index bccf483..57bfdf1 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Symbol.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Symbol.pm
@@ -528,7 +528,7 @@ method list_inputs()
 =cut
 
 
-method infer_type(Str|Undef @args)
+method infer_type(Maybe[Str] @args)
 {
     my ($positional_arguments, $kwargs, $kwargs_order) = _parse_arguments("Dtype", @args);
     my $sdata = [];
@@ -1370,6 +1370,7 @@ method load(Str $fname)
 }
 
 =head2 load_json
+
     Load symbol from json string.
 
     Parameters
@@ -1469,12 +1470,12 @@ sub _parse_arguments
             }
             else
             {
-                confess("Argument need to be of type $type");
+                confess("Argument needs to be of type $type");
             }
         }
         else
         {
-            confess("Argument need to be one type $type");
+            confess("Argument needs to be one type $type");
         }
     }
     return (\@positional_arguments, \%kwargs, \@kwargs_order);
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Symbol/Base.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Symbol/Base.pm
index 2cb20b7..d668dec 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Symbol/Base.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Symbol/Base.pm
@@ -32,7 +32,7 @@ use AI::MXNet::Function::Parameters;
 
 =head1 DESCRIPTION
 
-    A convenience class that loads all C++m symbol related functions at runtime.
+    A convenience class that loads all C++ symbol related functions at runtime.
 =cut
 
 my %function_meta;
diff --git a/perl-package/AI-MXNet/lib/AI/MXNet/Symbol/NameManager.pm b/perl-package/AI-MXNet/lib/AI/MXNet/Symbol/NameManager.pm
index 95ea8a6..0126655 100644
--- a/perl-package/AI-MXNet/lib/AI/MXNet/Symbol/NameManager.pm
+++ b/perl-package/AI-MXNet/lib/AI/MXNet/Symbol/NameManager.pm
@@ -21,7 +21,11 @@ use warnings;
 use Mouse;
 use AI::MXNet::Function::Parameters;
 
-=head1
+=head1 NAME
+
+    AI::MXNet::Symbol::NameManager - Automated symbol naming.
+
+=head1 DESCRIPTION
 
     NameManager that does an automatic naming.
 
diff --git a/perl-package/AI-MXNet/t/test_gluon.t b/perl-package/AI-MXNet/t/test_gluon.t
index 3212722..545cb7b 100644
--- a/perl-package/AI-MXNet/t/test_gluon.t
+++ b/perl-package/AI-MXNet/t/test_gluon.t
@@ -1164,7 +1164,7 @@ sub test_zero_grad
         $net->($data)->backward;
     });
     $net->collect_params->zero_grad;
-    my $grad = $net->collect_params->{test_zero_grad_weight}->grad;
+    my $grad = $net->collect_params->params->get('test_zero_grad_weight')->grad;
     ok(almost_equal($grad->aspdl, $grad->aspdl * 0));
 }
 
diff --git a/perl-package/AI-MXNetCAPI/Changes b/perl-package/AI-MXNetCAPI/Changes
index 8dad8b4..938b8e2 100644
--- a/perl-package/AI-MXNetCAPI/Changes
+++ b/perl-package/AI-MXNetCAPI/Changes
@@ -1,5 +1,8 @@
 Revision history for Perl extension AI::MXNetCAPI
 
+1.32    Sun Aug  5 14:25:31 PDT 2018
+        - Bugfixes.
+
 1.3     Tue Jun 26 20:57:40 PDT 2018
         - Major update, Gluon interface updated to parity with Python's API
 
diff --git a/perl-package/AI-MXNetCAPI/META.json b/perl-package/AI-MXNetCAPI/META.json
index 35271e3..8540235 100644
--- a/perl-package/AI-MXNetCAPI/META.json
+++ b/perl-package/AI-MXNetCAPI/META.json
@@ -37,5 +37,5 @@
       }
    },
    "release_status" : "stable",
-   "version" : "1.3"
+   "version" : "1.32"
 }
diff --git a/perl-package/AI-MXNetCAPI/META.yml b/perl-package/AI-MXNetCAPI/META.yml
index 48760da..1db34c5 100644
--- a/perl-package/AI-MXNetCAPI/META.yml
+++ b/perl-package/AI-MXNetCAPI/META.yml
@@ -19,4 +19,4 @@ no_index:
     - inc
 requires:
   Test::More: '0'
-version: '1.3'
+version: '1.32'
diff --git a/perl-package/AI-MXNetCAPI/README b/perl-package/AI-MXNetCAPI/README
index dca8b4a..f5881ff 100644
--- a/perl-package/AI-MXNetCAPI/README
+++ b/perl-package/AI-MXNetCAPI/README
@@ -1,4 +1,4 @@
-AI-MXNetCAPI version 1.3
+AI-MXNetCAPI version 1.32
 =====================
 
 Swig interface to MXNet c api.
diff --git a/perl-package/AI-MXNetCAPI/lib/AI/MXNetCAPI.pm b/perl-package/AI-MXNetCAPI/lib/AI/MXNetCAPI.pm
index b578507..e371219 100644
--- a/perl-package/AI-MXNetCAPI/lib/AI/MXNetCAPI.pm
+++ b/perl-package/AI-MXNetCAPI/lib/AI/MXNetCAPI.pm
@@ -18,7 +18,7 @@
 package AI::MXNetCAPI;
 use base qw(DynaLoader);
 bootstrap AI::MXNetCAPI;
-our $VERSION = '1.3';
+our $VERSION = '1.32';
 1;
 __END__
 
diff --git a/perl-package/AI-MXNetCAPI/mxnet_typemaps.i b/perl-package/AI-MXNetCAPI/mxnet_typemaps.i
index 4d9177a..68e11ca 100644
--- a/perl-package/AI-MXNetCAPI/mxnet_typemaps.i
+++ b/perl-package/AI-MXNetCAPI/mxnet_typemaps.i
@@ -1215,5 +1215,5 @@
 
 %typemap(in) (void* callback_handle)
 {
-    $1 = (void*)$input;
+    $1 = (void*)newSVsv($input);
 }