Ancient
view release on metacpan or search on metacpan
t/lib/NeuralNet/Layer.pm view on Meta::CPAN
weights $self, \@w;
# Initialize biases to zero
biases $self, [(0) x $out];
# Initialize gradient accumulators
weight_grads $self, [map { [(0) x $in] } 1 .. $out];
bias_grads $self, [(0) x $out];
}
sub forward {
my ($self, $input) = @_;
last_input $self, $input;
my $w = weights $self;
my $b = biases $self;
my $out_size = output_size $self;
my @output;
for my $i (0 .. $out_size - 1) {
my $sum = $b->[$i];
for my $j (0 .. @$input - 1) {
$sum += $w->[$i][$j] * $input->[$j];
}
push @output, $sum;
}
last_output $self, \@output;
return \@output;
}
sub backward {
my ($self, $grad) = @_;
my $input = last_input $self;
my $w = weights $self;
my $in_size = input_size $self;
my $out_size = output_size $self;
# Compute weight gradients
my $wg = weight_grads $self;
my $bg = bias_grads $self;
for my $i (0 .. $out_size - 1) {
$bg->[$i] += $grad->[$i];
for my $j (0 .. $in_size - 1) {
$wg->[$i][$j] += $grad->[$i] * $input->[$j];
}
}
# Compute gradient w.r.t. input
my @input_grad = (0) x $in_size;
for my $j (0 .. $in_size - 1) {
for my $i (0 .. $out_size - 1) {
$input_grad[$j] += $w->[$i][$j] * $grad->[$i];
}
}
return \@input_grad;
}
sub update {
my ($self, $lr) = @_;
my $w = weights $self;
my $b = biases $self;
my $wg = weight_grads $self;
my $bg = bias_grads $self;
my $out_size = output_size $self;
my $in_size = input_size $self;
# Update weights and biases
for my $i (0 .. $out_size - 1) {
$b->[$i] -= $lr * $bg->[$i];
$bg->[$i] = 0; # Reset gradient
for my $j (0 .. $in_size - 1) {
$w->[$i][$j] -= $lr * $wg->[$i][$j];
$wg->[$i][$j] = 0; # Reset gradient
}
}
}
sub num_params {
my ($self) = @_;
my $in = input_size $self;
my $out = output_size $self;
return $in * $out + $out; # weights + biases
}
1;
__END__
=head1 NAME
NeuralNet::Layer - Dense layer with typed slots
=head1 SYNOPSIS
use NeuralNet::Layer;
my $layer = NeuralNet::Layer->new(
input_size => 4,
output_size => 2,
);
$layer->BUILD;
my $out = $layer->forward([1, 2, 3, 4]);
=head1 DESCRIPTION
Demonstrates typed slots (Int:required), ArrayRef slots,
function-style accessors, and custom methods.
=cut
( run in 2.069 seconds using v1.01-cache-2.11-cpan-63c85eba8c4 )