AI-Perceptron
view release on metacpan or search on metacpan
->weights([ 0.1, 0.2 ]);
my @inputs = ( 1.3, -0.45 ); # input can be any number
my $target = 1; # output is always -1 or 1
my $current = $p->compute_output( @inputs );
print "current output: $current, target: $target\n";
$p->add_examples( [ $target, @inputs ] );
$p->max_iterations( 10 )->train or
warn "couldn't train in 10 iterations!";
print "training until it gets it right\n";
$p->max_iterations( -1 )->train; # watch out for infinite loops
DESCRIPTION
This module is meant to show how a single node of a neural network
works.
Training is done by the *Stochastic Approximation of the
Gradient-Descent* model.
MODEL
Model of a Perceptron
update weights for each example that fails
The value each weight is adjusted by is calculated as follows:
delta[i] = learning_rate * (expected_output - output) * input[i]
Which is know as a negative feedback loop - it uses the current output
as an input to determine what the next output will be.
Also, note that this means you can get stuck in an infinite loop. It's
not a bad idea to set the maximum number of iterations to prevent that.
CONSTRUCTOR
new( [%args] )
Creates a new perceptron with the following default properties:
num_inputs = 1
learning_rate = 0.01
threshold = 0.0
weights = empty list
threshold( [ $float ] )
Set/get the perceptron's number of inputs.
training_examples( [ \@examples ] )
Set/get the perceptron's list of training examples. This should be a
list of arrayrefs of the form:
[ $expected_result => @inputs ]
max_iterations( [ $int ] )
Set/get the perceptron's number of inputs, a negative value implies
no maximum.
METHODS
compute_output( @inputs )
Computes and returns the perceptron's output (either -1 or 1) for
the given inputs. See the above model for more details.
add_examples( @training_examples )
Adds the @training_examples to to current list of examples. See
lib/AI/Perceptron.pm view on Meta::CPAN
->weights([ 0.1, 0.2 ]);
my @inputs = ( 1.3, -0.45 ); # input can be any number
my $target = 1; # output is always -1 or 1
my $current = $p->compute_output( @inputs );
print "current output: $current, target: $target\n";
$p->add_examples( [ $target, @inputs ] );
$p->max_iterations( 10 )->train or
warn "couldn't train in 10 iterations!";
print "training until it gets it right\n";
$p->max_iterations( -1 )->train; # watch out for infinite loops
=cut
package AI::Perceptron;
use strict;
use accessors qw( num_inputs learning_rate _weights threshold
training_examples max_iterations );
our $VERSION = '1.0';
our $Debug = 0;
sub new {
my $class = shift;
my $self = bless {}, $class;
return $self->init( @_ );
}
sub init {
my $self = shift;
my %args = @_;
$self->num_inputs( $args{Inputs} || 1 )
->learning_rate( $args{N} || 0.05 )
->max_iterations( -1 )
->threshold( $args{T} || 0.0 )
->training_examples( [] )
->weights( [] );
# DEPRECATED: backwards compat
if ($args{W}) {
$self->threshold( shift @{ $args{W} } )
->weights( [ @{ $args{W} } ] );
}
lib/AI/Perceptron.pm view on Meta::CPAN
my $self = shift;
$self->add_examples( @_ ) if @_;
$self->verify_weights;
# adjust the weights for each training example until the output
# function correctly classifies all the training examples.
my $iter = 0;
while(! $self->classifies_examples_correctly ) {
if (($self->max_iterations > 0) and
($iter >= $self->max_iterations)) {
$self->emit( "stopped training after $iter iterations" );
return;
}
$iter++;
$self->emit( "Training iteration $iter" );
foreach my $training_example (@{ $self->training_examples }) {
my ($expected_output, @inputs) = @$training_example;
$self->emit( "Training X=<", join(',', @inputs),
lib/AI/Perceptron.pm view on Meta::CPAN
# want the perceptron's output equal to training output
# TODO: this duplicates work by classifies_examples_correctly()
my $output = $self->compute_output(@inputs);
next if ($output == $expected_output);
$self->adjust_threshold( $expected_output, $output )
->adjust_weights( \@inputs, $expected_output, $output );
}
}
$self->emit( "completed in $iter iterations." );
return $self;
}
# return true unless all training examples are correctly classified
sub classifies_examples_correctly {
my $self = shift;
my $training_examples = $self->training_examples;
foreach my $training_example (@$training_examples) {
lib/AI/Perceptron.pm view on Meta::CPAN
update weights for each example that fails
The value each weight is adjusted by is calculated as follows:
delta[i] = learning_rate * (expected_output - output) * input[i]
Which is know as a negative feedback loop - it uses the current output as an
input to determine what the next output will be.
Also, note that this means you can get stuck in an infinite loop. It's not a
bad idea to set the maximum number of iterations to prevent that.
=head1 CONSTRUCTOR
=over 4
=item new( [%args] )
Creates a new perceptron with the following default properties:
num_inputs = 1
lib/AI/Perceptron.pm view on Meta::CPAN
Set/get the perceptron's number of inputs.
=item training_examples( [ \@examples ] )
Set/get the perceptron's list of training examples. This should be a list of
arrayrefs of the form:
[ $expected_result => @inputs ]
=item max_iterations( [ $int ] )
Set/get the perceptron's number of inputs, a negative value implies no maximum.
=back
=head1 METHODS
=over 4
=item compute_output( @inputs )
t/01_basic.t view on Meta::CPAN
use Test::More 'no_plan'; # tests => 3;
use_ok( 'AI::Perceptron' );
my $p = AI::Perceptron->new
->num_inputs( 2 )
->learning_rate( 0.01 )
->threshold( 0.8 )
->weights([ -0.5, 0.5 ])
->max_iterations( 20 );
# get the current output of the node given a training example:
my @inputs = ( 1, 1 );
my $target_output = 1;
my $current_output = $p->compute_output( @inputs );
ok( defined $current_output, 'compute_output' );
is( $current_output, $target_output, 'expected output for preset weights' );
# train the perceptron until it gets it right:
use Test::More 'no_plan'; # tests => 3;
use AI::Perceptron;
my $p = AI::Perceptron->new
->num_inputs( 3 )
->learning_rate( 0.01 )
->threshold( 0.02 )
->weights([ 0.1, 0.2, -0.3 ])
->max_iterations( 5 )
->training_examples( [ -1 => 1, 2 ] );
is( $p->num_inputs, 3, 'num_inputs' );
is( $p->learning_rate, 0.01, 'learning_rate' );
is( $p->threshold, 0.02, 'threshold' );
is( $p->max_iterations, 5, 'threshold' );
isa_ok( $p->weights, 'ARRAY', 'weights' );
isa_ok( $p->training_examples, 'ARRAY', 'examples' );
is( $p->add_examples( [-1 => 1, 1] ), $p, 'add_examples' );
can_ok( $p, 'add_example', 'add_example' );
##
## backwards compat
##
( run in 2.878 seconds using v1.01-cache-2.11-cpan-96521ef73a4 )