Code viewer for World: XOR multi-layer network (c...

// Cloned by K.Ellis on 6 Dec 2019 from World "XOR multi-layer network" by "Coding Train" project 
// Please leave this clone trail here.
 

// XOR multi-layer network

// Port from:
// https://github.com/CodingTrain/Toy-Neural-Network-JS/tree/master/examples/xor
// with modifications 

// libraries from:
// https://github.com/CodingTrain/Toy-Neural-Network-JS/tree/master/lib
// ported to here:
// https://ancientbrain.com/uploads.php?userid=codingtrain 



//=== Tweaker's box ============================================

// number of nodes in each layer:
const noinput = 2;
const nohidden = 10;
const nooutput = 1;

// XOR define the exemplars to learn from:
let training_data = [
  {    inputs: [0, 0],    outputs: [0]  },
  {    inputs: [0, 1],    outputs: [1]  },
  {    inputs: [1, 0],    outputs: [1]  },
  {    inputs: [1, 1],    outputs: [0]  }
];

// AND
/*let training_data = [
  {    inputs: [0, 0],    outputs: [0]  },
  {    inputs: [0, 1],    outputs: [0]  },
  {    inputs: [1, 0],    outputs: [0]  },
  {    inputs: [1, 1],    outputs: [1]  }
];*/


// OR
/*let training_data = [
  {    inputs: [0, 0],    outputs: [0]  },
  {    inputs: [0, 1],    outputs: [1]  },
  {    inputs: [1, 0],    outputs: [1]  },
  {    inputs: [1, 1],    outputs: [1]  }
];*/


var nn;     // global var 

var yGoal = 0.96;
var yReached = false;
var y = 0;
var millisecond;

const learningrate = 0.3; 

// train this number of times per draw()
const notrain = 10;

// Take screenshot on this step:
AB.screenshotStep  = 200;   


// divide 0,1 into squares 
// show all squares or just the corner squares:
var showall = false;

const canvassize    = 400;
const squaresize    = 40;

const cols          = 10 ;
const rows          = 10;


// Matrix.randomize() is changed to point to this. Must be defined by user of Matrix. 

function randomWeight()
{
    return ( AB.randomFloatAtoB ( -0.5,0.5 ) );
     //return (  -1,1 );
            // Coding Train default is -1 to 1 // -0.5, 0.5 
}    

//=== End of tweaker's box ============================================




function setup() 
{
  createCanvas (canvassize, canvassize);
  
   $.getScript ( "/uploads/codingtrain/matrix.js", function()
   {
        $.getScript ( "/uploads/codingtrain/nn.js", function()
        {
            nn = new NeuralNetwork ( noinput, nohidden, nooutput );
        });
   });
   
}



function draw() 
{
    //if (!yReached) 
    //{
        
       
          // check if libraries loaded yet:
          if ( typeof nn == 'undefined' ) return;
          nn.setLearningRate ( learningrate );
        
          //https://www.w3schools.com/colors/colors_groups.asp
          background ('#ff00ff'); 
        
          // train n times 
          for (let i = 0; i < notrain ; i++) 
          {
            let data = random ( training_data );
            nn.train ( data.inputs, data.outputs );
            //console.log("training " + i);
          }
        
        // draw either some squares or all squares:
          if ( showall )
          {
            // redraw all squares each time round
            for (let i = 0; i < cols; i++) 
                for (let j = 0; j < rows; j++) 
                    drawquare ( i, j );
          }
          else
          {
            // redraw just the 4 squares 
            for ( let i = 0; i < cols; i = i + cols-1 ) 
                for ( let j = 0; j < rows; j = j + rows-1 ) 
                    drawquare ( i, j );
          }
       
    /*}else{
            console.log("y goal reached, y = " + y);
            return;
    }*/
}  




AB.world.endRun = function()
{
    if ( AB.abortRun ) AB.abortRun=true;
    return AB.msg  ( "<br> <font color=darkblue> <B> y goal reached = </B> </font>" +  yGoal + 
                     "<br> <font color=darkblue> <B> Time taken in seconds = </B> </font>" +  Math.trunc(millisecond/1000) );
};

 
function drawquare ( i, j )
{
    
      if(y < yGoal)
      {
         millisecond = millis(); 
         AB.msg ( "<br> <font color=darkblue> <B> y goal = </B> </font>" + yGoal +
                 "<br> <font color=darkblue> <B> Time in seconds = </B> </font>" + Math.trunc(millisecond/1000));
                 
            let x1 = i / cols;
            let x2 = j / rows;
            let inputs = [x1, x2];
            y = nn.predict(inputs);
            //console.log ( "input (" +x1 + "," + x2 + ") output " + y );
            console.log("y =  " + y);
          
            strokeWeight(2);
            stroke('white');
            fill ( y * 255 );      // 0 is black, 1 is white 
          
            rect ( i * squaresize, j * squaresize, squaresize, squaresize );
      }
      else
      {
            AB.world.endRun();
            yReached = true;
            console.log("y goal reached, y = " + y);
            return;
      } 
}