EihiS

September 27, 2015

Neuron networks , part III

Filed under: Uncategorized, linux — Tags: , , , , , , — admin @ 8:46 am

the NEU.c header looks like:

// activate extra computation : NE_outPulse[] mode
#define _NEU_USES_PULSES_OUTPUTS
// activate extra computation : NE_outTrigger[], schmidt trigger tanh'd output
#define _NEU_USES_ASYMETRIC_OUTPUTS
//
#define _neu_asym_magnify 200.0//2.0 // 8.0  is default , schm-trig amplifier for tanh
#define _neu_asym_value 0.1 //  default 0.1 , scm-trig 'delta' from 0 , rising/falling. 0.1 : schmidt trig asymetry
#define _neu_asym_rescale (float) (( (float) _neu_asym_magnify+ (float) _neu_asym_magnify + (float) _neu_asym_value) / (float) (_neu_asym_magnify) )
//
// Hidden and output neurons (post) modes
//
#define _NEU_USES_TANH_HIDDEN
#define _NEU_USES_TANH_OUTPUT
// learning rates
#define _NEU_INITIAL_LR_HO (float)0.08
#define _NEU_INITIAL_LR_IH (float)0.008
// we use some globals :
int NE_numInputs;   //  define howmuch inputs
int NE_numPatterns; // howmuch patterns for learning if a set is created
int NE_numHidden;   // hidden layer neuron number
int NE_numOutputs;  // output layer neuron quantity
int NE_numEpochs;   // used to count learning epochs (convergence)
//
// NEU variables
int NE_patNum = 0;
double NE_errThisPat[_max_outputs];
double NE_outPred[_max_outputs];
// asymetrics
#ifdef _NEU_USES_ASYMETRIC_OUTPUTS
double NE_last_outPred[_max_outputs];	// for last state saves
double NE_outTrigger[_max_outputs];
#endif
// pulsed mode output (another , alternate , output mode)
#ifdef _NEU_USES_PULSES_OUTPUTS
double  NE_outPredPulsed[_max_outputs];
double NE_outPulse[_max_outputs];
double NE_outPeriod[_max_outputs];
#endif
//
double NE_RMSerror[_max_outputs];
double NE_bias_value = 0.0 ;	// variable bias - used for 1 of the inputs
//
double hiddenVal[_max_hidden];	// mximum hidden neuron count
double hiddenPulse[_max_hidden];
double hiddenPeriod[_max_hidden];
//
double weightsIH[_max_inputs][_max_hidden];
double weightsHO[_max_hidden][_max_outputs];
//
double trainInputs[_max_patterns+1][_max_inputs];
double trainOutput[_max_patterns][_max_outputs];
//

And the CalcNet() function ( heavy optimizations could be applied ) .btw, sorry for the bad identations (blog’s content editor is not good at this )

// calculates the network output : you setup NE_patNum. trainOutputs have to be set only if
// in learning mode, to calculate errors.
void NEU_calcNet(void)
{
    //
    int j,k;
    int i = 0;
    for(i = 0;i<NE_numHidden;i++)
    {
  hiddenVal[i] = 0.0;
  //
for(j = 0;j<NE_numInputs;j++)
{
if(trainInputs[NE_patNum][j]>1.0) trainInputs[NE_patNum][j]=1.0;
if(trainInputs[NE_patNum][j]<-1.0) trainInputs[NE_patNum][j]=-1.0;
hiddenVal[i] = hiddenVal[i] + (trainInputs[NE_patNum][j] * weightsIH[j][i]);
}
// uses tanh'd mode ?
#ifdef _NEU_USES_TANH_HIDDEN
hiddenVal[i] = tanh(hiddenVal[i]); // hidden state is tanh'd
#endif
// uses pulsed mode?
#ifdef _NEU_USES_PULSES_OUTPUTS
if((hiddenPulse[i]>-0.001)&&(hiddenPulse[i]<0.001))
{
hiddenPeriod[i]=abs(hiddenVal[i])*0.7;// assign new period
if (hiddenVal[i]>0.0) {hiddenPulse[i]=1.0;}else {hiddenPulse[i]=-1.0;} // set corresponding output pulse pos/neg
}/
else { hiddenPulse[i]*=0.7-hiddenPeriod[i];} // looses amplitude downto < abs 0.001
#endif
    }
   //calculate the output of the network
   //the output neuron is linear
   for (k=0;k<NE_numOutputs;k++)
   {
NE_outPred[k] = 0.0;
#ifdef _NEU_USES_PULSES_OUTPUTS
NE_outPredPulsed[k]=0.0;// pulsed mode intermediaire output
#endif
for(i = 0;i<NE_numHidden;i++)
{
NE_outPred[k] = NE_outPred[k] + hiddenVal[i] * weightsHO[i][k];
#ifdef _NEU_USES_PULSES_OUTPUTS
NE_outPredPulsed[k] = NE_outPredPulsed[k] + hiddenPulse[i] * weightsHO[i][k];
#endif
}
//calculate the error
NE_errThisPat[k] = NE_outPred[k] - trainOutput[NE_patNum][k];
// tanh'd
#ifdef _NEU_USES_TANH_OUTPUT
// uses asymetric (Triggers out) ?
#ifdef  _NEU_USES_ASYMETRIC_OUTPUTS
if(NE_outPred[k]-NE_last_outPred[k]>0.0) // rising edge
{ 
NE_last_outPred[k]=NE_outPred[k];
NE_outTrigger[k]=(NE_outPred[k]-_neu_asym_value)*_neu_asym_magnify;
//NE_outPred[k]-=0.1;
//NE_outPred[k]*=_neu_asym_magnify;
} 
else 
{ 
NE_last_outPred[k]=NE_outPred[k];	// falling edge
NE_outTrigger[k]=(NE_outPred[k]+_neu_asym_value)*_neu_asym_magnify;
} 
// tanh'd final result
NE_outTrigger[k]=tanh(NE_outTrigger[k])/_neu_asym_rescale;
#endif
// uses tanh'd output, with no asymetry
NE_outPred[k]=tanh(NE_outPred[k]); 
#endif
//
#ifdef _NEU_USES_PULSES_OUTPUTS
// pulse mode : uses ne_outprepulsed
if((NE_outPulse[k]>-0.001)&&(NE_outPulse[k]<0.001))
{
NE_outPeriod[k]=abs(NE_outPredPulsed[k])*0.7;// assign new period
if (NE_outPredPulsed[k]>0.0) {NE_outPulse[k]=1.0;}else {NE_outPulse[k]=-1.0;} // set corresponding output pulse pos/neg
}
else { NE_outPulse[k]*=0.7-NE_outPeriod[k];} // looses amplitude downto < abs 0.001
#endif
}
}

