AI-NeuralNet-Simple
view release on metacpan or search on metacpan
if (!c_create_network(n))
return -1;
/* Perl already seeded the random number generator, via a rand(1) call */
c_assign_random_weights(n);
return handle;
}
double c_train_set(int handle, SV* set, int iterations, double mse)
{
NEURAL_NETWORK *n = c_get_network(handle);
AV *input_array, *output_array; /* perl arrays */
double *input, *output; /* C arrays */
double max_error = 0.0;
int set_length=0;
int i,j;
int index;
output_array = get_array_from_aoa(set, i+1);
if (av_len(output_array)+1 != n->size.output)
croak("Length of output data does not match");
for (j = 0; j < n->size.output; j++) {
index = (i/2*n->size.output)+j;
output[index] = get_float_element(output_array, j);
}
}
for (i = 0; i < iterations; i++) {
max_error = 0.0;
for (j = 0; j < (set_length/2); j++) {
double error;
c_feed(n, &input[j*n->size.input], &output[j*n->size.output], 1);
if (mse >= 0.0 || i == iterations - 1) {
error = mean_square_error(n, &output[j*n->size.output]);
if (error > max_error)
max_error = error;
}
}
if (mse >= 0 && max_error <= mse) /* Below their target! */
break;
}
SV * input
SV * output
int
c_new_network (input, hidden, output)
int input
int hidden
int output
double
c_train_set (handle, set, iterations, mse)
int handle
SV * set
int iterations
double mse
SV *
c_infer (handle, array_ref)
int handle
SV * array_ref
examples/game_ai.pl view on Meta::CPAN
use constant HIDE => [0.0, 0.0, 0.0, 1.0];
use constant GOOD => 2.0;
use constant AVERAGE => 1.0;
use constant POOR => 0.0;
use constant YES => 1.0;
use constant NO => 0.0;
my $net = AI::NeuralNet::Simple->new(4,20,4);
$net->iterations(shift || 100000);
$net->train_set( [
# health knife gun enemy
[GOOD, YES, YES, 0], WANDER,
[GOOD, YES, NO, 2], HIDE,
[GOOD, YES, NO, 1], ATTACK,
[GOOD, YES, NO, 0], WANDER,
[GOOD, NO, YES, 2], ATTACK,
[GOOD, NO, YES, 1], ATTACK,
[GOOD, NO, NO, 3], HIDE,
[GOOD, NO, NO, 2], HIDE,
lib/AI/NeuralNet/Simple.pm view on Meta::CPAN
}
my $seed = rand(1); # Perl invokes srand() on first call to rand()
my $handle = c_new_network(@args);
logdie "could not create new network" unless $handle >= 0;
my $self = bless {
input => $args[0],
hidden => $args[1],
output => $args[2],
handle => $handle,
}, $class;
$self->iterations(10000); # set a reasonable default
}
sub train {
my ( $self, $inputref, $outputref ) = @_;
return c_train( $self->handle, $inputref, $outputref );
}
sub train_set {
my ( $self, $set, $iterations, $mse ) = @_;
$iterations ||= $self->iterations;
$mse = -1.0 unless defined $mse;
return c_train_set( $self->handle, $set, $iterations, $mse );
}
sub iterations {
my ( $self, $iterations ) = @_;
if ( defined $iterations ) {
logdie "iterations() value must be a positive integer."
unless $iterations
and $iterations =~ /^\d+$/;
$self->{iterations} = $iterations;
return $self;
}
$self->{iterations};
}
sub delta {
my ( $self, $delta ) = @_;
return c_get_delta( $self->handle ) unless defined $delta;
logdie "delta() value must be a positive number" unless $delta > 0.0;
c_set_delta( $self->handle, $delta );
return $self;
}
lib/AI/NeuralNet/Simple.pm view on Meta::CPAN
$net->train([0,0] => [1,0]);
}
The routine returns the Mean Squared Error (MSE) representing how far the
network answered.
It is far preferable to use C<train_set()> as this lets you control the MSE
over the training set and it is more efficient because there are less memory
copies back and forth.
=head2 C<train_set(\@dataset, [$iterations, $mse])>
Similar to train, this method allows us to train an entire data set at once.
It is typically faster than calling individual "train" methods. The first
argument is expected to be an array ref of pairs of input and output array
refs.
The second argument is the number of iterations to train the set. If
this argument is not provided here, you may use the C<iterations()> method to
set it (prior to calling C<train_set()>, of course). A default of 10,000 will
be provided if not set.
The third argument is the targeted Mean Square Error (MSE). When provided,
the traning sequence will compute the maximum MSE seen during an iteration
over the training set, and if it is less than the supplied target, the
training stops. Computing the MSE at each iteration costs, but you are
certain to not over-train your network.
$net->train_set([
[1,1] => [0,1],
[1,0] => [0,1],
[0,1] => [0,1],
[0,0] => [1,0],
], 10000, 0.01);
The routine returns the MSE of the last iteration, which is the highest MSE
seen over the whole training set (and not an average MSE).
=head2 C<iterations([$integer])>
If called with a positive integer argument, this method will allow you to set
number of iterations that train_set will use and will return the network
object. If called without an argument, it will return the number of iterations
it was set to.
$net->iterations; # returns 100000
my @training_data = (
[1,1] => [0,1],
[1,0] => [0,1],
[0,1] => [0,1],
[0,0] => [1,0],
);
$net->iterations(100000) # let's have lots more iterations!
->train_set(\@training_data);
=head2 C<learn_rate($rate)>)
This method, if called without an argument, will return the current learning
rate. .20 is the default learning rate.
If called with an argument, this argument must be greater than zero and less
than one. This will set the learning rate and return the object.
$net->learn_rate; #returns the learning rate
$net->learn_rate(.1)
->iterations(100000)
->train_set(\@training_data);
If you choose a lower learning rate, you will train the network slower, but you
may get a better accuracy. A higher learning rate will train the network
faster, but it can have a tendancy to "overshoot" the answer when learning and
not learn as accurately.
=head2 C<infer(\@input)>
This method, if provided with an input array reference, will return an array
( run in 0.828 second using v1.01-cache-2.11-cpan-96521ef73a4 )