AI-NNFlex
view release on metacpan or search on metacpan
lib/AI/NNFlex.pm view on Meta::CPAN
my $weight = $network->calcweight;
push @{$node->{'connectedNodesEast'}->{'nodes'}},$eastNodes;
push @{$node->{'connectedNodesEast'}->{'weights'}}, $weight;
if (scalar @debug > 0)
{$network->dbug ("East to west Connection ".$node->{'nodeid'}." to ".$eastNodes->{'nodeid'},2);}
}
}
}
$nodeid++;
}
$currentLayer++;
}
# add bias node to westerly connections
if ($network->{'bias'})
{
foreach my $layer (@{$network->{'layers'}})
{
foreach my $node (@{$layer->{'nodes'}})
{
push @{$node->{'connectedNodesWest'}->{'nodes'}},$network->{'biasnode'};
my $weight = $network->calcweight;
push @{$node->{'connectedNodesWest'}->{'weights'}},$weight;
if (scalar @debug > 0)
{$network->dbug ("West to east Connection - bias to ".$node->{'nodeid'}." weight = $weight",2);}
}
}
}
return 1; # return success if we get to here
}
###############################################################################
# sub $network->dbug
###############################################################################
sub dbug
{
my $network = shift;
my $message = shift;
my $level = shift;
my @DEBUGLEVELS;
# cover for debug calls before the network is created
if (!$network->{'debug'})
{
@DEBUGLEVELS=@DEBUG;
}
else
{
@DEBUGLEVELS = @{$network->{'debug'}};
}
# 0 is error so ALWAYS display
if (!(grep /0/,@DEBUGLEVELS)){push @DEBUGLEVELS,0}
foreach (@DEBUGLEVELS)
{
if ($level == $_)
{
print "$message\n";
}
}
}
###############################################################################
# AI::NNFlex::dump_state
###############################################################################
sub dump_state
{
my $network = shift;
my %params =@_;
my $filename = $params{'filename'};
my $activations = $params{'activations'};
open (OFILE,">$filename") or return "Can't create weights file $filename";
foreach my $layer (@{$network->{'layers'}})
{
foreach my $node (@{$layer->{'nodes'}})
{
if ($activations)
{
print OFILE $node->{'nodeid'}." activation = ".$node->{'activation'}."\n";
}
my $connectedNodeCounter=0;
foreach my $connectedNode (@{$node->{'connectedNodesEast'}->{'nodes'}})
{
my $weight = ${$node->{'connectedNodesEast'}->{'weights'}}[$connectedNodeCounter];
print OFILE $node->{'nodeid'}." <- ".$connectedNode->{'nodeid'}." = ".$weight."\n";
$connectedNodeCounter++;
}
if ($node->{'connectedNodesWest'})
{
my $connectedNodeCounter=0;
foreach my $connectedNode (@{$node->{'connectedNodesWest'}->{'nodes'}})
{
#FIXME - a more easily read format would be connectedNode first in the file
my $weight = ${$node->{'connectedNodesWest'}->{'weights'}}[$connectedNodeCounter];
print OFILE $node->{'nodeid'}." -> ".$connectedNode->{'nodeid'}." = ".$weight."\n";
}
}
}
}
lib/AI/NNFlex.pm view on Meta::CPAN
sub lesion
{
my $layer = shift;
my %params = @_;
my $return;
my $nodeLesion = $params{'nodes'};
my $connectionLesion = $params{'connections'};
# go through the layers & node inactivating random nodes according
# to probability
foreach my $node (@{$layer->{'nodes'}})
{
$return = $node->lesion(%params);
}
return $return;
}
###############################################################################
###############################################################################
# package AI::NNFlex::node
###############################################################################
###############################################################################
package AI::NNFlex::node;
###############################################################################
# AI::NNFlex::node::new
###############################################################################
sub new
{
my $class = shift;
my $params = shift;
my $node = {};
foreach (keys %{$params})
{
$$node{$_} = $$params{$_}
}
if ($$params{'randomactivation'})
{
$$node{'activation'} =
rand($$params{'random'});
AI::NNFlex::dbug($params,"Randomly activated at ".$$node{'activation'},2);
}
else
{
$$node{'activation'} = 0;
}
$$node{'active'} = 1;
$$node{'error'} = 0;
bless $node,$class;
AI::NNFlex::dbug($params,"Created node $node",2);
return $node;
}
##############################################################################
# sub lesion
##############################################################################
sub lesion
{
my $node = shift;
my %params = @_;
my $nodeLesion = $params{'nodes'};
my $connectionLesion = $params{'connections'};
# go through the layers & node inactivating random nodes according
# to probability
if ($nodeLesion)
{
my $probability = rand(1);
if ($probability < $nodeLesion)
{
$node->{'active'} = 0;
}
}
if ($connectionLesion)
{
# init works from west to east, so we should here too
my $nodeCounter=0;
foreach my $connectedNode (@{$node->{'connectedNodesEast'}->{'nodes'}})
{
my $probability = rand(1);
if ($probability < $connectionLesion)
{
my $reverseNodeCounter=0; # maybe should have done this differntly in init, but 2 late now!
${$node->{'connectedNodesEast'}->{'nodes'}}[$nodeCounter] = undef;
foreach my $reverseConnection (@{$connectedNode->{'connectedNodesWest'}->{'nodes'}})
{
if ($reverseConnection == $node)
{
${$connectedNode->{'connectedNodesEast'}->{'nodes'}}[$reverseNodeCounter] = undef;
}
$reverseNodeCounter++;
}
}
$nodeCounter++;
}
}
( run in 0.724 second using v1.01-cache-2.11-cpan-39bf76dae61 )