const PIXELS = 28,
PIXELSSQUARED = PIXELS * PIXELS,
NOTRAIN = 124800,
NOTEST = 20800,
noinput = PIXELSSQUARED,
nohidden = 64,
nooutput = 26,
learningrate = .1;
let do_training = !0;
const TRAINPERSTEP = 15,
TESTPERSTEP = 5,
ZOOMFACTOR = 7,
ZOOMPIXELS = 7 * PIXELS,
canvaswidth = PIXELS + ZOOMPIXELS + 50,
canvasheight = 3 * ZOOMPIXELS + 100,
DOODLE_THICK = 18,
DOODLE_BLUR = 3;
let mnist,nn,doodle,demo,trainrun=1,
train_index = 0,
testrun = 1,
test_index = 0,
total_tests = 0,
total_correct = 0,
doodle_exists = !1,
demo_exists = !1,
mousedrag = !1,
alp = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var train_inputs, test_inputs, demo_inputs, doodle_inputs, thehtml;
function randomWeight(){return AB.randomFloatAtoB(-.5,.5)}AB.headerCSS({"max-height":"95vh"}),
thehtml="<hr> <h1> 1. Doodle </h1> Top row: Doodle (left) and shrunk (right). <br> Draw your doodle in top LHS. <button onclick='wipeDoodle();' class='normbutton' >Clear doodle</button> <br> ",
AB.msg(thehtml,1),thehtml="<hr> <h1> 2. Training </h1> Middle row: Training image magnified (left) and original (right). <br> <button onclick='do_training = false;' class='normbutton' >Stop training</button> <br> ",
AB.msg(thehtml,3),thehtml="<h3> Hidden tests </h3> ",
AB.msg(thehtml,5),thehtml="<hr> <h1> 3. Demo </h1> Bottom row: Test image magnified (left) and original (right). <br> The network is <i>not</i> trained on any of these images. <br> <button onclick='makeDemo();' class='normbutton' >Demo test image</button> <br> ",
AB.msg(thehtml,7);
const greenspan="<span style='font-weight:bold; font-size:x-large; color:red'> ";
function setup()
{
createCanvas(canvaswidth, canvasheight),(doodle = createGraphics(ZOOMPIXELS, ZOOMPIXELS)).pixelDensity(1),
AB.loadingScreen(),
$.getScript("/uploads/rania/matrix.js",function()
{
$.getScript("/uploads/rania/nn.js",function()
{
$.getScript("/uploads/rania/mnist.js",function()
{
console.log("All JS loaded"),
(
nn=new NeuralNetwork(noinput, nohidden, nooutput)).setLearningRate(learningrate), loadData()})})})}
function loadData(){loadMNIST(function(t){mnist = t,
console.log("All data loaded into mnist object:"),
console.log(mnist),
AB.removeLoading()})}
function getImage(t){let e = createImage(PIXELS, PIXELS); e.loadPixels();
for(let
n = 0; n < PIXELSSQUARED; n ++)
{
let o = t [n],
i = 4 *n;
e.pixels[i + 0] = o,
e.pixels[i + 1] = o,
e.pixels[i + 2] = o,
e.pixels[i + 3] = 255
}
return e.updatePixels(), e}
function getInputs(t)
{let
e = [];
for (let
n = 0;
n < PIXELSSQUARED; n ++){
let o = t [n];
e [n] = o / 255}
return e}
function trainit(t){
let e = mnist.train_images[train_index],
n = mnist.train_labels[train_index];
if(t)
{
var o = getImage(e);
image(o, 0, ZOOMPIXELS + 50,
ZOOMPIXELS, ZOOMPIXELS),
image(o, ZOOMPIXELS + 50,
ZOOMPIXELS + 50, PIXELS, PIXELS)}
let i = getInputs(e),
s = [0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0,0];
s[n] = 1,
train_inputs = i, s.length <=26&&nn.train(i, s),
thehtml =" trainrun: "+ trainrun +"<br> no: "+train_index,AB.msg(thehtml, 4), ++ train_index == NOTRAIN&&(train_index = 0,
console.log("finished trainrun: "+ trainrun), trainrun ++)}
function testit()
{let
t = mnist.test_images[test_index],
e = mnist.test_labels[test_index],
n = getInputs(t);test_inputs=n;
let
o = findMax(nn.predict(n));
total_tests ++,
o == e&&total_correct ++;
let i = total_correct / total_tests * 100; thehtml =" testrun: "+ testrun +"<br> no: "+total_tests +" <br> correct: "+ total_correct +"<br> score: "+ greenspan+i.toFixed(2) +"</span>",
AB.msg(thehtml, 6), ++test_index == NOTEST&&(
console.log("finished testrun: "+ testrun +" score: "+ i.toFixed(2)),testrun++, test_index=0, total_tests=0, total_correct = 0)}
function find12(t)
{let e = 0, n = 0 , o = 0, i = 0;
for(
let s = 0;
s < t.length; s++) t [s] > o? (n = e ,i = o, e = s , o = t[s]): t[s] > i&& (n = s,i = t[s])
return[e, n]}
function findMax(t){let
e = 0, n = 0;
for(let o = 0; o < t.length; o ++) t [o] > n && ( e = o, n = t[o]);
return e}
function draw()
{if(void 0!==mnist) {if(background("blue"), do_training){
for(let t = 0; t < TRAINPERSTEP; t++) trainit ( 0==t );
for(let t = 0; t < TESTPERSTEP; t ++)testit()}
if(demo_exists&&(drawDemo(), guessDemo()),
doodle_exists&&(drawDoodle(),
guessDoodle()),mouseIsPressed)
{
var t = ZOOMPIXELS + 20; mouseX < t&&mouseY < t&&pmouseX < t&&pmouseY < t&&(mousedrag = !0,
doodle_exists = !0, doodle.stroke("black"),
doodle.strokeWeight(DOODLE_THICK), doodle.line(mouseX,mouseY,pmouseX,pmouseY))}
else mousedrag&&(mousedrag =!1, doodle.filter(BLUR,DOODLE_BLUR))}}
function makeDemo(){demo_exists = !0;
var t = AB.randomIntAtoB(0, NOTEST -1);
demo = mnist.test_images[t];
var e = mnist.test_labels[t]; thehtml="Test image no: "+t+"<br>Classification: "+alp[e -1]+"<br>", AB.msg(thehtml, 8)}
function drawDemo(){
var tb=bgetImage(demo);
image(t, 0, canvasheight - ZOOMPIXELS,
ZOOMPIXELS, ZOOMPIXELS),
image(t,ZOOMPIXELS + 50,
canvasheight - ZOOMPIXELS,PIXELS,PIXELS)}
function guessDemo() {
let t = getInputs(demo);
demo_inputs=t;
let e = findMax(nn.predict(t));thehtml=" We classify it as: "+greenspan+alp[e - 1]+"</span>",AB.msg(thehtml, 9)}
function drawDoodle()
{
let t = doodle.get();image(t, 0 , 0, ZOOMPIXELS,ZOOMPIXELS),image(t,ZOOMPIXELS + 50, 0,PIXELS, PIXELS)}
function guessDoodle()
{let t = doodle.get();
t.resize(PIXELS, PIXELS), t.loadPixels();
let e = [];
for(let n = 0; n < PIXELSSQUARED; n++) e [n] = t.pixels[4 * n] / 255;
doodle_inputs=e; let n = find12(nn.predict(e));
thehtml=" We classify it as: "+ greenspan + alp[n[0]] +"</span> <br> No.2 guess is: "+ greenspan + alp[n[1]]+"</span>",AB.msg(thehtml, 2)}
function wipeDoodle() {doodle_exists=!1, doodle.background("ligh blue")}
function showInputs(t){
var e ="";
for(let n = 0; n<t.length; n++) {n%PIXELS == 0&&(e+="\n"), e=e+" "+t[n].toFixed(2)}
console.log(e)}