Here is an example of float weights settings  ( 1+1+8 inputs , 1 output )

//

Neuron network array
numInputs :10
numHidden :3
numOutputs :1
INPUT to HIDDEN weights:
INPUT[0]:0.7249 -0.3254 -0.0132 
INPUT[1]:2.6476 -1.7487 1.8793 
INPUT[2]:1.6000 -2.1098 -0.1300 
INPUT[3]:1.5954 -2.1106 -0.1713 
INPUT[4]:1.5973 -2.1053 -0.0823 
INPUT[5]:1.5956 -2.1127 -0.2124 
INPUT[6]:1.5922 -2.1073 -0.1447 
INPUT[7]:1.5945 -2.1101 -0.1476 
INPUT[8]:1.5912 -2.1103 -0.1890 
INPUT[9]:1.5921 -2.1062 -0.0817 
HIDDEN to OUTPUT weights:
OUTPUT[0]:1.8294 1.8561 -1.0271
// input 0 is the cell's state at this moment.
// input 1 is the bias input. the network works 'out of the box' with 1.0 as a start value
// input 2 to 9 are the 8 surrounding cell's values
// output 0 is obviously the new cell's value once Calcnet() function is executed.
//
// nb : this weights have been obtained using a kind of unsupervised network training 
// followings are other working results, in bulk..
Neuron network array
numInputs :10
numHidden :3
numOutputs :1

INPUT to HIDDEN weights:
INPUT[0]:-0.0229 0.2218 0.7648
INPUT[1]:-2.0418 1.8457 3.1429
INPUT[2]:0.2120 2.2448 1.8066
INPUT[3]:0.2278 2.2442 1.8049
INPUT[4]:0.1597 2.2419 1.8062
INPUT[5]:0.2398 2.2457 1.8072
INPUT[6]:0.1784 2.2429 1.8051
INPUT[7]:0.1867 2.2433 1.8063
INPUT[8]:0.2036 2.2434 1.8054
INPUT[9]:0.1458 2.2410 1.8064
HIDDEN to OUTPUT weights:
OUTPUT[0]:1.0483 -1.7011 1.6570 

Yet another one
Neuron network array
numInputs :10
numHidden :3
numOutputs :1

