AI-NeuralNet-Simple

 view release on metacpan or  search on metacpan

Simple.xs  view on Meta::CPAN

    n->error.hidden  = malloc(sizeof(double) * n->size.hidden);
    n->error.output  = malloc(sizeof(double) * n->size.output);
    
    /* one extra for sentinel */
    n->weight.input_to_hidden  
        = malloc(sizeof(void *) * (input_layer_with_bias + 1));
    n->weight.hidden_to_output 
        = malloc(sizeof(void *) * (hidden_layer_with_bias + 1));

    if(!n->weight.input_to_hidden || !n->weight.hidden_to_output) {
        printf("Initial malloc() failed\n");
        return 0;
    }
    
    /* now allocate the actual rows */
    for(i = 0; i < input_layer_with_bias; i++) {
        n->weight.input_to_hidden[i] 
            = malloc(hidden_layer_with_bias * sizeof(double));
        if(n->weight.input_to_hidden[i] == 0) {
            free(*n->weight.input_to_hidden);
            printf("Second malloc() to weight.input_to_hidden failed\n");
            return 0;
        }
    }

    /* now allocate the actual rows */
    for(i = 0; i < hidden_layer_with_bias; i++) {
        n->weight.hidden_to_output[i] 
            = malloc(n->size.output * sizeof(double));
        if(n->weight.hidden_to_output[i] == 0) {
            free(*n->weight.hidden_to_output);
            printf("Second malloc() to weight.hidden_to_output failed\n");
            return 0;
        }
    }

    /* initialize the sentinel value */
    n->weight.input_to_hidden[input_layer_with_bias]   = 0;
    n->weight.hidden_to_output[hidden_layer_with_bias] = 0;

    return 1;
}

examples/game_ai.pl  view on Meta::CPAN

    [POOR,     NO,   NO, 2],  HIDE,
    [POOR,     NO,   NO, 1],  HIDE,
    [POOR,     NO,   NO, 0],  WANDER,
    [POOR,    YES,   NO, 0],  WANDER,
]);


my $format = "%8s %5s %3s %7s %6s\n";
my @actions = qw/attack run wander hide/;

printf $format, qw/Health Knife Gun Enemies Action/;
display_result($net,2,1,1,1);
display_result($net,2,0,0,2);
display_result($net,2,0,1,2);
display_result($net,2,0,1,3);
display_result($net,1,1,0,0);
display_result($net,1,0,1,2);
display_result($net,0,1,0,3);

while (1) {
    print "Type 'quit' to exit\n";
    my $health  = prompt("Am I in poor, average, or good health? ", qr/^(?i:[pag])/);
    my $knife   = prompt("Do I have a knife? ", qr/^(?i:[yn])/);
    my $gun     = prompt("Do I have a gun? ", qr/^(?i:[yn])/);
    my $enemies = prompt("How many enemies can I see? ", qr/^\d+$/);
    
    $health = substr $health, 0, 1;
    $health =~ tr/pag/012/;
    foreach ($knife,$gun) {
        $_ = substr $_, 0, 1;
        tr/yn/10/;
    }
    printf "I think I will %s!\n\n", $actions[$net->winner([
        $health, 
        $knife, 
        $gun, 
        $enemies])];
}

sub prompt 
{
    my ($message,$domain) = @_;
    my $valid_response = 0;
    my $response;
    do {
        print $message;
        chomp($response = <STDIN>);
        exit if substr(lc $response, 0, 1) eq 'q';
        $valid_response = $response =~ /$domain/;
    } until $valid_response;
    return $response;
}

sub display_result
{
    my ($net,@data) = @_;
    my $result      = $net->winner(\@data);
    my @health      = qw/Poor Average Good/;
    my @knife       = qw/No Yes/;
    my @gun         = qw/No Yes/;
    printf $format, 
        $health[$_[1]], 
        $knife[$_[2]], 
        $gun[$_[3]], 
        $_[4],             # number of enemies
        $actions[$result];
}

examples/logical_or.pl  view on Meta::CPAN

use AI::NeuralNet::Simple;

my $net = AI::NeuralNet::Simple->new(2,1,2);
for (1 .. 100000) {
    $net->train([1,1],[0,1]);
    $net->train([1,0],[0,1]);
    $net->train([0,1],[0,1]);
    $net->train([0,0],[1,0]);
}

