AI-NeuralNet-Simple
view release on metacpan or search on metacpan
lib/AI/NeuralNet/Simple.pm view on Meta::CPAN
my ( $self, $cloning, $x, $copy, $internal ) = @_;
%$self = %$copy;
$self->{handle} = c_import_network($internal);
}
1;
__END__
=head1 NAME
AI::NeuralNet::Simple - An easy to use backprop neural net.
=head1 SYNOPSIS
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
=head2 The Disclaimer
Please note that the following information is terribly incomplete. That's
deliberate. Anyone familiar with neural networks is going to laugh themselves
silly at how simplistic the following information is and the astute reader will
notice that I've raised far more questions than I've answered.
So why am I doing this? Because I'm giving I<just enough> information for
someone new to neural networks to have enough of an idea of what's going on so
they can actually use this module and then move on to something more powerful,
if interested.
=head2 The Biology
A neural network, at its simplest, is merely an attempt to mimic nature's
"design" of a brain. Like many successful ventures in the field of artificial
intelligence, we find that blatantly ripping off natural designs has allowed us
to solve many problems that otherwise might prove intractable. Fortunately,
Mother Nature has not chosen to apply for patents.
Our brains are comprised of neurons connected to one another by axons. The
axon makes the actual connection to a neuron via a synapse. When neurons
receive information, they process it and feed this information to other neurons
who in turn process the information and send it further until eventually
commands are sent to various parts of the body and muscles twitch, emotions are
felt and we start eyeing our neighbor's popcorn in the movie theater, wondering
if they'll notice if we snatch some while they're watching the movie.
=head2 A simple example of a neuron
Now that you have a solid biology background (uh, no), how does this work when
we're trying to simulate a neural network? The simplest part of the network is
the neuron (also known as a node or, sometimes, a neurode). A we might think
of a neuron as follows (OK, so I won't make a living as an ASCII artist):
Input neurons Synapses Neuron Output
----
n1 ---w1----> / \
n2 ---w2---->| n4 |---w4---->
n3 ---w3----> \ /
----
(Note that the above doesn't quite match what's in the C code for this module,
but it's close enough for you to get the idea. This is one of the many
oversimplifications that have been made).
In the above example, we have three input neurons (n1, n2, and n3). These
neurons feed whatever output they have through the three synapses (w1, w2, w3)
to the neuron in question, n4. The three synapses each have a "weight", which
is an amount that the input neurons' output is multiplied by.
The neuron n4 computes its output with something similar to the following:
output = 0
foreach (input.neuron)
output += input.neuron.output * input.neuron.synapse.weight
ouput = activation_function(output)
The "activation function" is a special function that is applied to the inputs
to generate the actual output. There are a variety of activation functions
available with three of the most common being the linear, sigmoid, and tahn
activation functions. For technical reasons, the linear activation function
cannot be used with the type of network that C<AI::NeuralNet::Simple> employs.
This module uses the sigmoid activation function. (More information about
these can be found by reading the information in the L<SEE ALSO> section or by
just searching with Google.)
Once the activation function is applied, the output is then sent through the
next synapse, where it will be multiplied by w4 and the process will continue.
=head2 C<AI::NeuralNet::Simple> architecture
The architecture used by this module has (at present) 3 fixed layers of
neurons: an input, hidden, and output layer. In practice, a 3 layer network is
applicable to many problems for which a neural network is appropriate, but this
is not always the case. In this module, we've settled on a fixed 3 layer
network for simplicity.
Here's how a three layer network might learn "logical or". First, we need to
determine how many inputs and outputs we'll have. The inputs are simple, we'll
choose two inputs as this is the minimum necessary to teach a network this
concept. For the outputs, we'll also choose two neurons, with the neuron with
the highest output value being the "true" or "false" response that we are
looking for. We'll only have one neuron for the hidden layer. Thus, we get a
network that resembles the following:
Input Hidden Output
input1 ----> n1 -+ +----> n4 ---> output1
\ /
n3
/ \
input2 ----> n2 -+ +----> n5 ---> output2
Let's say that output 1 will correspond to "false" and output 2 will correspond
to true. If we feed 1 (or true) or both input 1 and input 2, we hope that output
2 will be true and output 1 will be false. The following table should illustrate
the expected results:
input output
1 2 1 2
----- ------
1 1 0 1
1 0 0 1
0 1 0 1
0 0 1 0
The type of network we use is a forward-feed back error propagation network,
referred to as a back-propagation network, for short. The way it works is
simple. When we feed in our input, it travels from the input to hidden layers
and then to the output layers. This is the "feed forward" part. We then
compare the output to the expected results and measure how far off we are. We
then adjust the weights on the "output to hidden" synapses, measure the error
on the hidden nodes and then adjust the weights on the "hidden to input"
synapses. This is what is referred to as "back error propagation".
We continue this process until the amount of error is small enough that we are
satisfied. In reality, we will rarely if ever get precise results from the
network, but we learn various strategies to interpret the results. In the
example above, we use a "winner takes all" strategy. Which ever of the output
nodes has the greatest value will be the "winner", and thus the answer.
In the examples directory, you will find a program named "logical_or.pl" which
demonstrates the above process.
=head2 Building a network
In creating a new neural network, there are three basic steps:
=over 4
=item 1 Designing
This is choosing the number of layers and the number of neurons per layer. In
C<AI::NeuralNet::Simple>, the number of layers is fixed.
With more complete neural net packages, you can also pick which activation
functions you wish to use and the "learn rate" of the neurons.
=item 2 Training
This involves feeding the neural network enough data until the error rate is
low enough to be acceptable. Often we have a large data set and merely keep
iterating until the desired error rate is achieved.
=item 3 Measuring results
One frequent mistake made with neural networks is failing to test the network
with different data from the training data. It's quite possible for a
backpropagation network to hit what is known as a "local minimum" which is not
truly where it should be. This will cause false results. To check for this,
after training we often feed in other known good data for verification. If the
results are not satisfactory, perhaps a different number of neurons per layer
should be tried or a different set of training data should be supplied.
=back
=head1 Programming C<AI::NeuralNet::Simple>
=head2 C<new($input, $hidden, $output)>
C<new()> accepts three integers. These number represent the number of nodes in
the input, hidden, and output layers, respectively. To create the "logical or"
network described earlier:
my $net = AI::NeuralNet::Simple->new(2,1,2);
By default, the activation function for the neurons is the sigmoid function
S() with delta = 1:
S(x) = 1 / (1 + exp(-delta * x))
but you can change the delta after creation. You can also use a bipolar
activation function T(), using the hyperbolic tangent:
T(x) = tanh(delta * x)
tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
which allows the network to have neurons negatively impacting the weight,
since T() is a signed function between (-1,+1) whereas S() only falls
within (0,1).
=head2 C<delta($delta)>
( run in 0.672 second using v1.01-cache-2.11-cpan-9581c071862 )