view release on metacpan or search on metacpan
examples/char_lstm.pl view on Meta::CPAN
package AI::MXNet::RNN::IO::ASCIIIterator;
use Mouse;
extends AI::MXNet::DataIter;
has 'data' => (is => 'ro', isa => 'PDL', required => 1);
has 'seq_size' => (is => 'ro', isa => 'Int', required => 1);
has '+batch_size' => (is => 'ro', isa => 'Int', required => 1);
has 'data_name' => (is => 'ro', isa => 'Str', default => 'data');
has 'label_name' => (is => 'ro', isa => 'Str', default => 'softmax_label');
has 'dtype' => (is => 'ro', isa => 'Dtype', default => 'float32');
has [qw/nd counter seq_counter vocab_size
data_size provide_data provide_label idx/] => (is => 'rw', init_arg => undef);
sub BUILD
{
my $self = shift;
$self->data_size($self->data->nelem);
my $segments = int(($self->data_size-$self->seq_size)/($self->batch_size*$self->seq_size));
$self->idx([0..$segments-1]);
$self->vocab_size($self->data->uniq->shape->at(0));
$self->counter(0);
$self->seq_counter(0);
examples/char_lstm.pl view on Meta::CPAN
}
method reset()
{
$self->counter(0);
@{ $self->idx } = List::Util::shuffle(@{ $self->idx });
}
method next()
{
return undef if $self->counter == @{$self->idx};
my $offset = $self->idx->[$self->counter]*$self->batch_size*$self->seq_size + $self->seq_counter;
my $data = $self->nd->slice(
[$offset, $offset + $self->batch_size*$self->seq_size-1]
)->reshape([$self->batch_size, $self->seq_size]);
my $label = $self->nd->slice(
[$offset + 1 , $offset + $self->batch_size*$self->seq_size]
)->reshape([$self->batch_size, $self->seq_size]);
$self->seq_counter($self->seq_counter + 1);
if($self->seq_counter == $seq_size - 1)
{
examples/char_lstm.pl view on Meta::CPAN
dtype => $self->dtype
)
],
);
}
package main;
my $file = "data/input.txt";
open(F, $file) or die "can't open $file: $!";
my $fdata;
{ local($/) = undef; $fdata = <F>; close(F) };
my %vocabulary; my $i = 0;
$fdata = pdl(map{ exists $vocabulary{$_} ? $vocabulary{$_} : ($vocabulary{$_} = $i++) } split(//, $fdata));
my $data_iter = AI::MXNet::RNN::IO::ASCIIIterator->new(
batch_size => $batch_size,
data => $fdata,
seq_size => $seq_size
);
my %reverse_vocab = reverse %vocabulary;
my $mode = "${cell_mode}Cell";
my $stack = mx->rnn->SequentialRNNCell();
examples/cudnn_lstm_bucketing.pl view on Meta::CPAN
my $model = mx->mod->BucketingModule(
sym_gen => $sym_gen,
default_bucket_key => $data_train->default_bucket_key,
context => $contexts
);
my ($arg_params, $aux_params);
if($load_epoch)
{
(undef, $arg_params, $aux_params) = mx->rnn->load_rnn_checkpoint(
$cell, $model_prefix, $load_epoch);
}
$model->fit(
$data_train,
eval_data => $data_val,
eval_metric => mx->metric->Perplexity($invalid_label),
kvstore => $kv_store,
optimizer => $optimizer,
optimizer_params => {
learning_rate => $lr,
examples/cudnn_lstm_bucketing.pl view on Meta::CPAN
begin_epoch => $load_epoch,
initializer => mx->init->Xavier(factor_type => "in", magnitude => 2.34),
num_epoch => $num_epoch,
batch_end_callback => mx->callback->Speedometer($batch_size, $disp_batches),
($model_prefix ? (epoch_end_callback => mx->rnn->do_rnn_checkpoint($cell, $model_prefix, 1)) : ())
);
};
my $test = sub {
assert($model_prefix, "Must specifiy path to load from");
my (undef, $data_val, $vocab) = get_data('NT');
my $stack;
if($stack_rnn)
{
$stack = mx->rnn->SequentialRNNCell();
for my $i (0..$num_layers-1)
{
my $cell = mx->rnn->LSTMCell(num_hidden => $num_hidden, prefix => "lstm_${i}l0_");
if($bidirectional)
{
$cell = mx->rnn->BidirectionalCell(
examples/cudnn_lstm_bucketing.pl view on Meta::CPAN
$contexts = [map { mx->gpu($_) } split(/,/, $gpus)];
}
else
{
$contexts = mx->cpu(0);
}
my ($arg_params, $aux_params);
if($load_epoch)
{
(undef, $arg_params, $aux_params) = mx->rnn->load_rnn_checkpoint(
$stack, $model_prefix, $load_epoch);
}
my $model = mx->mod->BucketingModule(
sym_gen => $sym_gen,
default_bucket_key => $data_val->default_bucket_key,
context => $contexts
);
$model->bind(
data_shapes => $data_val->provide_data,
label_shapes => $data_val->provide_label,
examples/mnist.pl view on Meta::CPAN
$win->show_all();
Gtk2->main();
}
sub show_network {
my($viz) = @_;
my $load = Gtk2::Gdk::PixbufLoader->new();
$load->write($viz->graph->as_png);
$load->close();
my $img = Gtk2::Image->new_from_pixbuf($load->get_pixbuf());
my $sw = Gtk2::ScrolledWindow->new(undef, undef);
$sw->add_with_viewport($img);
my $win = Gtk2::Window->new('toplevel');
$win->signal_connect(delete_event => sub { Gtk2->main_quit() });
$win->add($sw);
$win->show_all();
Gtk2->main();
}
#show_sample();
lib/AI/MXNet/Contrib/AutoGrad.pm view on Meta::CPAN
);
}
=head2 backward
Compute the gradients of outputs w.r.t variables.
Parameters
----------
outputs: array ref of NDArray
out_grads: array ref of NDArray or undef
retain_graph: bool, defaults to false
=cut
method backward(
ArrayRef[AI::MXNet::NDArray] $outputs,
Maybe[ArrayRef[AI::MXNet::NDArray|Undef]] $out_grads=,
Bool $retain_graph=0
)
{
lib/AI/MXNet/Contrib/AutoGrad.pm view on Meta::CPAN
[],
$retain_graph
)
);
return;
}
my @ograd_handles;
for my $arr (@$out_grads)
{
push @ograd_handles, (defined $arr ? $arr->handle : undef);
}
assert(
(@ograd_handles == @output_handles),
"outputs and out_grads must have the same length"
);
check_call(
AI::MXNetCAPI::AutogradBackward(
scalar(@output_handles),
\@output_handles,
lib/AI/MXNet/Executor.pm view on Meta::CPAN
has '_symbol' => (is => 'rw', init_arg => 'symbol', isa => 'AI::MXNet::Symbol');
has '_ctx' => (is => 'rw', init_arg => 'ctx', isa => 'AI::MXNet::Context' );
has '_grad_req' => (is => 'rw', init_arg => 'grad_req', isa => 'Maybe[Str|ArrayRef[Str]|HashRef[Str]]');
has '_group2ctx' => (is => 'rw', init_arg => 'group2ctx', isa => 'Maybe[HashRef[AI::MXNet::Context]]');
has '_monitor_callback' => (is => 'rw', isa => 'CodeRef');
has [qw/_arg_dict
_grad_dict
_aux_dict
_output_dict
outputs
_output_dirty/] => (is => 'rw', init_arg => undef);
=head1 NAME
AI::MXNet::Executor - The actual executing object of MXNet.
=head2 new
Constructor, used by AI::MXNet::Symbol->bind and by AI::MXNet::Symbol->simple_bind.
Parameters
----------
lib/AI/MXNet/Executor.pm view on Meta::CPAN
AI::MXNetCAPI::ExecutorBackward(
$self->handle,
scalar(@{ $out_grads }),
[map { $_->handle } @{ $out_grads }]
)
);
if(not $self->_output_dirty)
{
AI::MXNet::Logging->warning(
"Calling backward without calling forward(is_train=True) "
."first. Behavior is undefined."
);
}
$self->_output_dirty(0);
}
=head2 set_monitor_callback
Install callback.
Parameters
lib/AI/MXNet/Executor.pm view on Meta::CPAN
Returns
-------
$exec : AI::MXNet::Executor
A new executor that shares memory with self.
=cut
method reshape(HashRef[Shape] $kwargs, Int :$partial_shaping=0, Int :$allow_up_sizing=0)
{
my ($arg_shapes, undef, $aux_shapes) = $self->_symbol->infer_shape(%{ $kwargs });
confess("Insufficient argument shapes provided.")
unless defined $arg_shapes;
my %new_arg_dict;
my %new_grad_dict;
my $i = 0;
for my $name (@{ $self->_symbol->list_arguments() })
{
my $new_shape = $arg_shapes->[$i];
my $arr = $self->arg_arrays->[$i];
my $darr;
lib/AI/MXNet/Executor/Group.pm view on Meta::CPAN
## this class is here because of https://github.com/gfx/p5-Mouse/pull/67
## once 2.4.7 version of Mouse in Ubuntu for affected Perl version
## these accessors should be merged into main class
package AI::MXNet::DataParallelExecutorGroup::_private;
use Mouse;
has [qw/output_layouts label_layouts arg_names aux_names
batch_size slices execs data_arrays
label_arrays param_arrays grad_arrays aux_arrays
data_layouts shared_data_arrays input_grad_arrays
_default_execs state_arrays/
] => (is => 'rw', init_arg => undef);
package AI::MXNet::DataParallelExecutorGroup;
use Mouse;
use AI::MXNet::Base;
use List::Util qw(sum);
=head1 DESCRIPTION
DataParallelExecutorGroup is a group of executors that lives on a group of devices.
This is a helper class used to implement data parallelization. Each mini-batch will
be split and run on the devices.
Parameters for constructor
----------
symbol : AI::MXNet::Symbol
The common symbolic computation graph for all executors.
contexts : ArrayRef[AI::MXNet::Context]
A array ref of contexts.
workload : ArrayRef[Num]
If not undef, could be an array ref of numbers that specify the workload to be assigned
to different context. Larger number indicate heavier workload.
data_shapes : ArrayRef[NameShape|AI::MXNet::DataDesc]
Should be a array ref of [name, shape] array refs, for the shapes of data. Note the order is
important and should be the same as the order that the `DataIter` provide the data.
label_shapes : Maybe[ArrayRef[NameShape|AI::MXNet::DataDesc]]
Should be a array ref of [$name, $shape] array refs, for the shapes of label. Note the order is
important and should be the same as the order that the `DataIter` provide the label.
param_names : ArrayRef[Str]
A array ref of strings, indicating the names of parameters (e.g. weights, filters, etc.)
in the computation graph.
for_training : Bool
Indicate whether the executors should be bind for training. When not doing training,
the memory for gradients will not be allocated.
inputs_need_grad : Bool
Indicate whether the gradients for the input data should be computed. This is currently
not used. It will be useful for implementing composition of modules.
shared_group : AI::MXNet::DataParallelExecutorGroup
Default is undef. This is used in bucketing. When not undef, it should be a executor
group corresponding to a different bucket. In other words, it will correspond to a different
symbol with the same set of parameters (e.g. unrolled RNNs with different lengths).
In this case the memory regions of the parameters will be shared.
logger : Logger
Default is AI::MXNet::Logging->get_logger.
fixed_param_names: Maybe[ArrayRef[Str]]
Indicate parameters to be fixed during training. Parameters in this array ref will not allocate
space for gradient, nor do gradient calculation.
grad_req : ArrayRef[GradReq]|HashRef[GradReq]|GradReq
Requirement for gradient accumulation. Can be 'write', 'add', or 'null'
lib/AI/MXNet/Executor/Group.pm view on Meta::CPAN
has 'data_shapes' => (is => 'rw', isa => 'ArrayRef[NameShape|AI::MXNet::DataDesc]', required => 1);
has 'label_shapes' => (is => 'rw', isa => 'Maybe[ArrayRef[NameShape|AI::MXNet::DataDesc]]');
has 'param_names' => (is => 'ro', isa => 'ArrayRef[Str]', required => 1);
has 'for_training' => (is => 'ro', isa => 'Bool', required => 1);
has 'inputs_need_grad' => (is => 'ro', isa => 'Bool', default => 0);
has 'shared_group' => (is => 'ro', isa => 'Maybe[AI::MXNet::DataParallelExecutorGroup]');
has 'logger' => (is => 'ro', default => sub { AI::MXNet::Logging->get_logger });
has 'fixed_param_names' => (is => 'rw', isa => 'Maybe[ArrayRef[Str]]');
has 'state_names' => (is => 'rw', isa => 'Maybe[ArrayRef[Str]]');
has 'grad_req' => (is => 'rw', isa => 'ArrayRef[GradReq]|HashRef[GradReq]|GradReq', default=>'write');
has '_p' => (is => 'rw', init_arg => undef);
sub BUILD
{
my $self = shift;
my $p = AI::MXNet::DataParallelExecutorGroup::_private->new;
$p->arg_names($self->symbol->list_arguments);
$p->aux_names($self->symbol->list_auxiliary_states);
$p->execs([]);
$self->_p($p);
$self->grad_req('null') if not $self->for_training;
$self->fixed_param_names([]) unless defined $self->fixed_param_names;
lib/AI/MXNet/Executor/Group.pm view on Meta::CPAN
=cut
method bind_exec(
ArrayRef[AI::MXNet::DataDesc] $data_shapes,
Maybe[ArrayRef[AI::MXNet::DataDesc]] $label_shapes=,
Maybe[AI::MXNet::DataParallelExecutorGroup] $shared_group=,
Bool $reshape=0
)
{
assert($reshape or not @{ $self->_p->execs });
$self->_p->batch_size(undef);
# calculate workload and bind executors
$self->_p->data_layouts($self->decide_slices($data_shapes));
# call it to make sure labels has the same batch size as data
if(defined $label_shapes)
{
$self->_p->label_layouts($self->decide_slices($label_shapes));
}
for my $i (0..@{ $self->contexts }-1)
lib/AI/MXNet/Executor/Group.pm view on Meta::CPAN
method reshape(
ArrayRef[AI::MXNet::DataDesc] $data_shapes,
Maybe[ArrayRef[AI::MXNet::DataDesc]] $label_shapes=
)
{
return if($data_shapes eq $self->data_shapes and $label_shapes eq $self->label_shapes);
if (not defined $self->_p->_default_execs)
{
$self->_p->_default_execs([@{ $self->_p->execs }]);
}
$self->bind_exec($data_shapes, $label_shapes, undef, 1);
}
=head2 set_params
Assign, i.e. copy parameters to all the executors.
Parameters
----------
$arg_params : HashRef[AI::MXNet::NDArray]
A dictionary of name to AI::MXNet::NDArray parameter mapping.
lib/AI/MXNet/Executor/Group.pm view on Meta::CPAN
Split the data_batch according to a workload and run forward on each devices.
Parameters
----------
data_batch : AI::MXNet::DataBatch
Or could be any object implementing similar interface.
is_train : bool
The hint for the backend, indicating whether we are during training phase.
Default is undef, then the value $self->for_training will be used.
=cut
method forward(AI::MXNet::DataBatch $data_batch, Maybe[Bool] $is_train=)
{
AI::MXNet::Executor::Group::_load_data($data_batch, $self->_p->data_arrays, $self->_p->data_layouts);
$is_train //= $self->for_training;
if(defined $self->_p->label_arrays)
{
confess("assert not is_train or data_batch.label")
lib/AI/MXNet/Executor/Group.pm view on Meta::CPAN
}, $self->_p->execs, $self->_p->slices);
}
method _bind_ith_exec(
Int $i,
ArrayRef[AI::MXNet::DataDesc] $data_shapes,
Maybe[ArrayRef[AI::MXNet::DataDesc]] $label_shapes,
Maybe[AI::MXNet::DataParallelExecutorGroup] $shared_group
)
{
my $shared_exec = $shared_group ? $shared_group->_p->execs->[$i] : undef;
my $context = $self->contexts->[$i];
my $shared_data_arrays = $self->_p->shared_data_arrays->[$i];
my %input_shapes = map { $_->name => $_->shape } @{ $data_shapes };
if(defined $label_shapes)
{
%input_shapes = (%input_shapes, map { $_->name => $_->shape } @{ $label_shapes });
}
my %input_types = map { $_->name => $_->dtype } @{ $data_shapes };
my $executor = $self->symbol->simple_bind(
ctx => $context,
lib/AI/MXNet/IO.pm view on Meta::CPAN
{
return AI::MXNet::DataBatch->new(
data => $self->getdata,
label => $self->getlabel,
pad => $self->getpad,
index => $self->getindex
);
}
else
{
return undef;
}
}
=head2 iter_next
Iterate to next batch.
Returns
-------
$has_next : Bool
lib/AI/MXNet/IO.pm view on Meta::CPAN
=cut
has 'data_iter' => (is => 'ro', isa => 'AI::MXnet::DataIter', required => 1);
has 'size' => (is => 'ro', isa => 'Int', required => 1);
has 'reset_internal' => (is => 'rw', isa => 'Int', default => 1);
has 'cur' => (is => 'rw', isa => 'Int', default => 0);
has 'current_batch' => (is => 'rw', isa => 'Maybe[AI::MXNet::DataBatch]');
has [qw/provide_data
default_bucket_key
provide_label
batch_size/] => (is => 'rw', init_arg => undef);
sub BUILD
{
my $self = shift;
$self->provide_data($self->data_iter->provide_data);
$self->provide_label($self->data_iter->provide_label);
$self->batch_size($self->data_iter->batch_size);
if($self->data_iter->can('default_bucket_key'))
{
$self->default_bucket_key($self->data_iter->default_bucket_key);
lib/AI/MXNet/IO.pm view on Meta::CPAN
}
method next()
{
if($self->iter_next)
{
return AI::MXNet::DataBatch->new(
data => $self->getdata,
label => $self->getlabel,
pad => $self->getpad,
index => undef
);
}
else
{
return undef;
}
}
# Load data from underlying arrays, internal use only
method _getdata($data_source)
{
confess("DataIter needs reset.") unless $self->cursor < $self->num_data;
if(($self->cursor + $self->batch_size) <= $self->num_data)
{
return [
lib/AI/MXNet/IO.pm view on Meta::CPAN
=cut
has 'handle' => (is => 'ro', isa => 'DataIterHandle', required => 1);
has '_debug_skip_load' => (is => 'rw', isa => 'Int', default => 0);
has '_debug_at_begin' => (is => 'rw', isa => 'Int', default => 0);
has 'data_name' => (is => 'ro', isa => 'Str', default => 'data');
has 'label_name' => (is => 'ro', isa => 'Str', default => 'softmax_label');
has [qw/first_batch
provide_data
provide_label
batch_size/] => (is => 'rw', init_arg => undef);
sub BUILD
{
my $self = shift;
$self->first_batch($self->next);
my $data = $self->first_batch->data->[0];
$self->provide_data([
AI::MXNet::DataDesc->new(
name => $self->data_name,
shape => $data->shape,
lib/AI/MXNet/IO.pm view on Meta::CPAN
method debug_skip_load()
{
$self->_debug_skip_load(1);
AI::MXNet::Logging->info('Set debug_skip_load to be true, will simply return first batch');
}
method reset()
{
$self->_debug_at_begin(1);
$self->first_batch(undef);
check_call(AI::MXNetCAPI::DataIterBeforeFirst($self->handle));
}
method next()
{
if($self->_debug_skip_load and not $self->_debug_at_begin)
{
return AI::MXNet::DataBatch->new(
data => [$self->getdata],
label => [$self->getlabel],
pad => $self->getpad,
index => $self->getindex
);
}
if(defined $self->first_batch)
{
my $batch = $self->first_batch;
$self->first_batch(undef);
return $batch
}
$self->_debug_at_begin(0);
my $next_res = check_call(AI::MXNetCAPI::DataIterNext($self->handle));
if($next_res)
{
return AI::MXNet::DataBatch->new(
data => [$self->getdata],
label => [$self->getlabel],
pad => $self->getpad,
index => $self->getindex
);
}
else
{
return undef;
}
}
method iter_next()
{
if(defined $self->first_batch)
{
return 1;
}
else
lib/AI/MXNet/Image.pm view on Meta::CPAN
has 'num_parts' => (is => 'ro', isa => 'Int', default => 0);
has 'aug_list' => (is => 'rw', isa => 'ArrayRef[CodeRef]');
has 'imglist' => (is => 'rw', isa => 'ArrayRef|HashRef');
has 'kwargs' => (is => 'ro', isa => 'HashRef');
has [qw/imgidx
imgrec
seq
cur
provide_data
provide_label
/] => (is => 'rw', init_arg => undef);
sub BUILD
{
my $self = shift;
assert($self->path_imgrec or $self->path_imglist or ref $self->imglist eq 'ARRAY');
if($self->path_imgrec)
{
print("loading recordio...\n");
if($self->path_imgidx)
{
lib/AI/MXNet/Image.pm view on Meta::CPAN
{
$self->imgrec->reset;
}
$self->cur(0);
}
method next_sample()
{
if(defined $self->seq)
{
return undef if($self->cur >= @{ $self->seq });
my $idx = $self->seq->[$self->cur];
$self->cur($self->cur + 1);
if(defined $self->imgrec)
{
my $s = $self->imgrec->read_idx($idx);
my ($header, $img) = AI::MXNet::RecordIO->unpack($s);
if(not defined $self->imglist)
{
return ($header->label, $img);
}
lib/AI/MXNet/Image.pm view on Meta::CPAN
return ($self->imglist->{$idx}[0], $img);
}
}
else
{
my ($label, $fname) = @{ $self->imglist->{$idx} };
if(not defined $self->imgrec)
{
open(F, $self->path_root . "/$fname") or confess("can't open $fname $!");
my $img;
{ local $/ = undef; $img = <F> };
close(F);
return ($label, $img);
}
}
}
else
{
my $s = $self->imgrec->read;
return undef if(not defined $s);
my ($header, $img) = AI::MXNet::RecordIO->unpack($s);
return ($header->label, $img)
}
}
method next()
{
my $batch_size = $self->batch_size;
my ($c, $h, $w) = @{ $self->data_shape };
my $batch_data = AI::MXNet::NDArray->empty([$batch_size, $c, $h, $w]);
lib/AI/MXNet/Image.pm view on Meta::CPAN
$data = [map { @{ $aug->($_) } } @$data];
}
for my $d (@$data)
{
assert(($i < $batch_size), 'Batch size must be multiples of augmenter output length');
$batch_data->at($i) .= AI::MXNet::NDArray->transpose($d, { axes=>[2, 0, 1] });
$batch_label->at($i) .= $label;
$i++;
}
}
return undef if not $i;
return AI::MXNet::DataBatch->new(data=>[$batch_data], label=>[$batch_label], pad => $batch_size-$i);
}
1;
lib/AI/MXNet/Initializer.pm view on Meta::CPAN
use overload "&{}" => sub { my $self = shift; sub { $self->call(@_) } },
'""' => sub {
my $self = shift;
my ($name) = ref($self) =~ /::(\w+)$/;
encode_json(
[lc $name,
$self->kwargs//{ map { $_ => "".$self->$_ } $self->meta->get_attribute_list }
]);
},
fallback => 1;
has 'kwargs' => (is => 'rw', init_arg => undef, isa => 'HashRef');
has '_verbose' => (is => 'rw', isa => 'Bool', lazy => 1, default => 0);
has '_print_func' => (is => 'rw', isa => 'CodeRef', lazy => 1,
default => sub {
return sub {
my $x = shift;
return ($x->norm/sqrt($x->size))->asscalar;
};
}
);
lib/AI/MXNet/Initializer.pm view on Meta::CPAN
patterns: array ref of str
array ref of regular expression patterns to match parameter names.
initializers: array ref of AI::MXNet::Initializer objects.
array ref of Initializers corresponding to the patterns.
=cut
package AI::MXNet::Mixed;
use Mouse;
extends 'AI::MXNet::Initializer';
has "map" => (is => "rw", init_arg => undef);
has "patterns" => (is => "ro", isa => 'ArrayRef[Str]');
has "initializers" => (is => "ro", isa => 'ArrayRef[AI::MXnet::Initializer]');
sub BUILD
{
my $self = shift;
confess("patterns count != initializers count")
unless (@{ $self->patterns } == @{ $self->initializers });
my %map;
@map{ @{ $self->patterns } } = @{ $self->initializers };
lib/AI/MXNet/KVStore.pm view on Meta::CPAN
fname : str
Path to input states file.
=cut
method load_optimizer_states(Str $fname)
{
confess("Cannot save states for distributed training")
unless defined $self->_updater;
open(F, "<:raw", "$fname") or confess("can't open $fname for reading: $!");
my $data;
{ local($/) = undef; $data = <F>; }
close(F);
$self->_updater->set_states($data);
}
=head2 _set_updater
Set a push updater into the store.
This function only changes the local store. Use set_optimizer for
multi-machines.
lib/AI/MXNet/Metric.pm view on Meta::CPAN
AI::MXNet::Perplexity
=cut
=head1 DESCRIPTION
Calculate perplexity.
Parameters
----------
ignore_label : int or undef
index of invalid label to ignore when
counting. usually should be -1. Include
all entries if undef.
axis : int (default -1)
The axis from prediction that was used to
compute softmax. By default uses the last
axis.
=cut
method update(ArrayRef[AI::MXNet::NDArray] $labels, ArrayRef[AI::MXNet::NDArray] $preds)
{
AI::MXNet::Metric::check_label_shapes($labels, $preds);
my ($loss, $num) = (0, 0);
lib/AI/MXNet/Module.pm view on Meta::CPAN
package AI::MXNet::Module::Private;
use Mouse;
has [qw/_param_names _fixed_param_names
_aux_names _data_names _label_names _state_names
_output_names _arg_params _aux_params
_params_dirty _optimizer _kvstore
_update_on_kvstore _updater _work_load_list
_preload_opt_states _exec_group
_data_shapes _label_shapes _context _grad_req/
] => (is => 'rw', init_arg => undef);
package AI::MXNet::Module;
use AI::MXNet::Base;
use AI::MXNet::Function::Parameters;
use List::Util qw(max);
use Data::Dumper ();
use Mouse;
func _create_kvstore(
Maybe[Str|AI::MXNet::KVStore] $kvstore,
lib/AI/MXNet/Module.pm view on Meta::CPAN
extends 'AI::MXNet::Module::Base';
has '_symbol' => (is => 'ro', init_arg => 'symbol', isa => 'AI::MXNet::Symbol', required => 1);
has '_data_names' => (is => 'ro', init_arg => 'data_names', isa => 'ArrayRef[Str]');
has '_label_names' => (is => 'ro', init_arg => 'label_names', isa => 'Maybe[ArrayRef[Str]]');
has 'work_load_list' => (is => 'rw', isa => 'Maybe[ArrayRef[Int]]');
has 'fixed_param_names' => (is => 'rw', isa => 'Maybe[ArrayRef[Str]]');
has 'state_names' => (is => 'rw', isa => 'Maybe[ArrayRef[Str]]');
has 'logger' => (is => 'ro', default => sub { AI::MXNet::Logging->get_logger });
has '_p' => (is => 'rw', init_arg => undef);
has 'context' => (
is => 'ro',
isa => 'AI::MXNet::Context|ArrayRef[AI::MXNet::Context]',
default => sub { AI::MXNet::Context->cpu }
);
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
if(@_%2)
lib/AI/MXNet/Module.pm view on Meta::CPAN
data_names : array ref of str
Default is ['data'] for a typical model used in image classification.
label_names : array ref of str
Default is ['softmax_label'] for a typical model used in image
classification.
logger : Logger
Default is AI::MXNet::Logging.
context : Context or list of Context
Default is cpu(0).
work_load_list : array ref of number
Default is undef, indicating an uniform workload.
fixed_param_names: array ref of str
Default is undef, indicating no network parameters are fixed.
=cut
method load(
Str $prefix,
Int $epoch,
Bool $load_optimizer_states=0,
%kwargs
)
{
my ($sym, $args, $auxs) = __PACKAGE__->load_checkpoint($prefix, $epoch);
lib/AI/MXNet/Module.pm view on Meta::CPAN
}
my $param_name = sprintf('%s-%04d.params', $prefix, $epoch);
$self->save_params($param_name, $arg_params, $aux_params);
AI::MXNet::Logging->info('Saved checkpoint to "%s"', $param_name);
}
# Internal function to reset binded state.
method _reset_bind()
{
$self->binded(0);
$self->_p->_exec_group(undef);
$self->_p->_data_shapes(undef);
$self->_p->_label_shapes(undef);
}
method data_names()
{
return $self->_p->_data_names;
}
method label_names()
{
return $self->_p->_label_names;
lib/AI/MXNet/Module.pm view on Meta::CPAN
:$for_training : bool
Default is 1. Whether the executors should be bind for training.
:$inputs_need_grad : bool
Default is 0. Whether the gradients to the input data need to be computed.
Typically this is not needed. But this might be needed when implementing composition
of modules.
:$force_rebind : bool
Default is 0. This function does nothing if the executors are already
binded. But with this 1, the executors will be forced to rebind.
:$shared_module : Module
Default is undef. This is used in bucketing. When not undef, the shared module
essentially corresponds to a different bucket -- a module with different symbol
but with the same sets of parameters (e.g. unrolled RNNs with different lengths).
=cut
method bind(
ArrayRef[AI::MXNet::DataDesc|NameShape] :$data_shapes,
Maybe[ArrayRef[AI::MXNet::DataDesc|NameShape]] :$label_shapes=,
Bool :$for_training=1,
Bool :$inputs_need_grad=0,
Bool :$force_rebind=0,
lib/AI/MXNet/Module.pm view on Meta::CPAN
."is not normalized to 1.0/batch_size/num_workers (%s vs. %s). "
."Is this intended?",
$optimizer->rescale_grad, $rescale_grad
);
}
}
$self->_p->_optimizer($optimizer);
$self->_p->_kvstore($kvstore);
$self->_p->_update_on_kvstore($update_on_kvstore);
$self->_p->_updater(undef);
if($kvstore)
{
# copy initialized local parameters to kvstore
_initialize_kvstore(
kvstore => $kvstore,
param_arrays => $self->_p->_exec_group->_p->param_arrays,
arg_params => $self->_p->_arg_params,
param_names => $self->_p->_param_names,
update_on_kvstore => $update_on_kvstore
lib/AI/MXNet/Module.pm view on Meta::CPAN
}
else
{
$self->_p->_updater(AI::MXNet::Optimizer->get_updater($optimizer));
}
$self->optimizer_initialized(1);
if($self->_p->_preload_opt_states)
{
$self->load_optimizer_states($self->_p->_preload_opt_states);
$self->_p->_preload_opt_states(undef);
}
}
=head2 borrow_optimizer
Borrow optimizer from a shared module. Used in bucketing, where exactly the same
optimizer (esp. kvstore) is used.
Parameters
----------
lib/AI/MXNet/Module.pm view on Meta::CPAN
{
assert($self->optimizer_initialized);
if($self->_p->_update_on_kvstore)
{
$self->_p->_kvstore->load_optimizer_states($fname);
}
else
{
open(F, "<:raw", "$fname") or confess("can't open $fname for reading: $!");
my $data;
{ local($/) = undef; $data = <F>; }
close(F);
$self->_p->_updater->set_states($data);
}
}
method install_monitor(AI::MXNet::Monitor $mon)
{
assert($self->binded);
$self->_p->_exec_group->install_monitor($mon);
}
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
backward, update parameters, etc. We aim to make the APIs easy to use, especially in the
case when we need to use imperative API to work with multiple modules (e.g. stochastic
depth network).
A module has several states:
- Initial state. Memory is not allocated yet, not ready for computation yet.
- Binded. Shapes for inputs, outputs, and parameters are all known, memory allocated,
ready for computation.
- Parameter initialized. For modules with parameters, doing computation before initializing
the parameters might result in undefined outputs.
- Optimizer installed. An optimizer can be installed to a module. After this, the parameters
of the module can be updated according to the optimizer after gradients are computed
(forward-backward).
In order for a module to interact with others, a module should be able to report the
following information in its raw stage (before binded)
- data_names: array ref of string indicating the names of required data.
- output_names: array ref of string indicating the names of required outputs.
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
- fit: train the module parameters on a data set
- predict: run prediction on a data set and collect outputs
- score: run prediction on a data set and evaluate performance
=cut
has 'logger' => (is => 'rw', default => sub { AI::MXNet::Logging->get_logger });
has '_symbol' => (is => 'rw', init_arg => 'symbol', isa => 'AI::MXNet::Symbol');
has [
qw/binded for_training inputs_need_grad
params_initialized optimizer_initialized/
] => (is => 'rw', isa => 'Bool', init_arg => undef, default => 0);
################################################################################
# High Level API
################################################################################
=head2 forward_backward
A convenient function that calls both forward and backward.
=cut
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
=head2 score
Run prediction on eval_data and evaluate the performance according to
eval_metric.
Parameters
----------
$eval_data : AI::MXNet::DataIter
$eval_metric : AI::MXNet::EvalMetric
:$num_batch= : Maybe[Int]
Number of batches to run. Default is undef, indicating run until the AI::MXNet::DataIter
finishes.
:$batch_end_callback= : Maybe[Callback]
Could also be a array ref of functions.
:$reset=1 : Bool
Default 1, indicating whether we should reset $eval_data before starting
evaluating.
$epoch=0 : Int
Default is 0. For compatibility, this will be passed to callbacks (if any). During
training, this will correspond to the training epoch number.
=cut
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
}
=head2 iter_predict
Iterate over predictions.
Parameters
----------
$eval_data : AI::MXNet::DataIter
:$num_batch= : Maybe[Int]
Default is undef, indicating running all the batches in the data iterator.
:$reset=1 : bool
Default is 1, indicating whether we should reset the data iter before start
doing prediction.
=cut
method iter_predict(AI::MXNet::DataIter $eval_data, Maybe[Int] :$num_batch=, Bool :$reset=1)
{
assert($self->binded and $self->params_initialized);
if($reset)
{
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
}
=head2 predict
Run prediction and collect the outputs.
Parameters
----------
$eval_data : AI::MXNet::DataIter
:$num_batch= : Maybe[Int]
Default is undef, indicating running all the batches in the data iterator.
:$merge_batches=1 : Bool
Default is 1.
:$reset=1 : Bool
Default is 1, indicating whether we should reset the data iter before start
doing prediction.
:$always_output_list=0 : Bool
Default is 0, see the doc for return values.
Returns
-------
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
}
=head2 fit
Train the module parameters.
Parameters
----------
$train_data : AI::MXNet::DataIter
:$eval_data= : Maybe[AI::MXNet::DataIter]
If not undef, it will be used as a validation set to evaluate the performance
after each epoch.
:$eval_metric='acc' : str or AI::MXNet::EvalMetric subclass object.
Default is 'accuracy'. The performance measure used to display during training.
Other possible predefined metrics are:
'ce' (CrossEntropy), 'f1', 'mae', 'mse', 'rmse', 'top_k_accuracy'
:$epoch_end_callback= : Maybe[Callback]|ArrayRef[Callback] function or array ref of functions.
Each callback will be called with the current $epoch, $symbol, $arg_params
and $aux_params.
:$batch_end_callback= : Maybe[Callback]|ArrayRef[Callback] function or array ref of functions.
Each callback will be called with a AI::MXNet::BatchEndParam.
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
Default { learning_rate => 0.01 }.
The parameters for the optimizer constructor.
:$eval_end_callback= : Maybe[Callback]|ArrayRef[Callback] function or array ref of functions
These will be called at the end of each full evaluation, with the metrics over
the entire evaluation set.
:$eval_batch_end_callback : Maybe[Callback]|ArrayRef[Callback] function or array ref of functions
These will be called at the end of each minibatch during evaluation
:$initializer= : Initializer
Will be called to initialize the module parameters if not already initialized.
:$arg_params= : hash ref
Default undef, if not undef, must be an existing parameters from a trained
model or loaded from a checkpoint (previously saved model). In this case,
the value here will be used to initialize the module parameters, unless they
are already initialized by the user via a call to init_params or fit.
$arg_params have higher priority than the $initializer.
:$aux_params= : hash ref
Default is undef. This is similar to the $arg_params, except for auxiliary states.
:$allow_missing=0 : Bool
Default is 0. Indicates whether we allow missing parameters when $arg_params
and $aux_params are not undefined. If this is 1, then the missing parameters
will be initialized via the $initializer.
:$force_rebind=0 : Bool
Default is 0. Whether to force rebinding the executors if already binded.
:$force_init=0 : Bool
Default is 0. Indicates whether we should force initialization even if the
parameters are already initialized.
:$begin_epoch=0 : Int
Default is 0. Indicates the starting epoch. Usually, if we are resuming from a
checkpoint saved at a previous training phase at epoch N, then we should specify
this value as N+1.
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
=head2 init_params
Initialize the parameters and auxiliary states.
Parameters
----------
:$initializer : Maybe[AI::MXNet::Initializer]
Called to initialize parameters if needed.
:$arg_params= : Maybe[HashRef[AI::MXNet::NDArray]]
If not undef, should be a hash ref of existing arg_params.
:$aux_params : Maybe[HashRef[AI::MXNet::NDArray]]
If not undef, should be a hash ref of existing aux_params.
:$allow_missing=0 : Bool
If true, params could contain missing values, and the initializer will be
called to fill those missing params.
:$force_init=0 : Bool
If true, will force re-initialize even if already initialized.
:$allow_extra=0 : Boolean, optional
Whether allow extra parameters that are not needed by symbol.
If this is True, no error will be thrown when arg_params or aux_params
contain extra parameters that is not needed by the executor.
=cut
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
method set_params(
Maybe[HashRef[AI::MXNet::NDArray]] $arg_params=,
Maybe[HashRef[AI::MXNet::NDArray]] $aux_params=,
Bool :$allow_missing=0,
Bool :$force_init=0,
Bool :$allow_extra=0
)
{
$self->init_params(
initializer => undef,
arg_params => $arg_params,
aux_params => $aux_params,
allow_missing => $allow_missing,
force_init => $force_init,
allow_extra => $allow_extra
);
}
=head2 save_params
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
different batch sizes or different image sizes.
If reshaping of data batch relates to modification of symbol or module, such as
changing image layout ordering or switching from training to predicting, module
rebinding is required.
Parameters
----------
$data_batch : DataBatch
Could be anything with similar API implemented.
:$is_train= : Bool
Default is undef, which means is_train takes the value of $self->for_training.
=cut
method forward(AI::MXNet::DataBatch $data_batch, Bool :$is_train=) { confess("NotImplemented") }
=head2 backward
Backward computation.
Parameters
----------
lib/AI/MXNet/Module/Base.pm view on Meta::CPAN
:$for_training=1 : Bool
Default is 1. Whether the executors should be bind for training.
:$inputs_need_grad=0 : Bool
Default is 0. Whether the gradients to the input data need to be computed.
Typically this is not needed. But this might be needed when implementing composition
of modules.
:$force_rebind=0 : Bool
Default is 0. This function does nothing if the executors are already
binded. But with this as 1, the executors will be forced to rebind.
:$shared_module= : A subclass of AI::MXNet::Module::Base
Default is undef. This is used in bucketing. When not undef, the shared module
essentially corresponds to a different bucket -- a module with different symbol
but with the same sets of parameters (e.g. unrolled RNNs with different lengths).
:$grad_req='write' : Str|ArrayRef[Str]|HashRef[Str]
Requirement for gradient accumulation. Can be 'write', 'add', or 'null'
(defaults to 'write').
Can be specified globally (str) or for each argument (array ref, hash ref).
=cut
method bind(
ArrayRef[AI::MXNet::DataDesc] $data_shapes,
lib/AI/MXNet/Module/Bucketing.pm view on Meta::CPAN
----------
$sym_gen : subref or any perl object that overloads &{} op
A sub when called with a bucket key, returns a list with triple
of ($symbol, $data_names, $label_names).
$default_bucket_key : str or anything else
The key for the default bucket.
$logger : Logger
$context : AI::MXNet::Context or array ref of AI::MXNet::Context objects
Default is cpu(0)
$work_load_list : array ref of Num
Default is undef, indicating uniform workload.
$fixed_param_names: arrayref of str
Default is undef, indicating no network parameters are fixed.
$state_names : arrayref of str
states are similar to data and label, but not provided by data iterator.
Instead they are initialized to 0 and can be set by set_states()
=cut
extends 'AI::MXNet::Module::Base';
has '_sym_gen' => (is => 'ro', init_arg => 'sym_gen', required => 1);
has '_default_bucket_key' => (is => 'rw', init_arg => 'default_bucket_key', required => 1);
has '_context' => (
is => 'ro', isa => 'AI::MXNet::Context|ArrayRef[AI::MXNet::Context]',
lazy => 1, default => sub { AI::MXNet::Context->cpu },
init_arg => 'context'
);
has '_work_load_list' => (is => 'rw', init_arg => 'work_load_list', isa => 'ArrayRef[Num]');
has '_curr_module' => (is => 'rw', init_arg => undef);
has '_curr_bucket_key' => (is => 'rw', init_arg => undef);
has '_buckets' => (is => 'rw', init_arg => undef, default => sub { +{} });
has '_fixed_param_names' => (is => 'rw', isa => 'ArrayRef[Str]', init_arg => 'fixed_param_names');
has '_state_names' => (is => 'rw', isa => 'ArrayRef[Str]', init_arg => 'state_names');
has '_params_dirty' => (is => 'rw', init_arg => undef);
sub BUILD
{
my ($self, $original_params) = @_;
$self->_fixed_param_names([]) unless defined $original_params->{fixed_param_names};
$self->_state_names([]) unless defined $original_params->{state_names};
$self->_params_dirty(0);
my ($symbol, $data_names, $label_names) = &{$self->_sym_gen}($self->_default_bucket_key);
$self->_check_input_names($symbol, $data_names//[], "data", 1);
$self->_check_input_names($symbol, $label_names//[], "label", 0);
$self->_check_input_names($symbol, $self->_state_names, "state", 1);
$self->_check_input_names($symbol, $self->_fixed_param_names, "fixed_param", 1);
}
method _reset_bind()
{
$self->binded(0);
$self->_buckets({});
$self->_curr_module(undef);
$self->_curr_bucket_key(undef);
}
method data_names()
{
if($self->binded)
{
return $self->_curr_module->data_names;
}
else
{
lib/AI/MXNet/Module/Bucketing.pm view on Meta::CPAN
This should correspond to the symbol for the default bucket.
:$label_shapes= : Maybe[ArrayRef[AI::MXNet::DataDesc|NameShape]]
This should correspond to the symbol for the default bucket.
:$for_training : Bool
Default is 1.
:$inputs_need_grad : Bool
Default is 0.
:$force_rebind : Bool
Default is 0.
:$shared_module : AI::MXNet::Module::Bucketing
Default is undef. This value is currently not used.
:$grad_req : str, array ref of str, hash ref of str to str
Requirement for gradient accumulation. Can be 'write', 'add', or 'null'
(defaults to 'write').
Can be specified globally (str) or for each argument (array ref, hash ref).
:$bucket_key : str
bucket key for binding. by default is to use the ->default_bucket_key
=cut
method bind(
ArrayRef[AI::MXNet::DataDesc|NameShape] :$data_shapes,
lib/AI/MXNet/Module/Bucketing.pm view on Meta::CPAN
work_load_list => $self->_work_load_list,
state_names => $self->_state_names,
fixed_param_names => $self->_fixed_param_names
);
$module->bind(
data_shapes => $data_shapes,
label_shapes => $label_shapes,
for_training => $for_training,
inputs_need_grad => $inputs_need_grad,
force_rebind => 0,
shared_module => undef,
grad_req => $grad_req
);
$self->_curr_module($module);
$self->_curr_bucket_key($self->_default_bucket_key);
$self->_buckets->{ $self->_default_bucket_key } = $module;
# copy back saved params, if already initialized
if($self->params_initialized)
{
$self->set_params($arg_params, $aux_params);
lib/AI/MXNet/Monitor.pm view on Meta::CPAN
return sub {
# returns |x|/size(x), async execution.
my ($x) = @_;
return $x->norm/sqrt($x->size);
}
},
lazy => 1
);
has 'pattern' => (is => 'ro', isa => 'Str', default => '.*');
has '_sort' => (is => 'ro', isa => 'Bool', init_arg => 'sort', default => 0);
has [qw/queue exes/] => (is => 'rw', init_arg => undef, default => sub { [] });
has [qw/step activated/] => (is => 'rw', init_arg => undef, default => 0);
has 're_pattern' => (
is => 'ro',
init_arg => undef,
default => sub {
my $pattern = shift->pattern;
my $re = eval { qr/$pattern/ };
confess("pattern $pattern failed to compile as a regexp $@")
if $@;
return $re;
},
lazy => 1
);
has 'stat_helper' => (
is => 'ro',
init_arg => undef,
default => sub {
my $self = shift;
return sub {
my ($name, $handle) = @_;
return if(not $self->activated or not $name =~ $self->re_pattern);
my $array = AI::MXNet::NDArray->new(handle => $handle, writable => 0);
push @{ $self->queue }, [$self->step, $name, $self->stat_func->($array)];
}
},
lazy => 1
lib/AI/MXNet/NDArray.pm view on Meta::CPAN
my $handle = check_call(AI::MXNetCAPI::NDArrayDetach($self->handle));
return __PACKAGE__->new(handle => $handle);
}
method backward(Maybe[AI::MXNet::NDArray] $out_grad=, Bool $retain_graph=0)
{
check_call(
AI::MXNetCAPI::AutogradBackward(
1,
[$self->handle],
[defined $out_grad ? $out_grad->handle : undef],
$retain_graph
)
)
}
method CachedOp(@args) { AI::MXNet::CachedOp->new(@args) }
my $lvalue_methods = join "\n", map {"use attributes 'AI::MXNet::NDArray', \\&AI::MXNet::NDArray::$_, 'lvalue';"}
qw/at slice aspdl asmpdl reshape copy sever T astype as_in_context copyto empty zero ones full
array/;
lib/AI/MXNet/Optimizer.pm view on Meta::CPAN
rescaling factor of gradient. Normally should be 1/batch_size.
clip_gradient : float, optional
clip gradient in range [-clip_gradient, clip_gradient]
param_idx2name : hash ref of string/int to float, optional
special treat weight decay in parameter ends with bias, gamma, and beta
=cut
has 'momentum' => (is => 'ro', isa => 'Num', default => 0);
has 'lamda' => (is => 'ro', isa => 'Num', default => 0.04);
has 'weight_previous' => (is => 'rw', init_arg => undef);
sub BUILD
{
my $self = shift;
$self->weight_previous({});
}
method create_state(Index $index, AI::MXNet::NDArray $weight)
{
return [
$self->momentum ? AI::MXNet::NDArray->zeros(
$weight->shape, ctx => $weight->context, dtype => $weight->dtype
) : undef,
$weight->copy
];
}
method update(
Index $index,
AI::MXNet::NDArray $weight,
AI::MXNet::NDArray $grad,
Maybe[AI::MXNet::NDArray] $state
)
lib/AI/MXNet/Optimizer.pm view on Meta::CPAN
special treat weight decay in parameter ends with bias, gamma, and beta
=cut
package AI::MXNet::SLGD;
use Mouse;
extends 'AI::MXNet::Optimizer';
method create_state(Index $index, AI::MXNet::NDArray $weight)
{
return undef;
}
method update(
Index $index,
AI::MXNet::NDArray $weight,
AI::MXNet::NDArray $grad,
AI::MXNet::NDArray|Undef $state
)
{
my $lr = $self->_get_lr($index);
lib/AI/MXNet/Optimizer.pm view on Meta::CPAN
use Mouse;
extends 'AI::MXNet::Optimizer';
has '+learning_rate' => (default => 0.001);
has 'gamma1' => (is => "ro", isa => "Num", default => 0.9);
has 'gamma2' => (is => "ro", isa => "Num", default => 0.9);
has 'epsilon' => (is => "ro", isa => "Num", default => 1e-8);
has 'centered' => (is => "ro", isa => "Bool", default => 0);
has 'clip_weights' => (is => "ro", isa => "Num");
has 'kwargs' => (is => "rw", init_arg => undef);
sub BUILD
{
my $self = shift;
$self->kwargs({
rescale_grad => $self->rescale_grad,
gamma1 => $self->gamma1,
epsilon => $self->epsilon
});
if($self->centered)
lib/AI/MXNet/Optimizer.pm view on Meta::CPAN
Exponential decay rate for the momentum schedule
=cut
use Mouse;
extends 'AI::MXNet::Optimizer';
has '+learning_rate' => (default => 0.001);
has 'beta1' => (is => "ro", isa => "Num", default => 0.9);
has 'beta2' => (is => "ro", isa => "Num", default => 0.999);
has 'epsilon' => (is => "ro", isa => "Num", default => 1e-8);
has 'schedule_decay' => (is => "ro", isa => "Num", default => 0.004);
has 'm_schedule' => (is => "rw", default => 1, init_arg => undef);
method create_state(Index $index, AI::MXNet::NDArray $weight)
{
return [
AI::MXNet::NDArray->zeros(
$weight->shape,
ctx => $weight->context,
dtype => $weight->dtype
), # mean
AI::MXNet::NDArray->zeros(
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
A container for holding variables.
Used by RNN cells for parameter sharing between cells.
Parameters
----------
prefix : str
All variables name created by this container will
be prepended with the prefix
=cut
has '_prefix' => (is => 'ro', init_arg => 'prefix', isa => 'Str', default => '');
has '_params' => (is => 'rw', init_arg => undef);
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
return $class->$orig(prefix => $_[0]) if @_ == 1;
return $class->$orig(@_);
};
sub BUILD
{
my $self = shift;
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
=cut
=head1 DESCRIPTION
Abstract base class for RNN cells
Parameters
----------
prefix : str
prefix for name of layers
(and name of weight if params is undef)
params : AI::MXNet::RNN::Params or undef
container for weight sharing between cells.
created if undef.
=cut
use AI::MXNet::Base;
use Mouse;
use overload "&{}" => sub { my $self = shift; sub { $self->call(@_) } };
has '_prefix' => (is => 'rw', init_arg => 'prefix', isa => 'Str', default => '');
has '_params' => (is => 'rw', init_arg => 'params', isa => 'Maybe[AI::MXNet::RNN::Params]');
has [qw/_own_params
_modified
_init_counter
_counter
/] => (is => 'rw', init_arg => undef);
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
return $class->$orig(prefix => $_[0]) if @_ == 1;
return $class->$orig(@_);
};
sub BUILD
{
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
}
=head2 unroll
Unroll an RNN cell across time steps.
Parameters
----------
:$length : Int
number of steps to unroll
:$inputs : AI::MXNet::Symbol, array ref of Symbols, or undef
if inputs is a single Symbol (usually the output
of Embedding symbol), it should have shape
of [$batch_size, $length, ...] if layout == 'NTC' (batch, time series)
or ($length, $batch_size, ...) if layout == 'TNC' (time series, batch).
If inputs is a array ref of symbols (usually output of
previous unroll), they should all have shape
($batch_size, ...).
If inputs is undef, a placeholder variables are
automatically created.
:$begin_state : array ref of Symbol
input states. Created by begin_state()
or output state of another cell. Created
from begin_state() if undef.
:$input_prefix : str
prefix for automatically created input
placehodlers.
:$layout : str
layout of input symbol. Only used if the input
is a single Symbol.
:$merge_outputs : Bool
If 0, returns outputs as an array ref of Symbols.
If 1, concatenates the output across the time steps
and returns a single symbol with the shape
[$batch_size, $length, ...) if the layout equal to 'NTC',
or [$length, $batch_size, ...) if the layout equal tp 'TNC'.
If undef, output whatever is faster
Returns
-------
$outputs : array ref of Symbol or Symbol
output symbols.
$states : Symbol or nested list of Symbol
has the same structure as begin_state()
=cut
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
Simple recurrent neural network cell
Parameters
----------
num_hidden : int
number of units in output symbol
activation : str or Symbol, default 'tanh'
type of activation function
prefix : str, default 'rnn_'
prefix for name of layers
(and name of weight if params is undef)
params : AI::MXNet::RNNParams or undef
container for weight sharing between cells.
created if undef.
=cut
has '_num_hidden' => (is => 'ro', init_arg => 'num_hidden', isa => 'Int', required => 1);
has 'forget_bias' => (is => 'ro', isa => 'Num');
has '_activation' => (
is => 'ro',
init_arg => 'activation',
isa => 'Activation',
default => 'tanh'
);
has '+_prefix' => (default => 'rnn_');
has [qw/_iW _iB
_hW _hB/] => (is => 'rw', init_arg => undef);
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
return $class->$orig(num_hidden => $_[0]) if @_ == 1;
return $class->$orig(@_);
};
sub BUILD
{
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
=head1 DESCRIPTION
Long-Short Term Memory (LSTM) network cell.
Parameters
----------
num_hidden : int
number of units in output symbol
prefix : str, default 'lstm_'
prefix for name of layers
(and name of weight if params is undef)
params : AI::MXNet::RNN::Params or None
container for weight sharing between cells.
created if undef.
forget_bias : bias added to forget gate, default 1.0.
Jozefowicz et al. 2015 recommends setting this to 1.0
=cut
has '+_prefix' => (default => 'lstm_');
has '+_activation' => (init_arg => undef);
has '+forget_bias' => (is => 'ro', isa => 'Num', default => 1);
method state_info()
{
return [{ shape => [0, $self->_num_hidden], __layout__ => 'NC' } , { shape => [0, $self->_num_hidden], __layout__ => 'NC' }];
}
method _gate_names()
{
[qw/_i _f _c _o/];
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
Gated Rectified Unit (GRU) network cell.
Note: this is an implementation of the cuDNN version of GRUs
(slight modification compared to Cho et al. 2014).
Parameters
----------
num_hidden : int
number of units in output symbol
prefix : str, default 'gru_'
prefix for name of layers
(and name of weight if params is undef)
params : AI::MXNet::RNN::Params or undef
container for weight sharing between cells.
created if undef.
=cut
has '+_prefix' => (default => 'gru_');
method _gate_names()
{
[qw/_r _z _o/];
}
method call(AI::MXNet::Symbol $inputs, SymbolOrArrayOfSymbols $states)
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
has '_bidirectional' => (is => 'ro', isa => 'Bool', init_arg => 'bidirectional', default => 0);
has 'forget_bias' => (is => 'ro', isa => 'Num', default => 1);
has 'initializer' => (is => 'rw', isa => 'Maybe[Initializer]');
has '_mode' => (
is => 'ro',
isa => enum([qw/rnn_relu rnn_tanh lstm gru/]),
init_arg => 'mode',
default => 'lstm'
);
has [qw/_parameter
_directions/] => (is => 'rw', init_arg => undef);
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
return $class->$orig(num_hidden => $_[0]) if @_ == 1;
return $class->$orig(@_);
};
sub BUILD
{
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
AI:MXNet::RNN::SequentialCell
=cut
=head1 DESCRIPTION
Sequentially stacking multiple RNN cells
Parameters
----------
params : AI::MXNet::RNN::Params or undef
container for weight sharing between cells.
created if undef.
=cut
has [qw/_override_cell_params _cells/] => (is => 'rw', init_arg => undef);
sub BUILD
{
my ($self, $original_arguments) = @_;
$self->_override_cell_params(defined $original_arguments->{params});
$self->_cells([]);
}
=head2 add
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
my ($i, $cell) = @_;
my $n = @{ $cell->state_info };
$states = [@{$begin_state}[$p..$p+$n-1]];
$p += $n;
($inputs, $states) = $cell->unroll(
$length,
inputs => $inputs,
input_prefix => $input_prefix,
begin_state => $states,
layout => $layout,
merge_outputs => ($i < $num_cells-1) ? undef : $merge_outputs
);
push @next_states, $states;
}, $self->_cells);
return ($inputs, [map { @{ $_ } } @next_states]);
}
package AI::MXNet::RNN::BidirectionalCell;
use Mouse;
use AI::MXNet::Base;
extends 'AI::MXNet::RNN::Cell::Base';
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
cell for forward unrolling
r_cell : AI::MXNet::RNN::Cell::Base
cell for backward unrolling
output_prefix : str, default 'bi_'
prefix for name of output
=cut
has 'l_cell' => (is => 'ro', isa => 'AI::MXNet::RNN::Cell::Base', required => 1);
has 'r_cell' => (is => 'ro', isa => 'AI::MXNet::RNN::Cell::Base', required => 1);
has '_output_prefix' => (is => 'ro', init_arg => 'output_prefix', isa => 'Str', default => 'bi_');
has [qw/_override_cell_params _cells/] => (is => 'rw', init_arg => undef);
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
if(@_ >= 2 and blessed $_[0] and blessed $_[1])
{
my $l_cell = shift(@_);
my $r_cell = shift(@_);
return $class->$orig(
l_cell => $l_cell,
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
=cut
=head1 DESCRIPTION
Abstract base class for Convolutional RNN cells
=cut
has '_h2h_kernel' => (is => 'ro', isa => 'Shape', init_arg => 'h2h_kernel');
has '_h2h_dilate' => (is => 'ro', isa => 'Shape', init_arg => 'h2h_dilate');
has '_h2h_pad' => (is => 'rw', isa => 'Shape', init_arg => undef);
has '_i2h_kernel' => (is => 'ro', isa => 'Shape', init_arg => 'i2h_kernel');
has '_i2h_stride' => (is => 'ro', isa => 'Shape', init_arg => 'i2h_stride');
has '_i2h_dilate' => (is => 'ro', isa => 'Shape', init_arg => 'i2h_dilate');
has '_i2h_pad' => (is => 'ro', isa => 'Shape', init_arg => 'i2h_pad');
has '_num_hidden' => (is => 'ro', isa => 'DimSize', init_arg => 'num_hidden');
has '_input_shape' => (is => 'ro', isa => 'Shape', init_arg => 'input_shape');
has '_conv_layout' => (is => 'ro', isa => 'Str', init_arg => 'conv_layout', default => 'NCHW');
has '_activation' => (is => 'ro', init_arg => 'activation');
has '_state_shape' => (is => 'rw', init_arg => undef);
has [qw/i2h_weight_initializer h2h_weight_initializer
i2h_bias_initializer h2h_bias_initializer/] => (is => 'rw', isa => 'Maybe[Initializer]');
sub BUILD
{
my $self = shift;
assert (
($self->_h2h_kernel->[0] % 2 == 1 and $self->_h2h_kernel->[1] % 2 == 1),
"Only support odd numbers, got h2h_kernel= (@{[ $self->_h2h_kernel ]})"
);
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
has '+_i2h_kernel' => (default => sub { [3, 3] });
has '+_i2h_stride' => (default => sub { [1, 1] });
has '+_i2h_dilate' => (default => sub { [1, 1] });
has '+_i2h_pad' => (default => sub { [1, 1] });
has '+_prefix' => (default => 'ConvRNN_');
has '+_activation' => (default => sub { sub { AI::MXNet::Symbol->LeakyReLU(@_, act_type => 'leaky', slope => 0.2) } });
has '+i2h_bias_initializer' => (default => 'zeros');
has '+h2h_bias_initializer' => (default => 'zeros');
has 'forget_bias' => (is => 'ro', isa => 'Num');
has [qw/_iW _iB
_hW _hB/] => (is => 'rw', init_arg => undef);
sub BUILD
{
my $self = shift;
$self->_iW($self->_params->get('i2h_weight', init => $self->i2h_weight_initializer));
$self->_hW($self->_params->get('h2h_weight', init => $self->h2h_weight_initializer));
$self->_iB(
$self->params->get(
'i2h_bias',
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
$states = [map { AI::MXNet::Symbol->Dropout(data => $_, p => $self->dropout_states) } @{ $states }];
}
return ($output, $states);
}
package AI::MXNet::RNN::ZoneoutCell;
use Mouse;
use AI::MXNet::Base;
extends 'AI::MXNet::RNN::ModifierCell';
has [qw/zoneout_outputs zoneout_states/] => (is => 'ro', isa => 'Num', default => 0);
has 'prev_output' => (is => 'rw', init_arg => undef);
=head1 NAME
AI::MXNet::RNN::ZoneoutCell
=cut
=head1 DESCRIPTION
Apply Zoneout on base cell.
=cut
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
assert(
(not $self->base_cell->isa('AI::MXNet::RNN::SequentialCell') or not $self->_bidirectional),
"Bidirectional SequentialCell doesn't support zoneout. ".
"Please add ZoneoutCell to the cells underneath instead."
);
}
method reset()
{
$self->SUPER::reset;
$self->prev_output(undef);
}
method call(AI::MXNet::Symbol $inputs, SymbolOrArrayOfSymbols $states)
{
my ($cell, $p_outputs, $p_states) = ($self->base_cell, $self->zoneout_outputs, $self->zoneout_states);
my ($next_output, $next_states) = &{$cell}($inputs, $states);
my $mask = sub {
my ($p, $like) = @_;
AI::MXNet::Symbol->Dropout(
AI::MXNet::Symbol->ones_like(
lib/AI/MXNet/RNN/Cell.pm view on Meta::CPAN
name=>$output_sym->name."_plus_residual");
}, [@{ $outputs }], [@{ $inputs }]);
$outputs = \@temp;
}
return ($outputs, $states);
}
func _normalize_sequence($length, $inputs, $layout, $merge, $in_layout=)
{
assert((defined $inputs),
"unroll(inputs=>undef) has been deprecated. ".
"Please create input variables outside unroll."
);
my $axis = index($layout, 'T');
my $in_axis = defined $in_layout ? index($in_layout, 'T') : $axis;
if(blessed($inputs))
{
if(not $merge)
{
assert(
lib/AI/MXNet/RNN/IO.pm view on Meta::CPAN
Encode sentences and (optionally) build a mapping
from string tokens to integer indices. Unknown keys
will be added to vocabulary.
Parameters
----------
$sentences : array ref of array refs of str
A array ref of sentences to encode. Each sentence
should be a array ref of string tokens.
:$vocab : undef or hash ref of str -> int
Optional input Vocabulary
:$invalid_label : int, default -1
Index for invalid token, like <end-of-sentence>
:$invalid_key : str, default '\n'
Key for invalid token. Uses '\n' for end
of sentence by default.
:$start_label=0 : int
lowest index.
Returns
lib/AI/MXNet/RNN/IO.pm view on Meta::CPAN
----------
sentences : array ref of array refs of int
encoded sentences
batch_size : int
batch_size of data
invalid_label : int, default -1
key for invalid label, e.g. <end-of-sentence>
dtype : str, default 'float32'
data type
buckets : array ref of int
size of data buckets. Automatically generated if undef.
data_name : str, default 'data'
name of data
label_name : str, default 'softmax_label'
name of label
layout : str
format of data and label. 'NT' means (batch_size, length)
and 'TN' means (length, batch_size).
=cut
use Mouse;
lib/AI/MXNet/RNN/IO.pm view on Meta::CPAN
has 'invalid_label' => (is => 'ro', isa => 'Int', default => -1);
has 'data_name' => (is => 'ro', isa => 'Str', default => 'data');
has 'label_name' => (is => 'ro', isa => 'Str', default => 'softmax_label');
has 'dtype' => (is => 'ro', isa => 'Dtype', default => 'float32');
has 'layout' => (is => 'ro', isa => 'Str', default => 'NT');
has 'buckets' => (is => 'rw', isa => 'Maybe[ArrayRef[Int]]');
has [qw/data nddata ndlabel
major_axis default_bucket_key
provide_data provide_label
idx curr_idx
/] => (is => 'rw', init_arg => undef);
sub BUILD
{
my $self = shift;
if(not defined $self->buckets)
{
my @buckets;
my $p = pdl([map { scalar(@$_) } @{ $self->sentences }]);
enumerate(sub {
my ($i, $j) = @_;
lib/AI/MXNet/RNN/IO.pm view on Meta::CPAN
my $label = $buck->zeros;
$label->slice([0, -2], 'X') .= $buck->slice([1, -1], 'X');
$label->slice([-1, -1], 'X') .= $self->invalid_label;
push @{ $self->nddata }, AI::MXNet::NDArray->array($buck, dtype => $self->dtype);
push @{ $self->ndlabel }, AI::MXNet::NDArray->array($label, dtype => $self->dtype);
}
}
method next()
{
return undef if($self->curr_idx == @{ $self->idx });
my ($i, $j) = @{ $self->idx->[$self->curr_idx] };
$self->curr_idx($self->curr_idx + 1);
my ($data, $label);
if($self->major_axis == 1)
{
$data = $self->nddata->[$i]->slice([$j, $j+$self->batch_size-1])->T;
$label = $self->ndlabel->[$i]->slice([$j, $j+$self->batch_size-1])->T;
}
else
{
lib/AI/MXNet/RecordIO.pm view on Meta::CPAN
idx_path : str
Path to index file
uri : str
Path to record file. Only support file types that are seekable.
flag : str
'w' for write or 'r' for read
=cut
has 'idx_path' => (is => 'ro', isa => 'Str', required => 1);
has [qw/idx
keys fidx/] => (is => 'rw', init_arg => undef);
method open()
{
$self->SUPER::open();
$self->idx({});
$self->keys([]);
open(my $f, $self->flag eq 'r' ? '<' : '>', $self->idx_path);
$self->fidx($f);
if(not $self->writable)
{
lib/AI/MXNet/RecordIO.pm view on Meta::CPAN
push @{ $self->keys }, $key;
$self->idx->{$key} = $val;
}
}
}
method close()
{
return if not $self->is_open;
$self->SUPER::close();
$self->fidx(undef);
}
=head2 seek
Query current read head position.
=cut
method seek(Int $idx)
{
assert(not $self->writable);
lib/AI/MXNet/Rtc.pm view on Meta::CPAN
extern "C" __global__ mykernel(float *x, float *y) {
const int x_ndim = 1;
const int x_dims = { 10 };
const int y_ndim = 1;
const int y_dims = { 10 };
y[threadIdx.x] = x[threadIdx.x];
}
=cut
has 'handle' => (is => 'rw', isa => 'RtcHandle', init_arg => undef);
has [qw/name kernel/] => (is => 'ro', isa => 'Str', required => 1);
has [qw/inputs outputs/] => (is => 'ro', isa => 'HashRef[AI::MXNet::NDArray]', required => 1);
sub BUILD
{
my $self = shift;
my (@input_names, @output_names, @input_nds, @output_nds);
while(my ($name, $arr) = each %{ $self->inputs })
{
push @input_names, $name;
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
Returns
-------
value : str
The name of this symbol, returns None for grouped symbol.
=cut
method name()
{
my ($name, $success) = check_call(AI::MXNetCAPI::SymbolGetName($self->handle));
return $success ? $name : undef;
}
=head2 attr
Get an attribute string from the symbol, this function only works for non-grouped symbol.
Parameters
----------
key : str
The key to get attribute from.
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
value : str
The attribute value of the key, returns None if attribute do not exist.
=cut
method attr(Str $key)
{
my ($attr, $success) = check_call(
AI::MXNetCAPI::SymbolGetAttr($self->handle, $key)
);
return $success ? $attr : undef;
}
=head2 list_attr
Get all attributes from the symbol.
Returns
-------
ret : hash ref of str to str
a dicitonary mapping attribute keys to values
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
return __PACKAGE__->new(handle => $handle);
}
=head2 get_children
Get a new grouped symbol whose output contains
inputs to output nodes of the original symbol
Returns
-------
sgroup : Symbol or undef
The children of the head node. If the symbol has no
inputs undef will be returned.
=cut
method get_children()
{
my $handle = check_call(AI::MXNetCAPI::SymbolGetChildren($self->handle));
my $ret = __PACKAGE__->new(handle => $handle);
return undef unless @{ $ret->list_outputs };
return $ret;
}
=head2 list_arguments
List all the arguments in the symbol.
Returns
-------
args : array ref of strings
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
----------
args : Array
Provide type of arguments in a positional way.
Unknown type can be marked as None
kwargs : Hash ref, must ne ssupplied as as sole argument to the method.
Provide keyword arguments of known types.
Returns
-------
arg_types : array ref of Dtype or undef
List of types of arguments.
The order is in the same order as list_arguments()
out_types : array ref of Dtype or undef
List of types of outputs.
The order is in the same order as list_outputs()
aux_types : array ref of Dtype or undef
List of types of outputs.
The order is in the same order as list_auxiliary()
=cut
method infer_type(Str|Undef @args)
{
my ($positional_arguments, $kwargs, $kwargs_order) = _parse_arguments("Dtype", @args);
my $sdata = [];
my $keys = [];
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
if($complete)
{
return (
[ map { DTYPE_MX_TO_STR->{ $_ } } @{ $arg_type }],
[ map { DTYPE_MX_TO_STR->{ $_ } } @{ $out_type }],
[ map { DTYPE_MX_TO_STR->{ $_ } } @{ $aux_type }]
);
}
else
{
return (undef, undef, undef);
}
}
=head2 infer_shape
Infer the shape of outputs and arguments of given known shapes of arguments.
User can either pass in the known shapes in positional way or keyword argument way.
Tuple of Nones is returned if there is not enough information passed in.
An error will be raised if there is inconsistency found in the known shapes passed in.
Parameters
----------
*args :
Provide shape of arguments in a positional way.
Unknown shape can be marked as undef
**kwargs :
Provide keyword arguments of known shapes.
Returns
-------
arg_shapes : array ref of Shape or undef
List of shapes of arguments.
The order is in the same order as list_arguments()
out_shapes : array ref of Shape or undef
List of shapes of outputs.
The order is in the same order as list_outputs()
aux_shapes : array ref of Shape or undef
List of shapes of outputs.
The order is in the same order as list_auxiliary()
=cut
method infer_shape(Maybe[Str|Shape] @args)
{
my @res = $self->_infer_shape_impl(0, @args);
if(not defined $res[1])
{
my ($arg_shapes) = $self->_infer_shape_impl(1, @args);
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
$indptr,
$sdata,
)
);
if($complete)
{
return $arg_shapes, $out_shapes, $aux_shapes;
}
else
{
return (undef, undef, undef);
}
}
=head2 debug_str
The debug string.
Returns
-------
debug_str : string
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
my ($arg_handles, $arg_arrays) = ([], []);
if(ref $args eq 'ARRAY')
{
confess("Length of $arg_key do not match number of arguments")
unless @$args == @$arg_names;
@{ $arg_handles } = map { $_->handle } @{ $args };
$arg_arrays = $args;
}
else
{
my %tmp = ((map { $_ => undef } @$arg_names), %$args);
if(not $allow_missing and grep { not defined } values %tmp)
{
my ($missing) = grep { not defined $tmp{ $_ } } (keys %tmp);
confess("key $missing is missing in $arg_key");
}
for my $name (@$arg_names)
{
push @$arg_handles, defined($tmp{ $name }) ? $tmp{ $name }->handle : undef;
push @$arg_arrays, defined($tmp{ $name }) ? $tmp{ $name } : undef;
}
}
return ($arg_handles, $arg_arrays);
}
=head2 simple_bind
Bind current symbol to get an executor, allocate all the ndarrays needed.
Allows specifying data types.
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
@shared_arg_name_list = @{ $shared_arg_names };
}
my %shared_data;
if(defined $shared_buffer)
{
while(my ($k, $v) = each %{ $shared_buffer })
{
$shared_data{$k} = $v->handle;
}
}
my $shared_exec_handle = defined $shared_exec ? $shared_exec->handle : undef;
my (
$updated_shared_data,
$in_arg_handles,
$arg_grad_handles,
$aux_state_handles,
$exe_handle
);
eval {
($updated_shared_data, $in_arg_handles, $arg_grad_handles, $aux_state_handles, $exe_handle)
=
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
\@provided_grad_req_types,
scalar(@provided_arg_shape_names),
\@provided_arg_shape_names,
\@provided_arg_shape_data,
\@provided_arg_shape_idx,
$num_provided_arg_types,
\@provided_arg_type_names,
\@provided_arg_type_data,
scalar(@shared_arg_name_list),
\@shared_arg_name_list,
defined $shared_buffer ? \%shared_data : undef,
$shared_exec_handle
)
);
};
if($@)
{
confess(
"simple_bind failed: Error: $@; Arguments: ".
Data::Dumper->new(
[$shapes//{}]
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
);
}
if(defined $shared_buffer)
{
while(my ($k, $v) = each %{ $updated_shared_data })
{
$shared_buffer->{$k} = AI::MXNet::NDArray->new(handle => $v);
}
}
my @arg_arrays = map { AI::MXNet::NDArray->new(handle => $_) } @{ $in_arg_handles };
my @grad_arrays = map { defined $_ ? AI::MXNet::NDArray->new(handle => $_) : undef } @{ $arg_grad_handles };
my @aux_arrays = map { AI::MXNet::NDArray->new(handle => $_) } @{ $aux_state_handles };
my $executor = AI::MXNet::Executor->new(
handle => $exe_handle,
symbol => $self,
ctx => $ctx,
grad_req => $grad_req,
group2ctx => $group2ctx
);
$executor->arg_arrays(\@arg_arrays);
$executor->grad_arrays(\@grad_arrays);
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
Maybe[HashRef[AI::MXNet::Context]] :$group2ctx=,
Maybe[AI::MXNet::Executor] :$shared_exec=
)
{
$grad_req //= 'write';
my $listed_arguments = $self->list_arguments();
my ($args_handle, $args_grad_handle, $aux_args_handle) = ([], [], []);
($args_handle, $args) = $self->_get_ndarray_inputs('args', $args, $listed_arguments);
if(not defined $args_grad)
{
@$args_grad_handle = ((undef) x (@$args));
}
else
{
($args_grad_handle, $args_grad) = $self->_get_ndarray_inputs(
'args_grad', $args_grad, $listed_arguments, 1
);
}
if(not defined $aux_states)
{
lib/AI/MXNet/Symbol.pm view on Meta::CPAN
sub _parse_arguments
{
my $type = shift;
my @args = @_;
my $type_c = find_type_constraint($type);
my $str_c = find_type_constraint("Str");
my @positional_arguments;
my %kwargs;
my @kwargs_order;
my $only_dtypes_and_undefs = (@args == grep { not defined($_) or $type_c->check($_) } @args);
my $only_dtypes_and_strs = (@args == grep { $type_c->check($_) or $str_c->check($_) } @args);
if(@args % 2 and $only_dtypes_and_undefs)
{
@positional_arguments = @args;
}
else
{
if($only_dtypes_and_undefs)
{
@positional_arguments = @args;
}
elsif($only_dtypes_and_strs)
{
my %tmp = @args;
if(values(%tmp) == grep { $type_c->check($_) } values(%tmp))
{
%kwargs = %tmp;
my $i = 0;
lib/AI/MXNet/Symbol/NameManager.pm view on Meta::CPAN
This is default implementation.
When user specified a name,
the user specified name will be used.
When user did not, we will automatically generate a
name based on hint string.
Parameters
----------
name : str or undef
The name the user has specified.
hint : str
A hint string, which can be used to generate name.
Returns
-------
full_name : str
A canonical name for the symbol.
=cut
lib/AI/MXNet/Visualization.pm view on Meta::CPAN
Int $line_length=120,
ArrayRef[Num] $positions=[.44, .64, .74, 1]
)
{
my $show_shape;
my %shape_dict;
if(defined $shape)
{
$show_shape = 1;
my $interals = $symbol->get_internals;
my (undef, $out_shapes, undef) = $interals->infer_shape(%{ $shape });
Carp::confess("Input shape is incomplete")
unless defined $out_shapes;
@shape_dict{ @{ $interals->list_outputs } } = @{ $out_shapes };
}
my $conf = decode_json($symbol->tojson);
my $nodes = $conf->{nodes};
my %heads = map { $_ => 1 } @{ $conf->{heads}[0] };
if($positions->[-1] <= 1)
{
$positions = [map { int($line_length * $_) } @{ $positions }];
lib/AI/MXNet/Visualization.pm view on Meta::CPAN
)
{
eval { require GraphViz; };
Carp::confess("plot_network requires GraphViz module") if $@;
my $draw_shape;
my %shape_dict;
if(defined $shape)
{
$draw_shape = 1;
my $interals = $symbol->get_internals;
my (undef, $out_shapes, undef) = $interals->infer_shape(%{ $shape });
Carp::confess("Input shape is incomplete")
unless defined $out_shapes;
@shape_dict{ @{ $interals->list_outputs } } = @{ $out_shapes };
}
my $conf = decode_json($symbol->tojson);
my $nodes = $conf->{nodes};
my %node_attr = (
qw/ shape box fixedsize true
width 1.3 height 0.8034 style filled/,
%{ $node_attrs }
t/test_module.t view on Meta::CPAN
sub test_module_states
{
my $stack = mx->rnn->SequentialRNNCell();
for my $i (0..1)
{
$stack->add(mx->rnn->LSTMCell(num_hidden=>20, prefix=>"lstm_l${i}_"));
}
my $begin_state = $stack->begin_state(func=>mx->sym->can('Variable'));
my (undef, $states) = $stack->unroll(10, begin_state=>$begin_state, inputs=>mx->sym->Variable('data'));
my $state_names = [map { $_->name } @$begin_state];
my $mod = mx->mod->Module(
mx->sym->Group($states), context=>[mx->cpu(0), mx->cpu(1)],
state_names=>$state_names
);
$mod->bind(data_shapes=>[['data', [5, 10]]], for_training=>0);
$mod->init_params();
my $batch = mx->io->DataBatch(data=>[mx->nd->zeros([5, 10])], label=>[]);
t/test_optimizers.t view on Meta::CPAN
}
}
func test_lr_wd_mult()
{
my $data = mx->sym->Variable('data');
my $bias = mx->sym->Variable('fc1_bias', lr_mult => 1.0);
my $fc1 = mx->sym->FullyConnected({ data => $data, bias => $bias, name => 'fc1', num_hidden => 10, lr_mult => 0 });
my $fc2 = mx->sym->FullyConnected({ data => $fc1, name => 'fc2', num_hidden => 10, wd_mult => 0.5 });
my $mod = mx->mod->new(symbol => $fc2, label_names => undef);
$mod->bind(data_shapes => [['data', [5,10]]]);
$mod->init_params(initializer => mx->init->Uniform(scale => 1.0));
$mod->init_optimizer(optimizer_params => { learning_rate => "1.0" });
my %args1 = %{ ($mod->get_params())[0] };
for my $k (keys %args1)
{
$args1{$k} = $args1{$k}->aspdl;
}
$mod->forward(AI::MXNet::DataBatch->new(data=>[mx->random->uniform({low=>-1.0, high=>1.0, shape=>[5,10]})], label=>undef), is_train=>1);
$mod->backward($mod->get_outputs());
$mod->update();
my %args2 = %{ ($mod->get_params())[0] };
for my $k (keys %args2)
{
$args2{$k} = $args2{$k}->aspdl;
}
is_deeply($mod->_p->_optimizer->lr_mult, { fc1_bias => 1, fc1_weight => 0 }, "lr_mult");
is_deeply($mod->_p->_optimizer->wd_mult, { fc2_bias => 0.5, fc2_weight => 0.5, fc1_bias => 0, }, "wd_mult");
ok(almost_equal($args1{fc1_weight}, $args2{fc1_weight}, 1e-10), "fc1_weight");
t/test_recordio.t view on Meta::CPAN
sub test_recordio
{
my ($fd, $frec) = tempfile();
my $N = 255;
my $writer = mx->recordio->MXRecordIO($frec, 'w');
for my $i (0..$N-1)
{
$writer->write(chr($i));
}
undef $writer;
my $reader = mx->recordio->MXRecordIO($frec, 'r');
for my $i (0..$N-1)
{
my $res = $reader->read;
is($res, chr($i));
}
}
sub test_indexed_recordio
{
my ($fi, $fidx) = tempfile();
my ($fr, $frec) = tempfile();
my $N = 255;
my $writer = mx->recordio->MXIndexedRecordIO($fidx, $frec, 'w');
for my $i (0..$N-1)
{
$writer->write_idx($i, chr($i));
}
undef $writer;
my $reader = mx->recordio->MXIndexedRecordIO($fidx, $frec, 'r');
my @keys = @{ $reader->keys };
is_deeply([sort {$a <=> $b} @keys], [0..$N-1]);
@keys = List::Util::shuffle(@keys);
for my $i (@keys)
{
my $res = $reader->read_idx($i);
is($res, chr($i));
}
t/test_rnn.t view on Meta::CPAN
use PDL;
use Test::More tests => 54;
sub test_rnn
{
my $cell = mx->rnn->RNNCell(100, prefix=>'rnn_');
my ($outputs) = $cell->unroll(3, input_prefix=>'rnn_');
$outputs = mx->sym->Group($outputs);
is_deeply([sort keys %{$cell->params->_params}], ['rnn_h2h_bias', 'rnn_h2h_weight', 'rnn_i2h_bias', 'rnn_i2h_weight']);
is_deeply($outputs->list_outputs(), ['rnn_t0_out_output', 'rnn_t1_out_output', 'rnn_t2_out_output']);
my (undef, $outs, undef) = $outputs->infer_shape(rnn_t0_data=>[10,50], rnn_t1_data=>[10,50], rnn_t2_data=>[10,50]);
is_deeply($outs, [[10, 100], [10, 100], [10, 100]]);
}
sub test_lstm
{
my $cell = mx->rnn->LSTMCell(100, prefix=>'rnn_', forget_bias => 1);
my($outputs) = $cell->unroll(3, input_prefix=>'rnn_');
$outputs = mx->sym->Group($outputs);
is_deeply([sort keys %{$cell->params->_params}], ['rnn_h2h_bias', 'rnn_h2h_weight', 'rnn_i2h_bias', 'rnn_i2h_weight']);
is_deeply($outputs->list_outputs(), ['rnn_t0_out_output', 'rnn_t1_out_output', 'rnn_t2_out_output']);
my (undef, $outs, undef) = $outputs->infer_shape(rnn_t0_data=>[10,50], rnn_t1_data=>[10,50], rnn_t2_data=>[10,50]);
is_deeply($outs, [[10, 100], [10, 100], [10, 100]]);
}
sub test_lstm_forget_bias
{
my $forget_bias = 2;
my $stack = mx->rnn->SequentialRNNCell();
$stack->add(mx->rnn->LSTMCell(100, forget_bias=>$forget_bias, prefix=>'l0_'));
$stack->add(mx->rnn->LSTMCell(100, forget_bias=>$forget_bias, prefix=>'l1_'));
t/test_rnn.t view on Meta::CPAN
);
}
sub test_gru
{
my $cell = mx->rnn->GRUCell(100, prefix=>'rnn_');
my($outputs) = $cell->unroll(3, input_prefix=>'rnn_');
$outputs = mx->sym->Group($outputs);
is_deeply([sort keys %{$cell->params->_params}], ['rnn_h2h_bias', 'rnn_h2h_weight', 'rnn_i2h_bias', 'rnn_i2h_weight']);
is_deeply($outputs->list_outputs(), ['rnn_t0_out_output', 'rnn_t1_out_output', 'rnn_t2_out_output']);
my (undef, $outs, undef) = $outputs->infer_shape(rnn_t0_data=>[10,50], rnn_t1_data=>[10,50], rnn_t2_data=>[10,50]);
is_deeply($outs, [[10, 100], [10, 100], [10, 100]]);
}
sub test_residual
{
my $cell = mx->rnn->ResidualCell(mx->rnn->GRUCell(50, prefix=>'rnn_'));
my $inputs = [map { mx->sym->Variable("rnn_t${_}_data") } 0..1];
my ($outputs)= $cell->unroll(2, inputs => $inputs);
$outputs = mx->sym->Group($outputs);
is_deeply(
[sort keys %{ $cell->params->_params }],
['rnn_h2h_bias', 'rnn_h2h_weight', 'rnn_i2h_bias', 'rnn_i2h_weight']
);
is_deeply(
$outputs->list_outputs,
['rnn_t0_out_plus_residual_output', 'rnn_t1_out_plus_residual_output']
);
my (undef, $outs) = $outputs->infer_shape(rnn_t0_data=>[10, 50], rnn_t1_data=>[10, 50]);
is_deeply($outs, [[10, 50], [10, 50]]);
$outputs = $outputs->eval(args => {
rnn_t0_data=>mx->nd->ones([10, 50]),
rnn_t1_data=>mx->nd->ones([10, 50]),
rnn_i2h_weight=>mx->nd->zeros([150, 50]),
rnn_i2h_bias=>mx->nd->zeros([150]),
rnn_h2h_weight=>mx->nd->zeros([150, 50]),
rnn_h2h_bias=>mx->nd->zeros([150])
});
my $expected_outputs = mx->nd->ones([10, 50])->aspdl;
t/test_rnn.t view on Meta::CPAN
is_deeply(
[sort keys %{ $cell->params->_params }],
['rnn_l_h2h_bias', 'rnn_l_h2h_weight', 'rnn_l_i2h_bias', 'rnn_l_i2h_weight',
'rnn_r_h2h_bias', 'rnn_r_h2h_weight', 'rnn_r_i2h_bias', 'rnn_r_i2h_weight']
);
is_deeply(
$outputs->list_outputs,
['bi_t0_plus_residual_output', 'bi_t1_plus_residual_output']
);
my (undef, $outs) = $outputs->infer_shape(rnn_t0_data=>[10, 50], rnn_t1_data=>[10, 50]);
is_deeply($outs, [[10, 50], [10, 50]]);
$outputs = $outputs->eval(args => {
rnn_t0_data=>mx->nd->ones([10, 50])+5,
rnn_t1_data=>mx->nd->ones([10, 50])+5,
rnn_l_i2h_weight=>mx->nd->zeros([75, 50]),
rnn_l_i2h_bias=>mx->nd->zeros([75]),
rnn_l_h2h_weight=>mx->nd->zeros([75, 25]),
rnn_l_h2h_bias=>mx->nd->zeros([75]),
rnn_r_i2h_weight=>mx->nd->zeros([75, 50]),
rnn_r_i2h_bias=>mx->nd->zeros([75]),
t/test_rnn.t view on Meta::CPAN
$outputs = mx->sym->Group($outputs);
my %params = %{ $cell->params->_params };
for my $i (0..4)
{
ok(exists $params{"rnn_stack${i}_h2h_weight"});
ok(exists $params{"rnn_stack${i}_h2h_bias"});
ok(exists $params{"rnn_stack${i}_i2h_weight"});
ok(exists $params{"rnn_stack${i}_i2h_bias"});
}
is_deeply($outputs->list_outputs(), ['rnn_stack4_t0_out_output', 'rnn_stack4_t1_out_output', 'rnn_stack4_t2_out_output']);
my (undef, $outs, undef) = $outputs->infer_shape(rnn_t0_data=>[10,50], rnn_t1_data=>[10,50], rnn_t2_data=>[10,50]);
is_deeply($outs, [[10, 100], [10, 100], [10, 100]]);
}
sub test_bidirectional
{
my $cell = mx->rnn->BidirectionalCell(
mx->rnn->LSTMCell(100, prefix=>'rnn_l0_'),
mx->rnn->LSTMCell(100, prefix=>'rnn_r0_'),
output_prefix=>'rnn_bi_'
);
my ($outputs) = $cell->unroll(3, input_prefix=>'rnn_');
$outputs = mx->sym->Group($outputs);
is_deeply($outputs->list_outputs(), ['rnn_bi_t0_output', 'rnn_bi_t1_output', 'rnn_bi_t2_output']);
my (undef, $outs, undef) = $outputs->infer_shape(rnn_t0_data=>[10,50], rnn_t1_data=>[10,50], rnn_t2_data=>[10,50]);
is_deeply($outs, [[10, 200], [10, 200], [10, 200]]);
}
sub test_unfuse
{
my $cell = mx->rnn->FusedRNNCell(
100, num_layers => 1, mode => 'lstm',
prefix => 'test_', bidirectional => 1
)->unfuse;
my ($outputs) = $cell->unroll(3, input_prefix=>'rnn_');
$outputs = mx->sym->Group($outputs);
is_deeply($outputs->list_outputs(), ['test_bi_lstm_0t0_output', 'test_bi_lstm_0t1_output', 'test_bi_lstm_0t2_output']);
my (undef, $outs, undef) = $outputs->infer_shape(rnn_t0_data=>[10,50], rnn_t1_data=>[10,50], rnn_t2_data=>[10,50]);
is_deeply($outs, [[10, 200], [10, 200], [10, 200]]);
}
sub test_zoneout
{
my $cell = mx->rnn->ZoneoutCell(
mx->rnn->RNNCell(100, prefix=>'rnn_'),
zoneout_outputs => 0.5,
zoneout_states => 0.5
);
my $inputs = [map { mx->sym->Variable("rnn_t${_}_data") } 0..2];
my ($outputs) = $cell->unroll(3, inputs => $inputs);
$outputs = mx->sym->Group($outputs);
my (undef, $outs) = $outputs->infer_shape(rnn_t0_data=>[10, 50], rnn_t1_data=>[10, 50], rnn_t2_data=>[10, 50]);
is_deeply($outs, [[10, 100], [10, 100], [10, 100]]);
}
sub test_convrnn
{
my $cell = mx->rnn->ConvRNNCell(input_shape => [1, 3, 16, 10], num_hidden=>10,
h2h_kernel=>[3, 3], h2h_dilate=>[1, 1],
i2h_kernel=>[3, 3], i2h_stride=>[1, 1],
i2h_pad=>[1, 1], i2h_dilate=>[1, 1],
prefix=>'rnn_');
my $inputs = [map { mx->sym->Variable("rnn_t${_}_data") } 0..2];
my ($outputs) = $cell->unroll(3, inputs => $inputs);
$outputs = mx->sym->Group($outputs);
is_deeply(
[sort keys %{ $cell->params->_params }],
['rnn_h2h_bias', 'rnn_h2h_weight', 'rnn_i2h_bias', 'rnn_i2h_weight']
);
is_deeply($outputs->list_outputs(), ['rnn_t0_out_output', 'rnn_t1_out_output', 'rnn_t2_out_output']);
my (undef, $outs) = $outputs->infer_shape(rnn_t0_data=>[1, 3, 16, 10], rnn_t1_data=>[1, 3, 16, 10], rnn_t2_data=>[1, 3, 16, 10]);
is_deeply($outs, [[1, 10, 16, 10], [1, 10, 16, 10], [1, 10, 16, 10]]);
}
sub test_convlstm
{
my $cell = mx->rnn->ConvLSTMCell(input_shape => [1, 3, 16, 10], num_hidden=>10,
h2h_kernel=>[3, 3], h2h_dilate=>[1, 1],
i2h_kernel=>[3, 3], i2h_stride=>[1, 1],
i2h_pad=>[1, 1], i2h_dilate=>[1, 1],
prefix=>'rnn_', forget_bias => 1);
my $inputs = [map { mx->sym->Variable("rnn_t${_}_data") } 0..2];
my ($outputs) = $cell->unroll(3, inputs => $inputs);
$outputs = mx->sym->Group($outputs);
is_deeply(
[sort keys %{ $cell->params->_params }],
['rnn_h2h_bias', 'rnn_h2h_weight', 'rnn_i2h_bias', 'rnn_i2h_weight']
);
is_deeply($outputs->list_outputs(), ['rnn_t0_out_output', 'rnn_t1_out_output', 'rnn_t2_out_output']);
my (undef, $outs) = $outputs->infer_shape(rnn_t0_data=>[1, 3, 16, 10], rnn_t1_data=>[1, 3, 16, 10], rnn_t2_data=>[1, 3, 16, 10]);
is_deeply($outs, [[1, 10, 16, 10], [1, 10, 16, 10], [1, 10, 16, 10]]);
}
sub test_convgru
{
my $cell = mx->rnn->ConvGRUCell(input_shape => [1, 3, 16, 10], num_hidden=>10,
h2h_kernel=>[3, 3], h2h_dilate=>[1, 1],
i2h_kernel=>[3, 3], i2h_stride=>[1, 1],
i2h_pad=>[1, 1], i2h_dilate=>[1, 1],
prefix=>'rnn_', forget_bias => 1);
my $inputs = [map { mx->sym->Variable("rnn_t${_}_data") } 0..2];
my ($outputs) = $cell->unroll(3, inputs => $inputs);
$outputs = mx->sym->Group($outputs);
is_deeply(
[sort keys %{ $cell->params->_params }],
['rnn_h2h_bias', 'rnn_h2h_weight', 'rnn_i2h_bias', 'rnn_i2h_weight']
);
is_deeply($outputs->list_outputs(), ['rnn_t0_out_output', 'rnn_t1_out_output', 'rnn_t2_out_output']);
my (undef, $outs) = $outputs->infer_shape(rnn_t0_data=>[1, 3, 16, 10], rnn_t1_data=>[1, 3, 16, 10], rnn_t2_data=>[1, 3, 16, 10]);
is_deeply($outs, [[1, 10, 16, 10], [1, 10, 16, 10], [1, 10, 16, 10]]);
}
test_rnn();
test_lstm();
test_lstm_forget_bias();
test_gru();
test_residual();
test_residual_bidirectional();
test_stack();
t/test_symbol.t view on Meta::CPAN
my $data = mx->symbol->Variable('data');
my $prev = mx->symbol->Variable('prevstate');
my $x2h = mx->symbol->FullyConnected(data=>$data, name=>'x2h', num_hidden=>$num_hidden);
my $h2h = mx->symbol->FullyConnected(data=>$prev, name=>'h2h', num_hidden=>$num_hidden);
my $out = mx->symbol->Activation(data=>mx->sym->elemwise_add($x2h, $h2h), name=>'out', act_type=>'relu');
# shape inference will fail because information is not available for h2h
my @ret = $out->infer_shape(data=>[$num_sample, $num_dim]);
is_deeply(\@ret, [undef, undef, undef]);
my ($arg_shapes, $out_shapes, $aux_shapes) = $out->infer_shape_partial(data=>[$num_sample, $num_dim]);
my %arg_shapes;
@arg_shapes{ @{ $out->list_arguments } } = @{ $arg_shapes };
is_deeply($arg_shapes{data}, [$num_sample, $num_dim]);
is_deeply($arg_shapes{x2h_weight}, [$num_hidden, $num_dim]);
is_deeply($arg_shapes{h2h_weight}, []);
# now we can do full shape inference
my $state_shape = $out_shapes->[0];
t/test_symbol.t view on Meta::CPAN
}
my ($fc2, $act2, $fc3, $sym1);
{
local($mx::AttrScope) = mx->AttrScope(ctx_group=>'stage2');
$fc2 = mx->symbol->FullyConnected(data => $act1, name => 'fc2', num_hidden => 64, lr_mult=>0.01);
$act2 = mx->symbol->Activation(data => $fc2, name=>'relu2', act_type=>"relu");
$fc3 = mx->symbol->FullyConnected(data => $act2, name=>'fc3', num_hidden=>10);
$fc3 = mx->symbol->BatchNorm($fc3, name=>'batchnorm0');
$sym1 = mx->symbol->SoftmaxOutput(data => $fc3, name => 'softmax')
}
{ local $/ = undef; my $json = <DATA>; open(F, ">save_000800.json"); print F $json; close(F); };
my $sym2 = mx->sym->load('save_000800.json');
unlink 'save_000800.json';
my %attr1 = %{ $sym1->attr_dict };
my %attr2 = %{ $sym2->attr_dict };
while(my ($k, $v1) = each %attr1)
{
ok(exists $attr2{ $k });
my $v2 = $attr2{$k};
while(my ($kk, $vv1) = each %{ $v1 })