view release on metacpan or search on metacpan
Revision history for Perl extension AI::MXNet::Gluon::ModelZoo
1.33 Thu Oct 4 13:25:56 PDT 2018
- Fixed kwalitee issues.
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
Changes
examples/image_classification.pl
lib/AI/MXNet/Gluon/ModelZoo.pm
lib/AI/MXNet/Gluon/ModelZoo/ModelStore.pm
lib/AI/MXNet/Gluon/ModelZoo/Vision.pm
lib/AI/MXNet/Gluon/ModelZoo/Vision/AlexNet.pm
lib/AI/MXNet/Gluon/ModelZoo/Vision/DenseNet.pm
lib/AI/MXNet/Gluon/ModelZoo/Vision/Inception.pm
lib/AI/MXNet/Gluon/ModelZoo/Vision/MobileNet.pm
lib/AI/MXNet/Gluon/ModelZoo/Vision/ResNet.pm
lib/AI/MXNet/Gluon/ModelZoo/Vision/SqueezeNet.pm
lib/AI/MXNet/Gluon/ModelZoo/Vision/VGG.pm
Makefile.PL
MANIFEST
META.json
META.yml
README
t/AI-MXNet-Gluon-ModelZoo.t
t/test_gluon_model_zoo.t
{
"abstract" : "Perl interface to MXNet Gluon ModelZoo",
"author" : [
"Sergey Kolychev <sergeykolychev.github@gmail.com>"
],
"dynamic_config" : 0,
"generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.143240",
"license" : [
"apache_2_0"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : "2"
},
"name" : "AI-MXNet-Gluon-ModelZoo",
"no_index" : {
"directory" : [
"t",
"inc"
]
},
"prereqs" : {
"build" : {
"requires" : {}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "6.30"
}
},
"runtime" : {
"requires" : {
"AI::MXNet" : "1.31",
"AI::MXNet::Gluon::Contrib" : "1.3",
"IO::Uncompress::Unzip" : "0"
}
},
"test" : {
"requires" : {}
}
},
"release_status" : "stable",
"version" : "1.33"
}
---
abstract: 'Perl interface to MXNet Gluon ModelZoo'
author:
- 'Sergey Kolychev <sergeykolychev.github@gmail.com>'
build_requires: {}
configure_requires:
ExtUtils::MakeMaker: '6.30'
dynamic_config: 0
generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.143240'
license: apache
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: AI-MXNet-Gluon-ModelZoo
no_index:
directory:
- t
- inc
requires:
AI::MXNet: '1.31'
AI::MXNet::Gluon::Contrib: '1.3'
IO::Uncompress::Unzip: '0'
version: '1.33'
Makefile.PL view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
use strict;
use warnings;
use 5.014000;
use ExtUtils::MakeMaker 6.30;
my %WriteMakefileArgs = (
"ABSTRACT" => "Perl interface to MXNet Gluon ModelZoo",
"AUTHOR" => "Sergey Kolychev <sergeykolychev.github\@gmail.com>",
"BUILD_REQUIRES" => {},
"CONFIGURE_REQUIRES" => {
"ExtUtils::MakeMaker" => "6.30"
},
"DISTNAME" => "AI-MXNet-Gluon-ModelZoo",
"EXE_FILES" => [],
"LICENSE" => "apache_2_0",
"NAME" => "AI::MXNet::Gluon::ModelZoo",
"PREREQ_PM" => {
"AI::MXNet" => "1.31",
"AI::MXNet::Gluon::Contrib" => "1.3",
"IO::Uncompress::Unzip" => "0"
},
"TEST_REQUIRES" => {},
"VERSION" => "1.33",
"test" => {
"TESTS" => "t/*.t"
}
);
my %FallbackPrereqs = (
"AI::MXNet" => "1.31",
"AI::MXNet::Gluon::Contrib" => "1.3",
"IO::Uncompress::Unzip" => "0"
);
unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
delete $WriteMakefileArgs{TEST_REQUIRES};
delete $WriteMakefileArgs{BUILD_REQUIRES};
$WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs;
}
delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
WriteMakefile(%WriteMakefileArgs);
This archive contains the distribution AI-MXNet-Gluon-ModelZoo,
version 1.33:
Perl interface to MXNet Gluon ModelZoo, a collection of pretrained machine learning models for computer vision.
This library is licensed under Apache 2.0 license https://www.apache.org/licenses/LICENSE-2.0
examples/image_classification.pl view on Meta::CPAN
#!/usr/bin/env perl
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
use strict;
use warnings;
use AI::MXNet::Gluon::ModelZoo 'get_model';
use AI::MXNet::Gluon::Utils 'download';
use Getopt::Long qw(HelpMessage);
GetOptions(
## my Pembroke Welsh Corgi Kyuubi, enjoing Solar eclipse of August 21, 2017
'image=s' => \(my $image = 'http://apache-mxnet.s3-accelerate.dualstack.amazonaws.com/'.
'gluon/dataset/kyuubi.jpg'),
'model=s' => \(my $model = 'resnet152_v2'),
'help' => sub { HelpMessage(0) },
) or HelpMessage(1);
## get a pretrained model (download parameters file if necessary)
my $net = get_model($model, pretrained => 1);
## ImageNet classes
my $fname = download('http://data.mxnet.io/models/imagenet/synset.txt');
my @text_labels = map { chomp; s/^\S+\s+//; $_ } IO::File->new($fname)->getlines;
## get the image from the disk or net
if($image =~ /^https/)
{
eval { require IO::Socket::SSL; };
die "Need to have IO::Socket::SSL installed for https images" if $@;
}
$image = $image =~ /^https?/ ? download($image) : $image;
# Following the conventional way of preprocessing ImageNet data:
# Resize the short edge into 256 pixes,
# And then perform a center crop to obtain a 224-by-224 image.
# The following code uses the image processing functions provided
# in the AI::MXNet::Image module.
$image = mx->image->imread($image);
$image = mx->image->resize_short($image, $model =~ /inception/ ? 330 : 256);
($image) = mx->image->center_crop($image, [($model =~ /inception/ ? 299 : 224)x2]);
## CV that is used to read image is column major (as PDL)
$image = $image->transpose([2,0,1])->expand_dims(axis=>0);
## normalizing the image
my $rgb_mean = nd->array([0.485, 0.456, 0.406])->reshape([1,3,1,1]);
my $rgb_std = nd->array([0.229, 0.224, 0.225])->reshape([1,3,1,1]);
$image = ($image->astype('float32') / 255 - $rgb_mean) / $rgb_std;
# Now we can recognize the object in the image.
# We perform an additional softmax on the output to obtain probability scores.
# And then print the top-5 recognized objects.
my $prob = $net->($image)->softmax;
for my $idx (@{ $prob->topk(k=>5)->at(0) })
{
my $i = $idx->asscalar;
printf(
"With prob = %.5f, it contains %s\n",
$prob->at(0)->at($i)->asscalar, $text_labels[$i]
);
}
lib/AI/MXNet/Gluon/ModelZoo.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
package AI::MXNet::Gluon::ModelZoo;
use strict;
use warnings;
use AI::MXNet qw(mx);
use AI::MXNet::Gluon qw(gluon);
use AI::MXNet::Gluon::NN qw(nn);
use AI::MXNet::Gluon::Contrib;
use AI::MXNet::Gluon::ModelZoo::Vision;
use Exporter;
use base qw(Exporter);
@AI::MXNet::Gluon::ModelZoo::EXPORT_OK = qw(get_model);
our $VERSION = '1.33';
=head1 NAME
AI::MXNet::Gluon::ModelZoo - A collection of pretrained MXNet Gluon models
=cut
=head1 SYNOPSIS
## run forward prediction on random data
use AI::MXNet::Gluon::ModelZoo qw(get_model);
my $alexnet = get_model('alexnet', pretrained => 1);
my $out = $alexnet->(mx->nd->random->uniform(shape=>[1, 3, 224, 224]));
print $out->aspdl;
=cut
=head1 DESCRIPTION
This module houses a collection of pretrained models (the parameters are hosted on public mxnet servers).
https://mxnet.incubator.apache.org/api/python/gluon/model_zoo.html
See examples/image_classification.pl for the example of real time image classification
using a pretrained model from the ModelZoo
=cut
our %models = qw/
resnet18_v1 resnet18_v1
resnet34_v1 resnet34_v1
resnet50_v1 resnet50_v1
resnet101_v1 resnet101_v1
resnet152_v1 resnet152_v1
resnet18_v2 resnet18_v2
resnet34_v2 resnet34_v2
resnet50_v2 resnet50_v2
resnet101_v2 resnet101_v2
resnet152_v2 resnet152_v2
vgg11 vgg11
vgg13 vgg13
vgg16 vgg16
vgg19 vgg19
vgg11_bn vgg11_bn
vgg13_bn vgg13_bn
vgg16_bn vgg16_bn
vgg19_bn vgg19_bn
alexnet alexnet
densenet121 densenet121
densenet161 densenet161
densenet169 densenet169
densenet201 densenet201
squeezenet1.0 squeezenet1_0
squeezenet1.1 squeezenet1_1
inceptionv3 inception_v3
mobilenet1.0 mobilenet1_0
mobilenet0.75 mobilenet0_75
mobilenet0.5 mobilenet0_5
mobilenet0.25 mobilenet0_25
mobilenetv2_1.0 mobilenet_v2_1_0
mobilenetv2_0.75 mobilenet_v2_0_75
mobilenetv2_0.5 mobilenet_v2_0_5
mobilenetv2_0.25 mobilenet_v2_0_25
/;
=head2 get_model
Returns a pre-defined model by name
Parameters
----------
$name : Str
Name of the model.
:$pretrained : Bool
Whether to load the pretrained weights for model.
:$classes : Int
Number of classes for the output layer.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
Returns
-------
HybridBlock
The model.
=cut
sub get_model
{
if(exists $models{lc $_[1]})
{
shift;
}
my ($name, %kwargs) = @_;
$name = lc $name;
Carp::confess(
"Model $name is not present in the zoo\nValid models are:\n".
join(', ', sort keys %models)."\n"
) unless exists $models{$name};
my $sub = $models{$name};
AI::MXNet::Gluon::ModelZoo::Vision->$sub(%kwargs);
}
sub vision { 'AI::MXNet::Gluon::ModelZoo::Vision' }
1;
=head1 AUTHOR
Sergey Kolychev, <sergeykolychev.github@gmail.com>
=head1 COPYRIGHT & LICENSE
This library is licensed under Apache 2.0 license L<https://www.apache.org/licenses/LICENSE-2.0>
=cut
lib/AI/MXNet/Gluon/ModelZoo/ModelStore.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
package AI::MXNet::Gluon::ModelZoo::ModelStore;
use strict;
use warnings;
use AI::MXNet::Function::Parameters;
=head1 NAME
AI::MXNet::Gluon::ModelZoo::ModelStore - Model zoo for pre-trained models.
=cut
use AI::MXNet::Gluon::Utils qw(download check_sha1);
use IO::Uncompress::Unzip qw(unzip);
use File::Path qw(make_path);
my %_model_sha1 = map { $_->[1] => $_->[0] } (
['44335d1f0046b328243b32a26a4fbd62d9057b45', 'alexnet'],
['f27dbf2dbd5ce9a80b102d89c7483342cd33cb31', 'densenet121'],
['b6c8a95717e3e761bd88d145f4d0a214aaa515dc', 'densenet161'],
['2603f878403c6aa5a71a124c4a3307143d6820e9', 'densenet169'],
['1cdbc116bc3a1b65832b18cf53e1cb8e7da017eb', 'densenet201'],
['ed47ec45a937b656fcc94dabde85495bbef5ba1f', 'inceptionv3'],
['9f83e440996887baf91a6aff1cccc1c903a64274', 'mobilenet0.25'],
['8e9d539cc66aa5efa71c4b6af983b936ab8701c3', 'mobilenet0.5'],
['529b2c7f4934e6cb851155b22c96c9ab0a7c4dc2', 'mobilenet0.75'],
['6b8c5106c730e8750bcd82ceb75220a3351157cd', 'mobilenet1.0'],
['36da4ff1867abccd32b29592d79fc753bca5a215', 'mobilenetv2_1.0'],
['e2be7b72a79fe4a750d1dd415afedf01c3ea818d', 'mobilenetv2_0.75'],
['aabd26cd335379fcb72ae6c8fac45a70eab11785', 'mobilenetv2_0.5'],
['ae8f9392789b04822cbb1d98c27283fc5f8aa0a7', 'mobilenetv2_0.25'],
['a0666292f0a30ff61f857b0b66efc0228eb6a54b', 'resnet18_v1'],
['48216ba99a8b1005d75c0f3a0c422301a0473233', 'resnet34_v1'],
['0aee57f96768c0a2d5b23a6ec91eb08dfb0a45ce', 'resnet50_v1'],
['d988c13d6159779e907140a638c56f229634cb02', 'resnet101_v1'],
['671c637a14387ab9e2654eafd0d493d86b1c8579', 'resnet152_v1'],
['a81db45fd7b7a2d12ab97cd88ef0a5ac48b8f657', 'resnet18_v2'],
['9d6b80bbc35169de6b6edecffdd6047c56fdd322', 'resnet34_v2'],
['ecdde35339c1aadbec4f547857078e734a76fb49', 'resnet50_v2'],
['18e93e4f48947e002547f50eabbcc9c83e516aa6', 'resnet101_v2'],
['f2695542de38cf7e71ed58f02893d82bb409415e', 'resnet152_v2'],
['264ba4970a0cc87a4f15c96e25246a1307caf523', 'squeezenet1.0'],
['33ba0f93753c83d86e1eb397f38a667eaf2e9376', 'squeezenet1.1'],
['dd221b160977f36a53f464cb54648d227c707a05', 'vgg11'],
['ee79a8098a91fbe05b7a973fed2017a6117723a8', 'vgg11_bn'],
['6bc5de58a05a5e2e7f493e2d75a580d83efde38c', 'vgg13'],
['7d97a06c3c7a1aecc88b6e7385c2b373a249e95e', 'vgg13_bn'],
['e660d4569ccb679ec68f1fd3cce07a387252a90a', 'vgg16'],
['7f01cf050d357127a73826045c245041b0df7363', 'vgg16_bn'],
['ad2f660d101905472b83590b59708b71ea22b2e5', 'vgg19'],
['f360b758e856f1074a85abd5fd873ed1d98297c3', 'vgg19_bn']
);
my $apache_repo_url = 'http://apache-mxnet.s3-accelerate.dualstack.amazonaws.com/';
my $_url_format = '%sgluon/models/%s.zip';
func short_hash($name)
{
Carp::confess("model $name is not available in model zoo") unless exists $_model_sha1{$name};
return substr($_model_sha1{$name}, 0, 8);
}
=head2 get_model_file
Return location for the pretrained on local file system.
This function will download from online model zoo when model cannot be found or has mismatch.
The root directory will be created if it doesn't exist.
Parameters
----------
$name : Str
Name of the model.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
Returns
-------
$file_path
Path to the requested pretrained model file.
=cut
method get_model_file(Str $name, Str :$root='~/.mxnet/models')
{
my $file_name = "$name-".short_hash($name);
$root =~ s/~/$ENV{HOME}/;
my $file_path = "$root/$file_name.params";
my $sha1_hash = $_model_sha1{$name};
if(-f $file_path)
{
if(check_sha1($file_path, $sha1_hash))
{
return $file_path;
}
else
{
warn("Mismatch in the content of model file detected. Downloading again.\n");
}
}
else
{
warn("Model file is not found. Downloading.\n");
}
if(not -d $root)
{
make_path($root);
}
my $zip_file_path = "$root/$file_name.zip";
my $repo_url = $ENV{MXNET_GLUON_REPO}//$apache_repo_url;
if($repo_url !~ /\/$/)
{
$repo_url .= '/';
}
download(
sprintf($_url_format, $repo_url, $file_name),
path=>$zip_file_path,
overwrite=>1
);
unzip($zip_file_path, $file_path);
unlink $zip_file_path;
if(check_sha1($file_path, $sha1_hash))
{
return $file_path;
}
else
{
Carp::confess("Downloaded file $file_path has different hash. Please try again.");
}
}
=head2 purge
Purge all pretrained model files in local file store.
Parameters
----------
root : str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method purge(Str $root='~/.mxnet/models')
{
$root =~ s/~/$ENV{HOME}/;
map { unlink } glob("$root/*.params");
}
1;
lib/AI/MXNet/Gluon/ModelZoo/Vision.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
package AI::MXNet::Gluon::ModelZoo::Vision;
use strict;
use warnings;
use AI::MXNet::Gluon::ModelZoo::ModelStore;
use AI::MXNet::Gluon::ModelZoo::Vision::AlexNet;
use AI::MXNet::Gluon::ModelZoo::Vision::DenseNet;
use AI::MXNet::Gluon::ModelZoo::Vision::Inception;
use AI::MXNet::Gluon::ModelZoo::Vision::MobileNet;
use AI::MXNet::Gluon::ModelZoo::Vision::ResNet;
use AI::MXNet::Gluon::ModelZoo::Vision::SqueezeNet;
use AI::MXNet::Gluon::ModelZoo::Vision::VGG;
sub import
{
my ($class, $short_name) = @_;
if($short_name)
{
$short_name =~ s/[^\w:]//g;
if(length $short_name)
{
my $short_name_package =<<"EOP";
package $short_name;
\@${short_name}::ISA = ('AI::MXNet::Gluon::ModelZoo::Vision');
1;
EOP
eval $short_name_package;
}
}
}
1;
lib/AI/MXNet/Gluon/ModelZoo/Vision/AlexNet.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
package AI::MXNet::Gluon::ModelZoo::Vision::AlexNet;
use strict;
use warnings;
use AI::MXNet::Function::Parameters;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::AlexNet - AlexNet model from the `"One weird trick..."
=cut
=head1 DESCRIPTION
AlexNet model from the "One weird trick..." <https://arxiv.org/abs/1404.5997> paper.
Parameters
----------
classes : Int, default 1000
Number of classes for the output layer.
=cut
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
method python_constructor_arguments() { ['classes'] }
sub BUILD
{
my $self = shift;
$self->name_scope(sub {
$self->features(nn->HybridSequential(prefix=>''));
$self->features->name_scope(sub {
$self->features->add(nn->Conv2D(64, kernel_size=>11, strides=>4,
padding=>2, activation=>'relu'));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2));
$self->features->add(nn->Conv2D(192, kernel_size=>5, padding=>2,
activation=>'relu'));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2));
$self->features->add(nn->Conv2D(384, kernel_size=>3, padding=>1,
activation=>'relu'));
$self->features->add(nn->Conv2D(256, kernel_size=>3, padding=>1,
activation=>'relu'));
$self->features->add(nn->Conv2D(256, kernel_size=>3, padding=>1,
activation=>'relu'));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2));
$self->features->add(nn->Flatten());
$self->features->add(nn->Dense(4096, activation=>'relu'));
$self->features->add(nn->Dropout(0.5));
$self->features->add(nn->Dense(4096, activation=>'relu'));
$self->features->add(nn->Dropout(0.5));
});
$self->output(nn->Dense($self->classes));
});
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision;
=head2 alexnet
AlexNet model from the `"One weird trick..." <https://arxiv.org/abs/1404.5997> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method alexnet(
Bool :$pretrained=0,
AI::MXNet::Context :$ctx=AI::MXNet::Context->cpu(),
Str :$root='~/.mxnet/models',
Int :$classes=1000
)
{
my $net = AI::MXNet::Gluon::ModelZoo::Vision::AlexNet->new($classes);
if($pretrained)
{
$net->load_parameters(
AI::MXNet::Gluon::ModelZoo::ModelStore->get_model_file(
'alexnet',
root=>$root
),
ctx=>$ctx
);
}
return $net;
}
1;
lib/AI/MXNet/Gluon/ModelZoo/Vision/DenseNet.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
package AI::MXNet::Gluon::ModelZoo::Vision::DenseNet;
use strict;
use warnings;
use AI::MXNet::Base;
use AI::MXNet::Function::Parameters;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
func _make_dense_block($num_layers, $bn_size, $growth_rate, $dropout, $stage_index)
{
my $out = nn->HybridSequential(prefix=>"stage${stage_index}_");
$out->name_scope(sub {
for(1..$num_layers)
{
$out->add(_make_dense_layer($growth_rate, $bn_size, $dropout));
}
});
return $out;
}
func _make_dense_layer($growth_rate, $bn_size, $dropout)
{
my $new_features = nn->HybridSequential(prefix=>'');
$new_features->add(nn->BatchNorm());
$new_features->add(nn->Activation('relu'));
$new_features->add(nn->Conv2D($bn_size * $growth_rate, kernel_size=>1, use_bias=>0));
$new_features->add(nn->BatchNorm());
$new_features->add(nn->Activation('relu'));
$new_features->add(nn->Conv2D($growth_rate, kernel_size=>3, padding=>1, use_bias=>0));
if($dropout)
{
$new_features->add(nn->Dropout($dropout));
}
my $out = nn->HybridConcurrent(axis=>1, prefix=>'');
$out->add(nn->Identity());
$out->add($new_features);
return $out;
}
func _make_transition($num_output_features)
{
my $out = nn->HybridSequential(prefix=>'');
$out->add(nn->BatchNorm());
$out->add(nn->Activation('relu'));
$out->add(nn->Conv2D($num_output_features, kernel_size=>1, use_bias=>0));
$out->add(nn->AvgPool2D(pool_size=>2, strides=>2));
return $out;
}
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::DenseNet - Densenet-BC model from the "Densely Connected Convolutional Networks"
=cut
=head1 DESCRIPTION
Densenet-BC model from the "Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf> paper.
Parameters
----------
num_init_features : Int
Number of filters to learn in the first convolution layer.
growth_rate : Int
Number of filters to add each layer (`k` in the paper).
block_config : array ref of Int
List of integers for numbers of layers in each pooling block.
bn_size : Int, default 4
Multiplicative factor for number of bottle neck layers.
(i.e. bn_size * k features in the bottleneck layer)
dropout : float, default 0
Rate of dropout after each dense layer.
classes : int, default 1000
Number of classification classes.
=cut
has [qw/num_init_features
growth_rate/] => (is => 'ro', isa => 'Int', required => 1);
has 'block_config' => (is => 'ro', isa => 'ArrayRef[Int]', required => 1);
has 'bn_size' => (is => 'ro', isa => 'Int', default => 4);
has 'dropout' => (is => 'ro', isa => 'Num', default => 0);
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
method python_constructor_arguments(){ [qw/num_init_features growth_rate block_config bn_size dropout classes/] }
sub BUILD
{
my $self = shift;
$self->name_scope(sub {
$self->features(nn->HybridSequential(prefix=>''));
$self->features->add(
nn->Conv2D(
$self->num_init_features, kernel_size=>7,
strides=>2, padding=>3, use_bias=>0
)
);
$self->features->add(nn->BatchNorm());
$self->features->add(nn->Activation('relu'));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2, padding=>1));
# Add dense blocks
my $num_features = $self->num_init_features;
for(enumerate($self->block_config))
{
my ($i, $num_layers) = @$_;
$self->features->add(_make_dense_block($num_layers, $self->bn_size, $self->growth_rate, $self->dropout, $i+1));
$num_features += $num_layers * $self->growth_rate;
if($i != @{ $self->block_config } - 1)
{
$self->features->add(_make_transition(int($num_features/2)));
$num_features = int($num_features/2);
}
}
$self->features->add(nn->BatchNorm());
$self->features->add(nn->Activation('relu'));
$self->features->add(nn->AvgPool2D(pool_size=>7));
$self->features->add(nn->Flatten());
$self->output(nn->Dense($self->classes));
});
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision;
my %densenet_spec = (
121 => [64, 32, [6, 12, 24, 16]],
161 => [96, 48, [6, 12, 36, 24]],
169 => [64, 32, [6, 12, 32, 32]],
201 => [64, 32, [6, 12, 48, 32]]
);
=head2 get_densenet
Densenet-BC model from the
"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf> paper.
Parameters
----------
$num_layers : Int
Number of layers for the variant of densenet. Options are 121, 161, 169, 201.
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method get_densenet(
Int $num_layers, Bool :$pretrained=0, :$ctx=AI::MXNet::Context->cpu(),
:$root='~/.mxnet/models',
Int :$bn_size=4,
Num :$dropout=0,
Int :$classes=1000
)
{
my ($num_init_features, $growth_rate, $block_config) = @{ $densenet_spec{$num_layers} };
my $net = AI::MXNet::Gluon::ModelZoo::Vision::DenseNet->new(
$num_init_features, $growth_rate, $block_config,
$bn_size, $dropout, $classes
);
if($pretrained)
{
$net->load_parameters(
AI::MXNet::Gluon::ModelZoo::ModelStore->get_model_file(
"densenet$num_layers",
root=>$root
),
ctx=>$ctx
);
}
return $net;
}
=head2 densenet121
Densenet-BC 121-layer model from the
"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method densenet121(%kwargs)
{
return __PACKAGE__->get_densenet(121, %kwargs)
}
=head2 densenet161
Densenet-BC 161-layer model from the
"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method densenet161(%kwargs)
{
return __PACKAGE__->get_densenet(161, %kwargs)
}
=head2 densenet169
Densenet-BC 169-layer model from the
"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method densenet169(%kwargs)
{
return __PACKAGE__->get_densenet(169, %kwargs)
}
=head2 densenet201
Densenet-BC 201-layer model from the
"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method densenet201(%kwargs)
{
return __PACKAGE__->get_densenet(201, %kwargs)
}
1;
lib/AI/MXNet/Gluon/ModelZoo/Vision/Inception.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
package AI::MXNet::Gluon::ModelZoo::Vision::Inception::V3;
use strict;
use warnings;
use AI::MXNet::Base;
use AI::MXNet::Function::Parameters;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
func _make_basic_conv(%kwargs)
{
my $out = nn->HybridSequential(prefix=>'');
$out->add(nn->Conv2D(use_bias=>0, %kwargs));
$out->add(nn->BatchNorm(epsilon=>0.001));
$out->add(nn->Activation('relu'));
return $out;
}
func _make_branch($use_pool, @conv_settings)
{
my $out = nn->HybridSequential(prefix=>'');
if($use_pool eq 'avg')
{
$out->add(nn->AvgPool2D(pool_size=>3, strides=>1, padding=>1));
}
elsif($use_pool eq 'max')
{
$out->add(nn->MaxPool2D(pool_size=>3, strides=>2));
}
my @setting_names = ('channels', 'kernel_size', 'strides', 'padding');
for my $setting (@conv_settings)
{
my %kwargs;
for(enumerate($setting))
{
my ($i, $value) = @$_;
if(defined $value)
{
$kwargs{ $setting_names[$i] } = $value;
}
}
$out->add(_make_basic_conv(%kwargs));
}
return $out;
}
func _make_A($pool_features, $prefix)
{
my $out = nn->HybridConcurrent(axis=>1, prefix=>$prefix);
$out->name_scope(sub {
$out->add(_make_branch('', [64, 1, undef, undef]));
$out->add(_make_branch(
'',
[48, 1, undef, undef],
[64, 5, undef, 2]
));
$out->add(_make_branch(
'',
[64, 1, undef, undef],
[96, 3, undef, 1],
[96, 3, undef, 1]
));
$out->add(_make_branch('avg', [$pool_features, 1, undef, undef]));
});
return $out;
}
func _make_B($prefix)
{
my $out = nn->HybridConcurrent(axis=>1, prefix=>$prefix);
$out->name_scope(sub {
$out->add(_make_branch('', [384, 3, 2, undef]));
$out->add(_make_branch(
'',
[64, 1, undef, undef],
[96, 3, undef, 1],
[96, 3, 2, undef]
));
$out->add(_make_branch('max'));
});
return $out;
}
func _make_C($channels_7x7, $prefix)
{
my $out = nn->HybridConcurrent(axis=>1, prefix=>$prefix);
$out->name_scope(sub {
$out->add(_make_branch('', [192, 1, undef, undef]));
$out->add(_make_branch(
'',
[$channels_7x7, 1, undef, undef],
[$channels_7x7, [1, 7], undef, [0, 3]],
[192, [7, 1], undef, [3, 0]]
));
$out->add(_make_branch(
'',
[$channels_7x7, 1, undef, undef],
[$channels_7x7, [7, 1], undef, [3, 0]],
[$channels_7x7, [1, 7], undef, [0, 3]],
[$channels_7x7, [7, 1], undef, [3, 0]],
[192, [1, 7], undef, [0, 3]]
));
$out->add(_make_branch(
'avg',
[192, 1, undef, undef]
));
});
return $out;
}
func _make_D($prefix)
{
my $out = nn->HybridConcurrent(axis=>1, prefix=>$prefix);
$out->name_scope(sub {
$out->add(_make_branch(
'',
[192, 1, undef, undef],
[320, 3, 2, undef]
));
$out->add(_make_branch(
'',
[192, 1, undef, undef],
[192, [1, 7], undef, [0, 3]],
[192, [7, 1], undef, [3, 0]],
[192, 3, 2, undef]
));
$out->add(_make_branch('max'));
});
return $out;
}
func _make_E($prefix)
{
my $out = nn->HybridConcurrent(axis=>1, prefix=>$prefix);
$out->name_scope(sub {
$out->add(_make_branch('', [320, 1, undef, undef]));
my $branch_3x3 = nn->HybridSequential(prefix=>'');
$out->add($branch_3x3);
$branch_3x3->add(_make_branch(
'',
[384, 1, undef, undef]
));
my $branch_3x3_split = nn->HybridConcurrent(axis=>1, prefix=>'');
$branch_3x3_split->add(_make_branch('', [384, [1, 3], undef, [0, 1]]));
$branch_3x3_split->add(_make_branch('', [384, [3, 1], undef, [1, 0]]));
$branch_3x3->add($branch_3x3_split);
my $branch_3x3dbl = nn->HybridSequential(prefix=>'');
$out->add($branch_3x3dbl);
$branch_3x3dbl->add(_make_branch(
'',
[448, 1, undef, undef],
[384, 3, undef, 1]
));
my $branch_3x3dbl_split = nn->HybridConcurrent(axis=>1, prefix=>'');
$branch_3x3dbl->add($branch_3x3dbl_split);
$branch_3x3dbl_split->add(_make_branch('', [384, [1, 3], undef, [0, 1]]));
$branch_3x3dbl_split->add(_make_branch('', [384, [3, 1], undef, [1, 0]]));
$out->add(_make_branch('avg', [192, 1, undef, undef]));
});
return $out;
}
func make_aux($classes)
{
my $out = nn->HybridSequential(prefix=>'');
$out->add(nn->AvgPool2D(pool_size=>5, strides=>3));
$out->add(_make_basic_conv(channels=>128, kernel_size=>1));
$out->add(_make_basic_conv(channels=>768, kernel_size=>5));
$out->add(nn->Flatten());
$out->add(nn->Dense($classes));
return $out;
}
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::Inception::V3 - Inception v3 model.
=cut
=head1 DESCRIPTION
Inception v3 model from
"Rethinking the Inception Architecture for Computer Vision"
<http://arxiv.org/abs/1512.00567> paper.
Parameters
----------
classes : Int, default 1000
Number of classification classes.
=cut
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
method python_constructor_arguments(){ ['classes'] }
sub BUILD
{
my $self = shift;
$self->name_scope(sub {
$self->features(nn->HybridSequential(prefix=>''));
$self->features->add(_make_basic_conv(channels=>32, kernel_size=>3, strides=>2));
$self->features->add(_make_basic_conv(channels=>32, kernel_size=>3));
$self->features->add(_make_basic_conv(channels=>64, kernel_size=>3, padding=>1));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2));
$self->features->add(_make_basic_conv(channels=>80, kernel_size=>1));
$self->features->add(_make_basic_conv(channels=>192, kernel_size=>3));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2));
$self->features->add(_make_A(32, 'A1_'));
$self->features->add(_make_A(64, 'A2_'));
$self->features->add(_make_A(64, 'A3_'));
$self->features->add(_make_B('B_'));
$self->features->add(_make_C(128, 'C1_'));
$self->features->add(_make_C(160, 'C2_'));
$self->features->add(_make_C(160, 'C3_'));
$self->features->add(_make_C(192, 'C4_'));
$self->features->add(_make_D('D_'));
$self->features->add(_make_E('E1_'));
$self->features->add(_make_E('E2_'));
$self->features->add(nn->AvgPool2D(pool_size=>8));
$self->features->add(nn->Dropout(0.5));
$self->output(nn->Dense($self->classes));
});
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision;
=head2 inception_v3
Inception v3 model from
"Rethinking the Inception Architecture for Computer Vision"
<http://arxiv.org/abs/1512.00567> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method inception_v3(
Bool :$pretrained=0, AI::MXNet::Context :$ctx=AI::MXNet::Context->cpu(),
Str :$root='~/.mxnet/models', Int :$classes=1000
)
{
my $net = AI::MXNet::Gluon::ModelZoo::Vision::Inception::V3->new($classes);
if($pretrained)
{
$net->load_parameters(
AI::MXNet::Gluon::ModelZoo::ModelStore->get_model_file(
"inceptionv3",
root=>$root
),
ctx=>$ctx
);
}
return $net;
}
1;
lib/AI/MXNet/Gluon/ModelZoo/Vision/MobileNet.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
use strict;
use warnings;
use AI::MXNet::Function::Parameters;
package AI::MXNet::Gluon::ModelZoo::Vision::MobileNet::RELU6;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
method hybrid_forward(GluonClass $F, GluonInput $x)
{
return $F->clip($x, a_min => 0, a_max => 6, name=>"relu6");
}
package AI::MXNet::Gluon::ModelZoo::Vision::MobileNet::LinearBottleneck;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
has [qw/in_channels channels t stride/] => (is => 'ro', isa => 'Int', required => 1);
method python_constructor_arguments(){ [qw/in_channels channels t stride/] }
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::MobileNet::LinearBottleneck - LinearBottleneck used in MobileNetV2 model
=cut
=head1 DESCRIPTION
LinearBottleneck used in MobileNetV2 model from the
"Inverted Residuals and Linear Bottlenecks:
Mobile Networks for Classification, Detection and Segmentation"
<https://arxiv.org/abs/1801.04381> paper.
Parameters
----------
in_channels : Int
Number of input channels.
channels : Int
Number of output channels.
t : Int
Layer expansion ratio.
stride : Int
stride
=cut
func _add_conv(
$out, $channels, :$kernel=1, :$stride=1, :$pad=0,
:$num_group=1, :$active=1, :$relu6=0
)
{
$out->add(nn->Conv2D($channels, $kernel, $stride, $pad, groups=>$num_group, use_bias=>0));
$out->add(nn->BatchNorm(scale=>1));
if($active)
{
$out->add($relu6 ? AI::MXNet::Gluon::ModelZoo::Vision::MobileNet::RELU6->new : nn->Activation('relu'));
}
}
sub BUILD
{
my $self = shift;
$self->use_shortcut($self->stride == 1 and $self->in_channels == $self->channels);
$self->name_scope(sub {
$self->out(nn->HybridSequential());
_add_conv($self->out, $self->in_channels * $self->t, relu6=>1);
_add_conv(
$self->out, $self->in_channels * $self->t, kernel=>3, stride=>$self->stride,
pad=>1, num_group=>$self->in_channels * $self->t, relu6=>1
);
_add_conv($self->out, $self->channels, active=>0, relu6=>1);
});
}
method hybrid_forward($F, $x)
{
my $out = $self->out->($x);
if($self->use_shortcut)
{
$out = $F->elemwise_add($out, $x);
}
return $out;
}
package AI::MXNet::Gluon::ModelZoo::Vision::MobileNet;
use AI::MXNet::Gluon::Mouse;
use AI::MXNet::Base;
extends 'AI::MXNet::Gluon::HybridBlock';
has 'multiplier' => (is => 'ro', isa => 'Num', default => 1);
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
method python_constructor_arguments(){ [qw/multiplier classes/] }
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::MobileNet - MobileNet model from the
"MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
=cut
=head1 DESCRIPTION
MobileNet model from the
"MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
<https://arxiv.org/abs/1704.04861> paper.
Parameters
----------
multiplier : Num, default 1.0
The width multiplier for controling the model size. Only multipliers that are no
less than 0.25 are supported. The actual number of channels is equal to the original
channel size multiplied by this multiplier.
classes : Int, default 1000
Number of classes for the output layer.
=cut
func _add_conv(
$out, :$channels=1, :$kernel=1, :$stride=1, :$pad=0,
:$num_group=1, :$active=1, :$relu6=0
)
{
$out->add(nn->Conv2D($channels, $kernel, $stride, $pad, groups=>$num_group, use_bias=>0));
$out->add(nn->BatchNorm(scale=>1));
if($active)
{
$out->add($relu6 ? AI::MXNet::Gluon::ModelZoo::Vision::MobileNet::RELU6->new : nn->Activation('relu'));
}
}
func _add_conv_dw($out, :$dw_channels=, :$channels=, :$stride=, :$relu6=0)
{
_add_conv($out, channels=>$dw_channels, kernel=>3, stride=>$stride,
pad=>1, num_group=>$dw_channels, relu6=>$relu6);
_add_conv($out, channels=>$channels, relu6=>$relu6);
}
sub BUILD
{
my $self = shift;
$self->name_scope(sub {
$self->features(nn->HybridSequential(prefix=>''));
$self->features->name_scope(sub {
_add_conv($self->features, channels=>int(32 * $self->multiplier), kernel=>3, pad=>1, stride=>2);
my $dw_channels = [map { int($_ * $self->multiplier) } (32, 64, (128)x2, (256)x2, (512)x6, 1024)];
my $channels = [map { int($_ * $self->multiplier) } (64, (128)x2, (256)x2, (512)x6, (1024)x2)];
my $strides = [(1, 2)x3, (1)x5, 2, 1];
for(zip($dw_channels, $channels, $strides))
{
my ($dwc, $c, $s) = @$_;
_add_conv_dw($self->features, dw_channels=>$dwc, channels=>$c, stride=>$s);
}
$self->features->add(nn->GlobalAvgPool2D());
$self->features->add(nn->Flatten());
});
$self->output(nn->Dense($self->classes));
});
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision::MobileNetV2;
use AI::MXNet::Gluon::Mouse;
use AI::MXNet::Base;
extends 'AI::MXNet::Gluon::HybridBlock';
has 'multiplier' => (is => 'ro', isa => 'Num', default => 1);
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
method python_constructor_arguments(){ [qw/multiplier classes/] }
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::MobileNetV2 - MobileNet model from the
"Inverted Residuals and Linear Bottlenecks: Mobile Networks for Classification, Detection and Segmentation"
=cut
=head1 DESCRIPTION
MobileNetV2 model from the
"Inverted Residuals and Linear Bottlenecks:
Mobile Networks for Classification, Detection and Segmentation"
<https://arxiv.org/abs/1801.04381> paper.
Parameters
----------
multiplier : Num, default 1.0
The width multiplier for controling the model size. Only multipliers that are no
less than 0.25 are supported. The actual number of channels is equal to the original
channel size multiplied by this multiplier.
classes : Int, default 1000
Number of classes for the output layer.
=cut
func _add_conv(
$out, $channels, :$kernel=1, :$stride=1, :$pad=0,
:$num_group=1, :$active=1, :$relu6=0
)
{
$out->add(nn->Conv2D($channels, $kernel, $stride, $pad, groups=>$num_group, use_bias=>0));
$out->add(nn->BatchNorm(scale=>1));
if($active)
{
$out->add($relu6 ? AI::MXNet::Gluon::ModelZoo::Vision::MobileNet::RELU6->new : nn->Activation('relu'));
}
}
sub BUILD
{
my $self = shift;
$self->name_scope(sub {
$self->features(nn->HybridSequential(prefix=>'features_'));
$self->features->name_scope(sub {
_add_conv(
$self->features, int(32 * $self->multiplier), kernel=>3,
stride=>2, pad=>1, relu6=>1
);
my $in_channels_group = [map { int($_ * $self->multiplier) } (32, 16, (24)x2, (32)x3, (64)x4, (96)x3, (160)x3)];
my $channels_group = [map { int($_ * $self->multiplier) } (16, (24)x2, (32)x3, (64)x4, (96)x3, (160)x3, 320)];
my $ts = [1, (6)x16];
my $strides = [(1, 2)x2, 1, 1, 2, (1)x6, 2, (1)x3];
for(zip($in_channels_group, $channels_group, $ts, $strides))
{
my ($in_c, $c, $t, $s) = @$_;
$self->features->add(
AI::MXNet::Gluon::ModelZoo::Vision::MobileNet::LinearBottleneck->new(
in_channels=>$in_c, channels=>$c,
t=>$t, stride=>$s
)
);
}
my $last_channels = $self->multiplier > 1 ? int(1280 * $self->multiplier) : 1280;
_add_conv($self->features, $last_channels, relu6=>1);
$self->features->add(nn->GlobalAvgPool2D());
});
$self->output(nn->HybridSequential(prefix=>'output_'));
$self->output->name_scope(sub {
$self->output->add(
nn->Conv2D($self->classes, 1, use_bias=>0, prefix=>'pred_'),
nn->Flatten()
);
});
});
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision;
=head2 get_mobilenet
MobileNet model from the
"MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
<https://arxiv.org/abs/1704.04861> paper.
Parameters
----------
$multiplier : Num
The width multiplier for controling the model size. Only multipliers that are no
less than 0.25 are supported. The actual number of channels is equal to the original
channel size multiplied by this multiplier.
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method get_mobilenet(
Num $multiplier, Bool :$pretrained=0, AI::MXNet::Context :$ctx=AI::MXNet::Context->cpu(),
Str :$root='~/.mxnet/models'
)
{
my $net = AI::MXNet::Gluon::ModelZoo::Vision::MobileNet->new($multiplier);
if($pretrained)
{
my $version_suffix = sprintf("%.2f", $multiplier);
if($version_suffix eq '1.00' or $version_suffix eq '0.50')
{
$version_suffix =~ s/.$//;
}
$net->load_parameters(
AI::MXNet::Gluon::ModelZoo::ModelStore->get_model_file(
"mobilenet$version_suffix",
root=>$root
),
ctx=>$ctx
);
}
return $net;
}
=head2 get_mobilenet_v2
MobileNetV2 model from the
"Inverted Residuals and Linear Bottlenecks:
Mobile Networks for Classification, Detection and Segmentation"
<https://arxiv.org/abs/1801.04381> paper.
Parameters
----------
$multiplier : Num
The width multiplier for controling the model size. Only multipliers that are no
less than 0.25 are supported. The actual number of channels is equal to the original
channel size multiplied by this multiplier.
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method get_mobilenet_v2(
Num $multiplier, Bool :$pretrained=0, AI::MXNet::Context :$ctx=AI::MXNet::Context->cpu(),
Str :$root='~/.mxnet/models'
)
{
my $net = AI::MXNet::Gluon::ModelZoo::Vision::MobileNetV2->new($multiplier);
if($pretrained)
{
my $version_suffix = sprintf("%.2f", $multiplier);
if($version_suffix eq '1.00' or $version_suffix eq '0.50')
{
$version_suffix =~ s/.$//;
}
$net->load_parameters(
AI::MXNet::Gluon::ModelZoo::ModelStore->get_model_file(
"mobilenetv2_$version_suffix",
root=>$root
),
ctx=>$ctx
);
}
return $net;
}
=head2 mobilenet1_0
MobileNet model from the
"MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
<https://arxiv.org/abs/1704.04861> paper, with width multiplier 1.0.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
=cut
method mobilenet1_0(%kwargs)
{
return __PACKAGE__->get_mobilenet(1.0, %kwargs);
}
=head2 mobilenet_v2_1_0
MobileNetV2 model from the
"Inverted Residuals and Linear Bottlenecks:
Mobile Networks for Classification, Detection and Segmentation"
<https://arxiv.org/abs/1801.04381> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
=cut
method mobilenet_v2_1_0(%kwargs)
{
return __PACKAGE__->get_mobilenet_v2(1.0, %kwargs);
}
=head2 mobilenet0_75
MobileNet model from the
"MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
<https://arxiv.org/abs/1704.04861> paper, with width multiplier 0.75.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
=cut
method mobilenet0_75(%kwargs)
{
return __PACKAGE__->get_mobilenet(0.75, %kwargs);
}
=head2 mobilenet_v2_0_75
MobileNetV2 model from the
"Inverted Residuals and Linear Bottlenecks:
Mobile Networks for Classification, Detection and Segmentation"
<https://arxiv.org/abs/1801.04381> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
=cut
method mobilenet_v2_0_75(%kwargs)
{
return __PACKAGE__->get_mobilenet_v2(0.75, %kwargs);
}
=head2 mobilenet0_5
MobileNet model from the
"MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
<https://arxiv.org/abs/1704.04861> paper, with width multiplier 0.5.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
=cut
method mobilenet0_5(%kwargs)
{
return __PACKAGE__->get_mobilenet(0.5, %kwargs);
}
=head2 mobilenet_v2_0_5
MobileNetV2 model from the
"Inverted Residuals and Linear Bottlenecks:
Mobile Networks for Classification, Detection and Segmentation"
<https://arxiv.org/abs/1801.04381> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
=cut
method mobilenet_v2_0_5(%kwargs)
{
return __PACKAGE__->get_mobilenet_v2(0.5, %kwargs);
}
=head2 mobilenet0_25
MobileNet model from the
"MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications"
<https://arxiv.org/abs/1704.04861> paper, with width multiplier 0.25.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
=cut
method mobilenet0_25(%kwargs)
{
return __PACKAGE__->get_mobilenet(0.25, %kwargs);
}
=head2 mobilenet_v2_0_25
MobileNetV2 model from the
"Inverted Residuals and Linear Bottlenecks:
Mobile Networks for Classification, Detection and Segmentation"
<https://arxiv.org/abs/1801.04381> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
=cut
method mobilenet_v2_0_25(%kwargs)
{
return __PACKAGE__->get_mobilenet_v2(0.25, %kwargs);
}
1;
lib/AI/MXNet/Gluon/ModelZoo/Vision/ResNet.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
use strict;
use warnings;
use AI::MXNet::Function::Parameters;
package AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BasicBlockV1;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BasicBlockV1 - BasicBlock V1 from `"Deep Residual Learning for Image Recognition"
=cut
=head1 DESCRIPTION
BasicBlock V1 from `"Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385>`_ paper.
This is used for ResNet V1 for 18, 34 layers.
Parameters
----------
channels : Int
Number of output channels.
stride : Int
Stride size.
downsample : Bool, default 0
Whether to downsample the input.
in_channels : Int, default 0
Number of input channels. Default is 0, to infer from the graph.
=cut
has ['channels',
'stride'] => (is => 'ro', isa => 'Int', required => 1);
has 'downsample' => (is => 'rw', default => 0);
has 'in_channels' => (is => 'ro', isa => 'Int', default => 0);
method python_constructor_arguments() { [qw/channels stride downsample/] }
func _conv3x3($channels, $stride, $in_channels)
{
return nn->Conv2D(
$channels, kernel_size=>3, strides=>$stride, padding=>1,
use_bias=>0, in_channels=>$in_channels
);
}
sub BUILD
{
my $self = shift;
$self->body(nn->HybridSequential(prefix=>''));
$self->body->add(_conv3x3($self->channels, $self->stride, $self->in_channels));
$self->body->add(nn->BatchNorm());
$self->body->add(nn->Activation('relu'));
$self->body->add(_conv3x3($self->channels, 1, $self->channels));
$self->body->add(nn->BatchNorm());
if($self->downsample)
{
$self->downsample(nn->HybridSequential(prefix=>''));
$self->downsample->add(
nn->Conv2D($self->channels, kernel_size=>1, strides=>$self->stride,
use_bias=>0, in_channels=>$self->in_channels)
);
$self->downsample->add(nn->BatchNorm());
}
else
{
$self->downsample(undef);
}
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
my $residual = $x;
$x = $self->body->($x);
if(defined $self->downsample)
{
$residual = $self->downsample->($residual);
}
$x = $F->Activation($residual+$x, act_type=>'relu');
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BottleneckV1;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BottleneckV1 - Bottleneck V1 from "Deep Residual Learning for Image Recognition"
=cut
=head1 DESCRIPTION
Bottleneck V1 from "Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385> paper.
This is used for ResNet V1 for 50, 101, 152 layers.
Parameters
----------
channels : int
Number of output channels.
stride : int
Stride size.
downsample : bool, default False
Whether to downsample the input.
in_channels : int, default 0
Number of input channels. Default is 0, to infer from the graph.
=cut
has ['channels',
'stride'] => (is => 'ro', isa => 'Int', required => 1);
has 'downsample' => (is => 'rw', default => 0);
has 'in_channels' => (is => 'ro', isa => 'Int', default => 0);
method python_constructor_arguments() { [qw/channels stride downsample/] }
func _conv3x3($channels, $stride, $in_channels)
{
return nn->Conv2D(
$channels, kernel_size=>3, strides=>$stride, padding=>1,
use_bias=>0, in_channels=>$in_channels
);
}
sub BUILD
{
my $self = shift;
$self->body(nn->HybridSequential(prefix=>''));
$self->body->add(nn->Conv2D(int($self->channels/4), kernel_size=>1, strides=>$self->stride));
$self->body->add(nn->BatchNorm());
$self->body->add(nn->Activation('relu'));
$self->body->add(_conv3x3(int($self->channels/4), 1, int($self->channels/4)));
$self->body->add(nn->BatchNorm());
$self->body->add(nn->Activation('relu'));
$self->body->add(nn->Conv2D($self->channels, kernel_size=>1, strides=>1));
$self->body->add(nn->BatchNorm());
if($self->downsample)
{
$self->downsample(nn->HybridSequential(prefix=>''));
$self->downsample->add(
nn->Conv2D($self->channels, kernel_size=>1, strides=>$self->stride,
use_bias=>0, in_channels=>$self->in_channels)
);
$self->downsample->add(nn->BatchNorm());
}
else
{
$self->downsample(undef);
}
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
my $residual = $x;
$x = $self->body->($x);
if(defined $self->downsample)
{
$residual = $self->downsample->($residual);
}
$x = $F->Activation($residual+$x, act_type=>'relu');
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BasicBlockV2;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BasicBlockV2 - BasicBlock V2 from "Identity Mappings in Deep Residual Networks"
=cut
=head1 DESCRIPTION
Bottleneck V2 from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
This is used for ResNet V2 for 18, 34 layers.
Parameters
----------
channels : Int
Number of output channels.
stride : Int
Stride size.
downsample : Bool, default 0
Whether to downsample the input.
in_channels : Int, default 0
Number of input channels. Default is 0, to infer from the graph.
=cut
has ['channels',
'stride'] => (is => 'ro', isa => 'Int', required => 1);
has 'downsample' => (is => 'rw', default => 0);
has 'in_channels' => (is => 'ro', isa => 'Int', default => 0);
method python_constructor_arguments() { [qw/channels stride downsample/] }
func _conv3x3($channels, $stride, $in_channels)
{
return nn->Conv2D(
$channels, kernel_size=>3, strides=>$stride, padding=>1,
use_bias=>0, in_channels=>$in_channels
);
}
sub BUILD
{
my $self = shift;
$self->bn1(nn->BatchNorm());
$self->conv1(_conv3x3($self->channels, $self->stride, $self->in_channels));
$self->bn2(nn->BatchNorm());
$self->conv2(_conv3x3($self->channels, 1, $self->channels));
if($self->downsample)
{
$self->downsample(
nn->Conv2D($self->channels, kernel_size=>1, strides=>$self->stride,
use_bias=>0, in_channels=>$self->in_channels)
);
}
else
{
$self->downsample(undef);
}
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
my $residual = $x;
$x = $self->bn1->($x);
$x = $F->Activation($x, act_type=>'relu');
if(defined $self->downsample)
{
$residual = $self->downsample->($x);
}
$x = $self->conv1->($x);
$x = $self->bn2->($x);
$x = $F->Activation($x, act_type=>'relu');
$x = $self->conv2->($x);
return $x + $residual;
}
package AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BottleneckV2;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BottleneckV2 - Bottleneck V2 from "Identity Mappings in Deep Residual Networks"
=cut
=head1 DESCRIPTION
Bottleneck V2 from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
This is used for ResNet V2 for 50, 101, 152 layers.
Parameters
----------
channels : int
Number of output channels.
stride : int
Stride size.
downsample : bool, default False
Whether to downsample the input.
in_channels : int, default 0
Number of input channels. Default is 0, to infer from the graph.
=cut
has ['channels',
'stride'] => (is => 'ro', isa => 'Int', required => 1);
has 'downsample' => (is => 'rw', default => 0);
has 'in_channels' => (is => 'ro', isa => 'Int', default => 0);
method python_constructor_arguments() { [qw/channels stride downsample/] }
func _conv3x3($channels, $stride, $in_channels)
{
return nn->Conv2D(
$channels, kernel_size=>3, strides=>$stride, padding=>1,
use_bias=>0, in_channels=>$in_channels
);
}
sub BUILD
{
my $self = shift;
$self->bn1(nn->BatchNorm());
$self->conv1(nn->Conv2D(int($self->channels/4), kernel_size=>1, strides=>1, use_bias=>0));
$self->bn2(nn->BatchNorm());
$self->conv2(_conv3x3(int($self->channels/4), $self->stride, int($self->channels/4)));
$self->bn3(nn->BatchNorm());
$self->conv3(nn->Conv2D($self->channels, kernel_size=>1, strides=>1, use_bias=>0));
if($self->downsample)
{
$self->downsample(
nn->Conv2D($self->channels, kernel_size=>1, strides=>$self->stride,
use_bias=>0, in_channels=>$self->in_channels)
);
}
else
{
$self->downsample(undef);
}
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
my $residual = $x;
$x = $self->bn1->($x);
$x = $F->Activation($x, act_type=>'relu');
if(defined $self->downsample)
{
$residual = $self->downsample->($x);
}
$x = $self->conv1->($x);
$x = $self->bn2->($x);
$x = $F->Activation($x, act_type=>'relu');
$x = $self->conv2->($x);
$x = $self->bn3->($x);
$x = $F->Activation($x, act_type=>'relu');
$x = $self->conv3->($x);
return $x + $residual;
}
# Nets
package AI::MXNet::Gluon::ModelZoo::Vision::ResNet::V1;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
use AI::MXNet::Base;
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::ResNet::V1 - ResNet V1 model from "Deep Residual Learning for Image Recognition"
=cut
=head1 DESCRIPTION
ResNet V1 model from from "Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385> paper.
Parameters
----------
block : AI::MXNet::Gluon::HybridBlock
Class for the residual block. Options are AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BasicBlockV1,
AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BottleneckV1.
layers : array ref of Int
Numbers of layers in each block
channels : array ref of Int
Numbers of channels in each block. Length should be one larger than layers list.
classes : int, default 1000
Number of classification classes.
thumbnail : bool, default 0
Enable thumbnail.
=cut
has 'block' => (is => 'ro', isa => 'Str', required => 1);
has ['layers',
'channels'] => (is => 'ro', isa => 'ArrayRef[Int]', required => 1);
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
has 'thumbnail' => (is => 'ro', isa => 'Bool', default => 0);
method python_constructor_arguments() { [qw/block layers channels classes thumbnail/] }
func _conv3x3($channels, $stride, $in_channels)
{
return nn->Conv2D(
$channels, kernel_size=>3, strides=>$stride, padding=>1,
use_bias=>0, in_channels=>$in_channels
);
}
sub BUILD
{
my $self = shift;
assert(@{ $self->layers } == (@{ $self->channels } - 1));
$self->name_scope(sub {
$self->features(nn->HybridSequential(prefix=>''));
if($self->thumbnail)
{
$self->features->add(_conv3x3($self->channels->[0], 1, 0));
}
else
{
$self->features->add(nn->Conv2D($self->channels->[0], 7, 2, 3, use_bias=>0));
$self->features->add(nn->BatchNorm());
$self->features->add(nn->Activation('relu'));
$self->features->add(nn->MaxPool2D(3, 2, 1));
}
for(enumerate($self->layers))
{
my ($i, $num_layer) = @$_;
my $stride = $i == 0 ? 1 : 2;
$self->features->add(
$self->_make_layer(
$self->block, $num_layer, $self->channels->[$i+1],
$stride, $i+1, in_channels=>$self->channels->[$i]
)
);
}
$self->features->add(nn->GlobalAvgPool2D());
$self->output(nn->Dense($self->classes, in_units=>$self->channels->[-1]));
});
}
method _make_layer($block, $layers, $channels, $stride, $stage_index, :$in_channels=0)
{
my $layer = nn->HybridSequential(prefix=>"stage${stage_index}_");
$layer->name_scope(sub {
$layer->add(
$block->new(
$channels, $stride, $channels != $in_channels, in_channels=>$in_channels,
prefix=>''
)
);
for(1..$layers-1)
{
$layer->add($block->new($channels, 1, 0, in_channels=>$channels, prefix=>''));
}
});
return $layer;
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision::ResNet::V2;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
use AI::MXNet::Base;
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::ResNet::V2 - ResNet V2 model from "Identity Mappings in Deep Residual Networks"
=cut
=head1 DESCRIPTION
ResNet V2 model from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
Parameters
----------
block : AI::MXNet::Gluon::HybridBlock
Class for the residual block. Options are AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BasicBlockV2,
AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BottleneckV2.
layers : array ref of Int
Numbers of layers in each block
channels : array ref of Int
Numbers of channels in each block. Length should be one larger than layers list.
classes : int, default 1000
Number of classification classes.
thumbnail : bool, default 0
Enable thumbnail.
=cut
has 'block' => (is => 'ro', isa => 'Str', required => 1);
has ['layers',
'channels'] => (is => 'ro', isa => 'ArrayRef[Int]', required => 1);
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
has 'thumbnail' => (is => 'ro', isa => 'Bool', default => 0);
method python_constructor_arguments() { [qw/block layers channels classes thumbnail/] }
func _conv3x3($channels, $stride, $in_channels)
{
return nn->Conv2D(
$channels, kernel_size=>3, strides=>$stride, padding=>1,
use_bias=>0, in_channels=>$in_channels
);
}
sub BUILD
{
my $self = shift;
assert(@{ $self->layers } == (@{ $self->channels } - 1));
$self->name_scope(sub {
$self->features(nn->HybridSequential(prefix=>''));
$self->features->add(nn->BatchNorm(scale=>0, center=>0));
if($self->thumbnail)
{
$self->features->add(_conv3x3($self->channels->[0], 1, 0));
}
else
{
$self->features->add(nn->Conv2D($self->channels->[0], 7, 2, 3, use_bias=>0));
$self->features->add(nn->BatchNorm());
$self->features->add(nn->Activation('relu'));
$self->features->add(nn->MaxPool2D(3, 2, 1));
}
my $in_channels = $self->channels->[0];
for(enumerate($self->layers))
{
my ($i, $num_layer) = @$_;
my $stride = $i == 0 ? 1 : 2;
$self->features->add(
$self->_make_layer(
$self->block, $num_layer, $self->channels->[$i+1],
$stride, $i+1, in_channels=>$in_channels
)
);
$in_channels = $self->channels->[$i+1];
}
$self->features->add(nn->BatchNorm());
$self->features->add(nn->Activation('relu'));
$self->features->add(nn->GlobalAvgPool2D());
$self->features->add(nn->Flatten());
$self->output(nn->Dense($self->classes, in_units=>$in_channels));
});
}
method _make_layer($block, $layers, $channels, $stride, $stage_index, :$in_channels=0)
{
my $layer = nn->HybridSequential(prefix=>"stage${stage_index}_");
$layer->name_scope(sub {
$layer->add(
$block->new(
$channels, $stride, $channels != $in_channels, in_channels=>$in_channels,
prefix=>''
)
);
for(1..$layers-1)
{
$layer->add($block->new($channels, 1, 0, in_channels=>$channels, prefix=>''));
}
});
return $layer;
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision;
# Specification
my %resnet_spec = (
18 => ['basic_block', [2, 2, 2, 2], [64, 64, 128, 256, 512]],
34 => ['basic_block', [3, 4, 6, 3], [64, 64, 128, 256, 512]],
50 => ['bottle_neck', [3, 4, 6, 3], [64, 256, 512, 1024, 2048]],
101 => ['bottle_neck', [3, 4, 23, 3], [64, 256, 512, 1024, 2048]],
152 => ['bottle_neck', [3, 8, 36, 3], [64, 256, 512, 1024, 2048]]
);
my @resnet_net_versions = qw(AI::MXNet::Gluon::ModelZoo::Vision::ResNet::V1 AI::MXNet::Gluon::ModelZoo::Vision::ResNet::V2);
my @resnet_block_versions = (
{
basic_block => 'AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BasicBlockV1',
bottle_neck => 'AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BottleneckV1'
},
{
basic_block => 'AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BasicBlockV2',
bottle_neck => 'AI::MXNet::Gluon::ModelZoo::Vision::ResNet::BottleneckV2'
},
);
=head2 get_resnet
ResNet V1 model from "Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385> paper.
ResNet V2 model from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
Parameters
----------
$version : Int
Version of ResNet. Options are 1, 2.
$num_layers : Int
Numbers of layers. Options are 18, 34, 50, 101, 152.
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
# Constructor
method get_resnet(
Int $version, Int $num_layers, Bool :$pretrained=0,
AI::MXNet::Context :$ctx=AI::MXNet::Context->cpu(),
Str :$root='~/.mxnet/models',
Maybe[Int] :$classes=,
Maybe[Bool] :$thumbnail=
)
{
my ($block_type, $layers, $channels) = @{ $resnet_spec{$num_layers} };
my $resnet_class = $resnet_net_versions[$version-1];
confess("invalid resnet $version [$version], can be 1,2") unless $resnet_class;
my $block_class = $resnet_block_versions[$version-1]{$block_type};
my $net = $resnet_class->new(
$block_class, $layers, $channels,
(defined($classes) ? (classes => $classes) : ()),
(defined($thumbnail) ? (thumbnail => $thumbnail) : ())
);
if($pretrained)
{
$net->load_parameters(
AI::MXNet::Gluon::ModelZoo::ModelStore->get_model_file(
"resnet${num_layers}_v$version",
root=>$root
),
ctx=>$ctx
);
}
return $net;
}
=head2 resnet18_v1
ResNet-18 V1 model from "Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet18_v1(%kwargs)
{
return __PACKAGE__->get_resnet(1, 18, %kwargs);
}
=head2 resnet34_v1
ResNet-34 V1 model from "Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet34_v1(%kwargs)
{
return __PACKAGE__->get_resnet(1, 34, %kwargs);
}
=head2 resnet50_v1
ResNet-50 V1 model from "Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet50_v1(%kwargs)
{
return __PACKAGE__->get_resnet(1, 50, %kwargs);
}
=head2 resnet101_v1
ResNet-101 V1 model from "Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet101_v1(%kwargs)
{
return __PACKAGE__->get_resnet(1, 101, %kwargs);
}
=head2 resnet152_v1
ResNet-152 V1 model from "Deep Residual Learning for Image Recognition"
<http://arxiv.org/abs/1512.03385> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet152_v1(%kwargs)
{
return __PACKAGE__->get_resnet(1, 152, %kwargs);
}
=head2 resnet18_v2
ResNet-18 V2 model from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet18_v2(%kwargs)
{
return __PACKAGE__->get_resnet(2, 18, %kwargs);
}
=head2 resnet34_v2
ResNet-34 V2 model from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet34_v2(%kwargs)
{
return __PACKAGE__->get_resnet(2, 34, %kwargs);
}
=head2 resnet50_v2
ResNet-50 V2 model from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet50_v2(%kwargs)
{
return __PACKAGE__->get_resnet(2, 50, %kwargs);
}
=head2 resnet101_v2
ResNet-101 V2 model from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet101_v2(%kwargs)
{
return __PACKAGE__->get_resnet(2, 101, %kwargs);
}
=head2 resnet152_v2
ResNet-152 V2 model from "Identity Mappings in Deep Residual Networks"
<https://arxiv.org/abs/1603.05027> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method resnet152_v2(%kwargs)
{
return __PACKAGE__->get_resnet(2, 152, %kwargs);
}
1;
lib/AI/MXNet/Gluon/ModelZoo/Vision/SqueezeNet.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
package AI::MXNet::Gluon::ModelZoo::Vision::SqueezeNet;
use strict;
use warnings;
use AI::MXNet::Function::Parameters;
use AI::MXNet::Gluon::Mouse;
use AI::MXNet::Types;
extends 'AI::MXNet::Gluon::HybridBlock';
func _make_fire($squeeze_channels, $expand1x1_channels, $expand3x3_channels)
{
my $out = nn->HybridSequential(prefix=>'');
$out->add(_make_fire_conv($squeeze_channels, 1));
my $paths = nn->HybridConcurrent(axis=>1, prefix=>'');
$paths->add(_make_fire_conv($expand1x1_channels, 1));
$paths->add(_make_fire_conv($expand3x3_channels, 3, 1));
$out->add($paths);
return $out;
}
func _make_fire_conv($channels, $kernel_size, $padding=0)
{
my $out = nn->HybridSequential(prefix=>'');
$out->add(nn->Conv2D($channels, $kernel_size, padding=>$padding));
$out->add(nn->Activation('relu'));
return $out;
}
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::SqueezeNet - SqueezeNet model from the "SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size"
=cut
=head1 DESCRIPTION
SqueezeNet model from the "SqueezeNet: AlexNet-level accuracy with 50x fewer parameters
and <0.5MB model size" <https://arxiv.org/abs/1602.07360> paper.
SqueezeNet 1.1 model from the official SqueezeNet repo
<https://github.com/DeepScale/SqueezeNet/tree/master/SqueezeNet_v1.1>.
SqueezeNet 1.1 has 2.4x less computation and slightly fewer parameters
than SqueezeNet 1.0, without sacrificing accuracy.
Parameters
----------
version : Str
Version of squeezenet. Options are '1.0', '1.1'.
classes : Int, default 1000
Number of classification classes.
=cut
has 'version' => (is => 'ro', isa => enum([qw[1.0 1.1]]), required => 1);
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
method python_constructor_arguments() { [qw/version classes/] }
sub BUILD
{
my $self = shift;
$self->name_scope(sub {
$self->features(nn->HybridSequential(prefix=>''));
if($self->version eq '1.0')
{
$self->features->add(nn->Conv2D(96, kernel_size=>7, strides=>2));
$self->features->add(nn->Activation('relu'));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2, ceil_mode=>1));
$self->features->add(_make_fire(16, 64, 64));
$self->features->add(_make_fire(16, 64, 64));
$self->features->add(_make_fire(32, 128, 128));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2, ceil_mode=>1));
$self->features->add(_make_fire(32, 128, 128));
$self->features->add(_make_fire(48, 192, 192));
$self->features->add(_make_fire(48, 192, 192));
$self->features->add(_make_fire(64, 256, 256));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2, ceil_mode=>1));
$self->features->add(_make_fire(64, 256, 256));
}
else
{
$self->features->add(nn->Conv2D(64, kernel_size=>3, strides=>2));
$self->features->add(nn->Activation('relu'));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2, ceil_mode=>1));
$self->features->add(_make_fire(16, 64, 64));
$self->features->add(_make_fire(16, 64, 64));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2, ceil_mode=>1));
$self->features->add(_make_fire(32, 128, 128));
$self->features->add(_make_fire(32, 128, 128));
$self->features->add(nn->MaxPool2D(pool_size=>3, strides=>2, ceil_mode=>1));
$self->features->add(_make_fire(48, 192, 192));
$self->features->add(_make_fire(48, 192, 192));
$self->features->add(_make_fire(64, 256, 256));
$self->features->add(_make_fire(64, 256, 256));
}
$self->features->add(nn->Dropout(0.5));
$self->output(nn->HybridSequential(prefix=>''));
$self->output->add(nn->Conv2D($self->classes, kernel_size=>1));
$self->output->add(nn->Activation('relu'));
$self->output->add(nn->AvgPool2D(13));
$self->output->add(nn->Flatten());
});
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision;
=head2 get_squeezenet
SqueezeNet model from the "SqueezeNet: AlexNet-level accuracy with 50x fewer parameters
and <0.5MB model size" <https://arxiv.org/abs/1602.07360> paper.
SqueezeNet 1.1 model from the official SqueezeNet repo
<https://github.com/DeepScale/SqueezeNet/tree/master/SqueezeNet_v1.1>.
SqueezeNet 1.1 has 2.4x less computation and slightly fewer parameters
than SqueezeNet 1.0, without sacrificing accuracy.
Parameters
----------
$version : Str
Version of squeezenet. Options are '1.0', '1.1'.
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method get_squeezenet(
Str $version, Bool :$pretrained=0, AI::MXNet::Context :$ctx=AI::MXNet::Context->cpu(),
Str :$root='~/.mxnet/models', Int :$classes=1000
)
{
my $net = AI::MXNet::Gluon::ModelZoo::Vision::SqueezeNet->new($version, $classes);
if($pretrained)
{
$net->load_parameters(
AI::MXNet::Gluon::ModelZoo::ModelStore->get_model_file(
"squeezenet$version",
root=>$root
),
ctx=>$ctx
);
}
return $net;
}
=head2 squeezenet1_0
SqueezeNet 1.0 model from the "SqueezeNet: AlexNet-level accuracy with 50x fewer parameters
and <0.5MB model size" <https://arxiv.org/abs/1602.07360> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method squeezenet1_0(%kwargs)
{
return __PACKAGE__->get_squeezenet('1.0', %kwargs);
}
=head2 squeezenet1_1
SqueezeNet 1.1 model from the official SqueezeNet repo
<https://github.com/DeepScale/SqueezeNet/tree/master/SqueezeNet_v1.1>.
SqueezeNet 1.1 has 2.4x less computation and slightly fewer parameters
than SqueezeNet 1.0, without sacrificing accuracy.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default CPU
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method squeezenet1_1(%kwargs)
{
return __PACKAGE__->get_squeezenet('1.1', %kwargs);
}
1;
lib/AI/MXNet/Gluon/ModelZoo/Vision/VGG.pm view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
use strict;
use warnings;
use AI::MXNet::Function::Parameters;
package AI::MXNet::Gluon::ModelZoo::Vision::VGG;
use AI::MXNet::Gluon::Mouse;
extends 'AI::MXNet::Gluon::HybridBlock';
use AI::MXNet::Base;
=head1 NAME
AI::MXNet::Gluon::ModelZoo::Vision::VGG - VGG model from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
=cut
=head1 DESCRIPTION
VGG model from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
layers : array ref of Int
Numbers of layers in each feature block.
filters : array ref of Int
Numbers of filters in each feature block. List length should match the layers.
classes : Int, default 1000
Number of classification classes.
batch_norm : Bool, default 0
Use batch normalization.
=cut
method python_constructor_arguments() { [qw/layers filters classes batch_norm/] }
has ['layers',
'filters'] => (is => 'ro', isa => 'ArrayRef[Int]', required => 1);
has 'classes' => (is => 'ro', isa => 'Int', default => 1000);
has 'batch_norm' => (is => 'ro', isa => 'Bool', default => 0);
sub BUILD
{
my $self = shift;
assert(@{ $self->layers } == @{ $self->filters });
$self->name_scope(sub {
$self->features($self->_make_features());
$self->features->add(nn->Dense(4096, activation=>'relu',
weight_initializer=>'normal',
bias_initializer=>'zeros'));
$self->features->add(nn->Dropout(rate=>0.5));
$self->features->add(nn->Dense(4096, activation=>'relu',
weight_initializer=>'normal',
bias_initializer=>'zeros'));
$self->features->add(nn->Dropout(rate=>0.5));
$self->output(nn->Dense($self->classes,
weight_initializer=>'normal',
bias_initializer=>'zeros'));
});
}
method _make_features()
{
my $featurizer = nn->HybridSequential(prefix=>'');
for(enumerate($self->layers))
{
my ($i, $num) = @$_;
for(0..$num-1)
{
$featurizer->add(
nn->Conv2D(
$self->filters->[$i], kernel_size => 3, padding => 1,
weight_initializer => mx->init->Xavier(
rnd_type => 'gaussian',
factor_type => 'out',
magnitude => 2
),
bias_initializer=>'zeros'
)
);
if($self->batch_norm)
{
$featurizer->add(nn->BatchNorm());
}
$featurizer->add(nn->Activation('relu'));
}
$featurizer->add(nn->MaxPool2D(strides=>2));
}
return $featurizer;
}
method hybrid_forward(GluonClass $F, GluonInput $x)
{
$x = $self->features->($x);
$x = $self->output->($x);
return $x;
}
package AI::MXNet::Gluon::ModelZoo::Vision;
# Specification
my %vgg_spec = (
11 => [[1, 1, 2, 2, 2], [64, 128, 256, 512, 512]],
13 => [[2, 2, 2, 2, 2], [64, 128, 256, 512, 512]],
16 => [[2, 2, 3, 3, 3], [64, 128, 256, 512, 512]],
19 => [[2, 2, 4, 4, 4], [64, 128, 256, 512, 512]]
);
=head2 get_vgg
VGG model from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
$num_layers : Int
Number of layers for the variant of densenet. Options are 11, 13, 16, 19.
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method get_vgg(
Int $num_layers, Bool :$pretrained=0, AI::MXNet::Context :$ctx=AI::MXNet::Context->cpu(),
Str :$root='~/.mxnet/models', Int :$classes=1000, Bool :$batch_norm=0
)
{
my ($layers, $filters) = @{ $vgg_spec{$num_layers} };
my $net = AI::MXNet::Gluon::ModelZoo::Vision::VGG->new($layers, $filters, $classes, $batch_norm);
if($pretrained)
{
$net->load_parameters(
AI::MXNet::Gluon::ModelZoo::ModelStore->get_model_file(
"vgg$num_layers".($batch_norm ? '_bn' : ''),
root=>$root
),
ctx=>$ctx
);
}
return $net;
}
=head2 vgg11
VGG-11 model from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method vgg11(%kwargs)
{
return __PACKAGE__->get_vgg(11, %kwargs);
}
=head2 vgg13
VGG-13 model from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method vgg13(%kwargs)
{
return __PACKAGE__->get_vgg(13, %kwargs);
}
=head2 vgg16
VGG-16 model from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method vgg16(%kwargs)
{
return __PACKAGE__->get_vgg(16, %kwargs);
}
=head2 vgg19
VGG-19 model from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method vgg19(%kwargs)
{
return __PACKAGE__->get_vgg(19, %kwargs);
}
=head2 vgg11_bn
VGG-11 model with batch normalization from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method vgg11_bn(%kwargs)
{
$kwargs{batch_norm} = 1;
return __PACKAGE__->get_vgg(11, %kwargs);
}
=head2 vgg13_bn
VGG-13 model with batch normalization from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method vgg13_bn(%kwargs)
{
$kwargs{batch_norm} = 1;
return __PACKAGE__->get_vgg(13, %kwargs);
}
=head2 vgg16_bn
VGG-16 model with batch normalization from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method vgg16_bn(%kwargs)
{
$kwargs{batch_norm} = 1;
return __PACKAGE__->get_vgg(16, %kwargs);
}
=head2 vgg19_bn
VGG-19 model with batch normalization from the "Very Deep Convolutional Networks for Large-Scale Image Recognition"
<https://arxiv.org/abs/1409.1556> paper.
Parameters
----------
:$pretrained : Bool, default 0
Whether to load the pretrained weights for model.
:$ctx : AI::MXNet::Context, default AI::MXNet::Context->cpu
The context in which to load the pretrained weights.
:$root : Str, default '~/.mxnet/models'
Location for keeping the model parameters.
=cut
method vgg19_bn(%kwargs)
{
$kwargs{batch_norm} = 1;
return __PACKAGE__->get_vgg(19, %kwargs);
}
1;
t/AI-MXNet-Gluon-ModelZoo.t view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
use strict;
use warnings;
use Test::More tests => 1;
BEGIN { use_ok('AI::MXNet::Gluon::ModelZoo') };
t/test_gluon_model_zoo.t view on Meta::CPAN
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
use strict;
use warnings;
use AI::MXNet::Gluon::ModelZoo qw(get_model);
use Test::More tests => 34;
sub test_models
{
my @all_models = ('resnet34_v1', 'resnet18_v1', 'resnet50_v1', 'resnet101_v1', 'resnet152_v1',
'resnet18_v2', 'resnet34_v2', 'resnet50_v2', 'resnet101_v2', 'resnet152_v2',
'vgg11', 'vgg13', 'vgg16', 'vgg19',
'vgg11_bn', 'vgg13_bn', 'vgg16_bn', 'vgg19_bn',
'alexnet', 'inceptionv3',
'densenet121', 'densenet161', 'densenet169', 'densenet201',
'squeezenet1.0', 'squeezenet1.1',
'mobilenet1.0', 'mobilenet0.75', 'mobilenet0.5', 'mobilenet0.25',
'mobilenetv2_1.0', 'mobilenetv2_0.75', 'mobilenetv2_0.5', 'mobilenetv2_0.25');
my %pretrained_to_test = ('squeezenet1.1' => 1);
for my $model_name (@all_models)
{
my $test_pretrain = exists $pretrained_to_test{ $model_name };
my $model = get_model($model_name, pretrained=>$test_pretrain, root=>'model/');
my $data_shape = $model_name !~ /inception/ ? [2, 3, 224, 224] : [2, 3, 299, 299];
if(not $test_pretrain)
{
$model->collect_params()->initialize();
}
$model->hybridize();
$model->(mx->nd->random->uniform(shape=>$data_shape))->wait_to_read;
ok(1, "forward for $model_name");
}
}
test_models();
view all matches for this distributionview release on metacpan - search on metacpan