INPUT to HIDDEN weights:
INPUT[0]:-0.3511 -0.7469 -0.3062
INPUT[1]:-1.9654 -2.7043 -1.9516
INPUT[2]:0.0046 -1.6099 -2.3226
INPUT[3]:0.0888 -1.6007 -2.3241
INPUT[4]:0.0356 -1.6225 -2.3280
INPUT[5]:0.0363 -1.6139 -2.3275
INPUT[6]:-0.0243 -1.6261 -2.3254
INPUT[7]:-0.0636 -1.6227 -2.3232
INPUT[8]:-0.0350 -1.6153 -2.3215
INPUT[9]:-0.0603 -1.6307 -2.3269
HIDDEN to OUTPUT weights:
OUTPUT[0]:1.0404 -1.8403 1.8139
Finally, another one (for that particular one, EXACT conway's rules is outputed with a bias value of 2.3 )
Neuron network array
numInputs :10
numHidden :3
numOutputs :1

INPUT to HIDDEN weights:
INPUT[0]:0.9719 0.4218 -0.4701
INPUT[1]:3.6418 2.0367 -2.4421
INPUT[2]:1.8977 3.3946 -0.1189
INPUT[3]:1.8869 3.4056 0.0242
INPUT[4]:1.8758 3.4251 0.1371
INPUT[5]:1.9026 3.3867 -0.1617
INPUT[6]:1.8715 3.4222 0.2166
INPUT[7]:1.9007 3.3728 -0.1277
INPUT[8]:1.8897 3.4263 0.0333
INPUT[9]:1.8785 3.3993 0.1416
HIDDEN to OUTPUT weights:
OUTPUT[0]:1.1289 -1.1504 1.0407
314159265358979323846264338327950288
419716939937510582097494459230781640
628620899862803482534211706798214808

August 12, 2015

neuron networks, part I

Filed under: Uncategorized — Tags: , , , , — admin @ 11:15 am

A neuron network is trained using back propagation learning, to achieve a successfull copying of the game of life rules (conway’s rules)

The neuron network description is :

  • 2 input neurons :
  1. Input 1 is the sum of the 8 surrounding cells at T ( range is 0.0 to 1.0 == 0 to 8 cells )
  2. Input 2 is the output neuron state at T-1 ( namely, the previous state of the output at T) (-1.0/+1.0)
  • 1 output neuron : the new cell’s state for this epoch. , -1.0 / +1.0 range
  • 5 hidden neurons
Network specifications :
  • input/output ranges from -1.0 to 1.0
  • hidden layer neurons uses the sigmoid like function for states : { hiddenval[k]=tanh(hiddenval[k]);  }
  • output layer neurons uses the sigmoid like function with magnifier for outputs :   { out[k]=tanh(out[k]*20.0); }
Many convergences with various weights append. using less than 5 hidden neurons can’t achieve convergence.
More than 5 hidden neurons does not improve convergence at all.
Here is weight dump of achieved convergence, with overall error less than 0.0036 % :
It was achieved after 72mega epochs, with Learning rates Hidden-to-Output of 0.03 and Learning rate Input-to-hidden of 0.3.
Weights,INPUT 1 to Hidden -22.13 -29.4693 14.7538 21.5601 -21.9645
Weights,INPUT 2 to Hidden -17.1351 -19.9037 -6.5521 -3.7809 17.136
Weights,Hidden to OUTPUT 1 1.8878 -1.906 1.8706 -1.3286 1.5681

Needless to say, the problem of the game of life rules as been exposed as : “output depends of the sum of the 8 surrounding cells AND the state of the center cell @ time T”.

A more complex approach is to use 8 input neurons ( the 8 surrounding cells) , plus the input neuron for the T-1 state of the cell.
(See part III for details about this)
Using the surrounding cells sum as an input value is one approach only: it’s a ’simplification’ provided to the neuron network previously described.

The game of life’s rule has two stages :

  1. sum the surrounding cell’s values beein ‘on’
  2. from this sum value, set the output value :
  • range 0..1 is the first solution case
  • range 2 is the second solution case
  • range 3 is the third solution case
  • range 4 to 8 is the fourth solution case
less than 5 hidden neurons will not converge.
We can compute a simple overview of the actual neuron network : 2×5 + 5×1 = 15 ’synapses’ computed.
From Part III of this post series, we have 9×3 + 3×1 = 30 synapses  ( so , its obvious that the summing the surrounding cell’s values and feeding it into the network improves cpu time for computation of an output state. but the setup of part III is somehow the ‘real’ cellular automata model..
The following images illustrate the results of the previous network (pre-computed sum of the surrounding cells )
This network just has different weight results (see last picture for values)
( snapshot of self running , once convergence was ok )
Here is the 64×64 pixels output MAPPING for the output neuron .
X axis (horizontal) is INPUT 1 :
The sum of the surrounding cells,
remapped from (0.0->8.0) to the ( 0.0 ; +1.0 ) range is used as input value.
(left is 0.0, right is  +1.0 (ie there are 8 cells around if it’s +1.0) )

Y axis (vertical) is INPUT 2 :
the network’s output at T-1 ( last output state ).top is -1.0 , bottom is +1.0

Finally, here is a snapshot of the weights used for this results  :
(Top of image : Hidden to Output neuron weights)
(Bottom : input 1, input 2 to Hidden neurons weights)
// … \\
This is a test network description. (to be continued)
314159265358979323846264338327950288
419716939937510582097494459230781640
628620899862803482534211706798214808

cat{ } { post_717 } { } 2009-2015 EIhIS Powered by WordPress