AI-MXNet-Gluon-ModelZoo

 view release on metacpan or  search on metacpan

lib/AI/MXNet/Gluon/ModelZoo/Vision/ResNet.pm  view on Meta::CPAN

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);



( run in 0.913 second using v1.01-cache-2.11-cpan-d80b1682f3f )