Feed Forward Artificial Neural Network written in PHP

Download a copy of the source code here

#!/usr/bin/php -Cq
<?php
/**
 * neuralPHP1 j0zf 2011.6.2
 * (c) Copyright 2011 by j0zf, Joseph D. Frazier, All rights reserved
 * May be used for educational purposes only
 * All copies of this code, all or in part, must give proper credit to the original author "j0zf"
 *
 */

error_reporting(-1);

if ( count($argv)<2) {
	exit ("Usage: neuralPHP1 [Numerical Input Vector Values]\n");
}

$I = $argv;
array_shift($I); // read in the input vector from the command line arguments

$NN = new C_nn();
$NN->generate( count($I), 3, 1 );  // Generate a ARGC by 3 by 1 Neural Network Value Matrix
$O = $NN->evaluate( $I );

echo "-- Input Vecotor --\n" . print_r( $I, true ) . "\n";
echo "-- Neural Net Value Matrix --\n" . print_r( $NN->V, true ) . "\n";
echo "-- Output Vector --\n" . print_r( $O, true ) . "\n";


/**
 * MAKE COMBINED WEIGHT AND VALUE MATRIX
 */
class C_nn
{
	var $W; // jagged 3d weight matrix
	var $V; // jagged 2d value matrix
	var $O; // output vector
	var $normalize_flag = false;
	
	/**
	 * GENERATE WEIGHT AND VALUE MATRICIES
	 * $vector_len[] is a list of the lengths of the value matrix where the first is the input vector len, and the last is the output vector len
	 */
	function generate( /* $vector_len[0], $vector_len[1], ... */ )
	{
		$vector_len = func_get_args();
		for ( $layer_i=0; $layer_i<count($vector_len); $layer_i++ ) {
			// Generate the "value vector" at this layer 
			for ( $value_i=0; $value_i<$vector_len[$layer_i]; $value_i++ ) { 
				$this->V[$layer_i][$value_i] = 0.0;
			}
			
			// Generate the Weights between the last "value vector" and the current "value vector"
			// on layer 0, just do the Input Vecotor, i.e. the first layer to our value matrix
			// note the first column (index 0) of the Weight Matrix is the weights between Value Column 0 and Value Column 1
			if ( $layer_i > 0 ) { 
				for ( $value_i=0; $value_i<$vector_len[$layer_i]; $value_i++ ) { 
					for ( $weight_i=0; $weight_i < $vector_len[$layer_i-1]; $weight_i++ ) { 
						$this->W[$layer_i-1][$value_i][$weight_i] = $this->fuzz();
					}
				}
			} 
		}
	}

	function fuzz()
	{
		return floatval(mt_rand( -1 * mt_getrandmax(), mt_getrandmax())) / floatval(mt_getrandmax());
	}

	function evaluate( $I = array() )
	{
		$O = array();
		$imin = min($I); 
		$imax = max($I); 

		// ASSIGN THE INPUT VECTOR TO THE FIRST COLUMN OF THE VALUE MATRIX
		// normalize the vector as it's added as the first vector of the value matrix
		//  I[i] - imin
		//  -----------    =  V[0][i]
		//  imax - imin
		for ($i=0; $i<count($I); $i++) {
			$denominator = $imax - $imin;
			if ( !$this->normalize_flag ) {
				$this->V[0][$i] = $I[$i];
			} elseif ( $denominator != 0 ) {
				$this->V[0][$i] = ( ( $I[$i] - $imin ) / ( $denominator ) );
			} else {
				$this->V[0][$i] = 0;
			}
		}

		// EVALUATE THE NEURAL NETWORK STRUCTURE
		for ( $layer_i=1; $layer_i < count($this->V); $layer_i++ ) {
			for ( $value_i=0; $value_i < count($this->V[$layer_i]); $value_i++ ) { 
				$sum = 0;
				for ( $weight_i=0; $weight_i < count($this->W[$layer_i-1][$value_i]); $weight_i++ ) { 
					$sum += ($this->V[$layer_i-1][$weight_i]) * ($this->W[$layer_i-1][$value_i][$weight_i]);
				}
				$this->V[$layer_i][$value_i] = $this->activation($sum);
			}
		}

		// GET THE OUTPUT VECTOR BY PASSING A THRESHOLD OVER THE LAST COLUMN OF THE VALUE MATRIX
		for ( $value_i=0; $value_i < count($this->V[count($this->V)-1]); $value_i++ ) {
			$this->O[$value_i] = $this->V[count($this->V)-1][$value_i];  // raw activation output values in the class output vector
			$O[$value_i] = $this->threshold( $this->V[count($this->V)-1][$value_i] ); // threshhold filtered output values in returned output vector
		}

		return $O;
	}

	function activation($x)
	{
		// The sigmoid function
		return ( 1.0 / ( 1.0 + exp( -1.0 * $x ) ) );
	}

	function threshold($v)
	{
		if ( is_array($v) ) {
			for($vi=0; $vi<count($v); $vi++) {
				$v[$vi] = ( $v[$vi] < 0.5 ? 0 : 1 );
			}
		} else {
			$v = ( $v < 0.5 ? 0 : 1 );
		}
		return $v;
	}

}




?>
Joseph Frazier | Create Your Badge

This page has been visited 4,442 times since June 09th, 2011

This is an ApogeeInvent Dynamic Website