printf "Answer: %d\n",   $net->winner([1,1]);
printf "Answer: %d\n",   $net->winner([1,0]);
printf "Answer: %d\n",   $net->winner([0,1]);
printf "Answer: %d\n\n", $net->winner([0,0]);
use Data::Dumper;
print Dumper $net->infer([1,1]);

lib/AI/NeuralNet/Simple.pm  view on Meta::CPAN


  use AI::NeuralNet::Simple;
  my $net = AI::NeuralNet::Simple->new(2,1,2);
  # teach it logical 'or'
  for (1 .. 10000) {
      $net->train([1,1],[0,1]);
      $net->train([1,0],[0,1]);
      $net->train([0,1],[0,1]);
      $net->train([0,0],[1,0]);
  }
  printf "Answer: %d\n",   $net->winner([1,1]);
  printf "Answer: %d\n",   $net->winner([1,0]);
  printf "Answer: %d\n",   $net->winner([0,1]);
  printf "Answer: %d\n\n", $net->winner([0,0]);

=head1 ABSTRACT

  This module is a simple neural net designed for those who have an interest
  in artificial intelligence but need a "gentle" introduction.  This is not
  intended to replace any of the neural net modules currently available on the
  CPAN.

=head1 DESCRIPTION

lib/AI/NeuralNet/Simple.pm  view on Meta::CPAN

not learn as accurately.

=head2 C<infer(\@input)>

This method, if provided with an input array reference, will return an array
reference corresponding to the output values that it is guessing.  Note that
these values will generally be close, but not exact.  For example, with the 
"logical or" program, you might expect results similar to:

  use Data::Dumper;
  print Dumper $net->infer([1,1]);
  
  $VAR1 = [
          '0.00993729281477686',
          '0.990100297418451'
        ];

That clearly has the second output item being close to 1, so as a helper method
for use with a winner take all strategy, we have ...

=head2 C<winner(\@input)>

This method returns the index of the highest value from inferred results:

  print $net->winner([1,1]); # will likely print "1"

For a more comprehensive example of how this is used, see the 
"examples/game_ai.pl" program.

=head1 EXPORT

None by default.

=head1 CAVEATS

t/10nn_simple.t  view on Meta::CPAN

    '... and supplying new() with bad arguments should also die';

my $net = $CLASS->new(2,1,2);
ok($net, 'Calling new with good arguments should succeed');
isa_ok($net, $CLASS => '...and the object it returns');

can_ok($net, 'learn_rate');
throws_ok {$net->learn_rate(2)}
    qr/^\QLearn rate must be between 0 and 1, exclusive\E/,
    '... and setting it outside of legal boundaries should die';
is(sprintf("%.1f", $net->learn_rate), "0.2", '... and it should have the correct learn rate');
isa_ok($net->learn_rate(.3), $CLASS => '... and setting it should return the object');
is(sprintf("%.1f", $net->learn_rate), "0.3", '... and should set it correctly');
$net->learn_rate(.2);

can_ok($net, 'train');

# teach the network logical 'or'

ok($net->train([1,1], [0,1]), 'Calling train() with valid data should succeed');
for (1 .. 10000) {
    $net->train([1,1],[0,1]);
    $net->train([1,0],[0,1]);

t/20nn_multi.t  view on Meta::CPAN

    use_ok($CLASS) || die; 
};

can_ok($CLASS, 'new');

my $net1 = $CLASS->new(2,1,2);
ok($net1, 'Calling new with good arguments should succeed');
isa_ok($net1, $CLASS => '...and the object it returns');

can_ok($net1, 'learn_rate');
is(sprintf("%.1f", $net1->learn_rate), "0.2", '... and it should have the correct learn rate');
isa_ok($net1->learn_rate(.5), $CLASS => '... and setting it should return the object');
is(sprintf("%.1f", $net1->learn_rate), "0.5", '... and should set it correctly');

my $net2 = $CLASS->new(5,8,2);
ok($net2, 'Calling new with good arguments should succeed');
isa_ok($net2, $CLASS => '...and the object it returns');

can_ok($net2, 'learn_rate');
is(sprintf("%.1f", $net2->learn_rate), "0.2", '... and it should have the correct learn rate');
isa_ok($net2->learn_rate(.3), $CLASS => '... and setting it should return the object');
is(sprintf("%.1f", $net2->learn_rate), "0.3", '... and should set it correctly');
$net2->learn_rate(.2);



( run in 0.670 second using v1.01-cache-2.11-cpan-de7293f3b23 )