AI-ML

 view release on metacpan or  search on metacpan

lib/AI/ML/NeuralNetwork.pm  view on Meta::CPAN

		$i++;
	}
	$self->load_weights_bias();
		
	$self->{n} 	    = exists $opts{n}     ? $opts{n}     : 100;
    $self->{alpha} 	= exists $opts{alpha} ? $opts{alpha} : 0.1;
	$self->{reg}    = exists $opts{reg}   ? $opts{reg}   : undef;
    $self->{cost} 	= exists $opts{cost}  ? $opts{cost}  : undef;
    $self->{plot} 	= exists $opts{plot}  ? $opts{plot}  : undef;
	return $self;
}


=head2 load_weights_bias

=cut
sub load_weights_bias {
	my ($self) = @_;
	my $size = keys %$self;
	$self->{layers} = $size;
	for my $i ( 1 .. $size-1 ) {
		my $j = $i - 1;
		$self->{"l$i"}{w} = Math::Lapack::Matrix->random($self->{"l$i"}{units}, $self->{"l$j"}{units});
		$self->{"l$i"}{b} = Math::Lapack::Matrix->zeros($self->{"l$i"}{units}, 1);
	}
}


=head2 train

=cut
sub train {
	my ($self, $x, $y, %opts) = @_;
	my $m = $x->columns;
	my $layers = $self->{layers};

	die "Wrong number of units in input layer" 	if ( $x->rows != $self->{"l0"}{units} );
	die "Wrong number of units in output layer" if ( $y->rows != $self->{"l".($layers-1)}{units} );

	my $var = { A0 => $x };

	my $iters     = $self->{n};
    my $alpha     = $self->{alpha};

	my ($rows, $cols, $cost);

	for my $iter (1 .. $iters) {
		my $aux;
		# forward propagation
		my ($i,$j);
		for ( 1 .. $layers-1){
			$i = $_;
			$j = $i - 1;
			$var->{"Z$i"} = $self->{"l$i"}{w} x $var->{"A$j"} + $self->{"l$i"}{b};
			$var->{"A$i"} = $functions->{ $self->{"l$i"}{func} }->($var->{"Z$i"});
			$i++;
		}
		$i--;

        if ($iter % 1000 == 0){
        	$cost = (-1 / $m)*sum(($y * log($var->{"A$i"})) + ((1-$y) * log(1-$var->{"A$i"})));
            $cost = $cost->get_element(0,0);
        }
		#
		## back propagation
		$var->{"dz$i"} = $var->{"A$i"} - $y;
		$aux = $var->{"dz$i"};
        #$aux->save_csv("/tmp/DZ$i.csv");

		$var->{"dw$i"} = (1 / $m) * ( $var->{"dz$i"} x T($var->{"A$j"}) );
		$var->{"db$i"} = (1 / $m) * sum( $var->{"dz$i"} , 0 );
		$var->{"da$j"} = T($self->{"l$i"}{w}) x $var->{"dz$i"};

        $self->{"l$i"}{w} = $self->{"l$i"}{w} - ( $alpha * $var->{"dw$i"} );
		$self->{"l$i"}{b} = $self->{"l$i"}{b} - ( $alpha * $var->{"db$i"} );

        $self->{"l$i"}{b}->get_element(0,0); #force eval
        $self->{"l$i"}{w}->get_element(0,0);

        if($iter == 100){
            $aux = $var->{"dw$i"};
            #$aux->save_csv("/tmp/DW$i.csv");
            $aux = $var->{"db$i"};
            #$aux->save_csv("/tmp/DB$i.csv");
            $aux = $var->{"da$j"};
            #$aux->save_csv("/tmp/da$j.m");

            $aux = $self->{"l$i"}{w};
            #$aux->save_csv("/tmp/W$i.csv");
            $aux = $self->{"l$i"}{b};
            #$aux->save_csv("/tmp/B$i.csv");
        }

		##print STDERR Dumper($self,$var);
		##
		$i--;$j--;
		for(; $j >= 0; $i--, $j--) {
			#print STDERR "Iter: $i\n";

			$var->{"dz$i"} = $var->{"da$i"} * $functions->{ $self->{"l$i"}{dfunc} }->($var->{"Z$i"}) ;
			$var->{"dw$i"} = (1 / $m) * ( $var->{"dz$i"} x T($var->{"A$j"}) );
			$var->{"db$i"} = (1 / $m) * sum( $var->{"dz$i"} , 0 );
			$var->{"da$j"} = T($self->{"l$i"}{w}) x $var->{"dz$i"} if $j >= 1;

            $self->{"l$i"}{w} = $self->{"l$i"}{w} - ( $alpha * $var->{"dw$i"} ); 
			$self->{"l$i"}{b} = $self->{"l$i"}{b} - ( $alpha * $var->{"db$i"} ); 


            if($iter == 100){
                $aux = $var->{"dz$i"};
                #$aux->save_csv("/tmp/DZ$i.csv");
                $aux = $var->{"dw$i"};
                #$aux->save_csv("/tmp/DW$i.csv");
                $aux = $var->{"db$i"};
                #$aux->save_csv("/tmp/DB$i.csv");
                #if ($j>=1){$aux = $var->{"da$j"};
                #$aux->save_csv("/tmp/da$j.m");}

                $aux = $self->{"l$i"}{w};
                #$aux->save_csv("/tmp/W$i.csv");
                $aux = $self->{"l$i"}{b};



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