// 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;
}
}