AI-NeuralNet-Mesh

 view release on metacpan or  search on metacpan

mesh.htm  view on Meta::CPAN

<P>Let's look at the code real quick, as it shows how to get at the indivudal
input connections:</P>
<PRE>
        = line 1 =      sub {
        = line 2 =              my $sum  = shift;
        = line 3 =              my $self = shift;
        = line 4 =              my $threshold = 0.50;
        = line 5 =              for my $x (0..$self-&gt;{_inputs_size}-1) { 
        = line 6 =                      return 0.000001 if(!$self-&gt;{_inputs}-&gt;[$x]-&gt;{value}&lt;$threshold)
        = line 7 =              }
        = line 8 =              return $sum/$self-&gt;{_inputs_size};
        = line 9 =      }</PRE>
<P>Line 2 and 3 pulls in our sum and self refrence. Line 5 opens a loop to go over
all the input lines into this node. Line 6 looks at each input line's value 
and comparse it to the threshold. If the value of that line is below threshold, then
we return 0.000001 to signify a 0 value. (We don't return a 0 value so that the network
doen't get hung trying to multiply a 0 by a huge weight during training [it just will
keep getting a 0 as the product, and it will never learn]). Line 8 returns the mean 
value of all the inputs if all inputs were above threshold.</P>
<P>Very simple, eh? :)
</P>
<P></P>
<DT><STRONG><A NAME="item_or_gate">or_gate($threshold);</A></STRONG><BR>
<DD>
<P>Self explanitory. Turns the node into a basic OR gate, $threshold is used same as above.</P>
<P>You can get this into your namespace with the ':acts' export 
tag as so:
</P>
<PRE>
        use AI::NeuralNet::Mesh ':acts';</PRE>
<P></P></DL>
<P>
<HR>
<H1><A NAME="variables">VARIABLES</A></H1>
<DL>
<DT><STRONG><A NAME="item_%24AI%3A%3ANeuralNet%3A%3AMesh%3A%3AConnector">$AI::NeuralNet::Mesh::Connector</A></STRONG><BR>
<DD>
This is an option is step up from average use of this module. This variable 
should hold the fully qualified name of the function used to make the actual connections
between the nodes in the network. This contains '_c' by default, but if you use
this variable, be sure to add the fully qualified name of the method. For example,
in the ALN example, I use a connector in the main package called <CODE>tree()</CODE> instead of
the default connector. Before I call the <A HREF="#item_new"><CODE>new()</CODE></A> constructor, I use this line of code:
<PRE>
        $AI::NeuralNet::Mesh::Connector = 'main::tree'
</PRE>
<P>The tree() function is called as a blessed method when it is used internally, providing
access to the bless refrence in the first argument. See notes on CUSTOM NETWORK CONNECTORS,
below, for more information on creating your own custom connector.</P>
<P></P>
<DT><STRONG><A NAME="item_%24AI%3A%3ANeuralNet%3A%3AMesh%3A%3ADEBUG">$AI::NeuralNet::Mesh::DEBUG</A></STRONG><BR>
<DD>
This variable controls the verbosity level. It will not hurt anything to set this 
directly, yet most people find it easier to set it using the <A HREF="#item_debug"><CODE>debug()</CODE></A> method, or 
any of its aliases.
<P></P></DL>
<P>
<HR>
<H1><A NAME="custom network connectors">CUSTOM NETWORK CONNECTORS</A></H1>
<P>Creating custom network connectors is step up from average use of this module. 
However, it can be very useful in creating other styles of neural networks, other
than the default fully-connected feed-foward network.</P>
<P>You create a custom connector by setting the variable $AI::NeuralNet::Mesh::Connector
to the fully qualified name of the function used to make the actual connections
between the nodes in the network. This variable contains '_c' by default, but if you use
this variable, be sure to add the fully qualified name of the method. For example,
in the ALN example, I use a connector in the main package called <CODE>tree()</CODE> instead of
the default connector. Before I call the <A HREF="#item_new"><CODE>new()</CODE></A> constructor, I use this line of code:</P>
<PRE>
        $AI::NeuralNet::Mesh::Connector = 'main::tree'
</PRE>
<P>The tree() function is called as a blessed method when it is used internally, providing
access to the bless refrence in the first argument.</P>
<P>Example connector:</P>
<PRE>
        sub connect_three {
        my $self        =       shift;
        my $r1a         =       shift;
        my $r1b         =       shift;
        my $r2a         =       shift;
        my $r2b         =       shift;
        my $mesh        =       $self-&gt;{mesh};

            for my $y (0..($r1b-$r1a)-1) {
                        $mesh-&gt;[$y+$r1a]-&gt;add_output_node($mesh-&gt;[$y+$r2a-1]) if($y&gt;0);
                        $mesh-&gt;[$y+$r1a]-&gt;add_output_node($mesh-&gt;[$y+$r2a]) if($y&lt;($r2b-$r2a));
                        $mesh-&gt;[$y+$r1a]-&gt;add_output_node($mesh-&gt;[$y+$r2a+1]) if($y&lt;($r2b-$r2a));
                }
        }</PRE>
<P>This is a very simple example. It feeds the outputs     of every node in the first layer
to the node directly above it, as well as the nodes on either side of the node directly
above it, checking for range sides, of course.</P>
<P>The network is stored internally as one long array of node objects. The goal here
is to connect one range of nodes in that array to another range of nodes. The calling
function has already calculated the indices into the array, and it passed it to you
as the four arguments after the $self refrence. The first two arguments we will call
$r1a and $r1b. These define the start and end indices of the first range, or ``layer.'' Likewise,
the next two arguemnts, $r2a and $r2b, define the start and end indices of the second
layer. We also grab a refrence to the mesh array so we dont have to type the $self
refrence over and over.</P>
<P>The loop that folows the arguments in the above example is very simple. It opens
a <CODE>for()</CODE> loop over the range of numbers, calculating the size instead of just going
$r1a..$r1b because we use the loop index with the next layer up as well.</P>
<P>$y + $r1a give the index into the mesh array of the current node to connect the output FROM.
We need to connect this nodes output lines to the next layers input nodes. We do this
with a simple method of the outputing node (the node at $y+$r1a), called add_output_node().</P>
<P><CODE>add_output_node()</CODE> takes one simple arguemnt: A blessed refrence to a node that it is supposed
to output its final value TO. We get this blessed refrence with more simple addition.</P>
<P>$y + $r2a gives us the node directly above the first node (supposedly...I'll get to the ``supposedly''
part in a minute.) By adding or subtracting from this number we get the neighbor nodes.
In the above example you can see we check the $y index to see that we havn't come close to
any of the edges of the range.</P>
<P>Using $y+$r2a we get the index of the node to pass to <CODE>add_output_node()</CODE> on the first node at
$y+<STRONG>$r1a</STRONG>.</P>
<P>And that's all there is to it!</P>
<P>For the fun of it, we'll take a quick look at the default connector.
Below is the actual default connector code, albeit a bit cleaned up, as well as
line numbers added.</P>
<PRE>
        = line 1  =     sub _c {
        = line 2  =     my $self        =       shift;



( run in 1.340 second using v1.01-cache-2.11-cpan-39bf76dae61 )