//---- normal P5 code -------------------------------------------------------
$.getScript("/uploads/atharva/prepareData.js")
$.getScript ( "https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js")
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js")
$.getScript("https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.11.7")
//$.getScript("https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css")
//AB.loadCSS ( "https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" )
thehtml = '<h1>Doodle Classifier</h1> '
AB.msg(thehtml, 1);
thehtml = '<h2>Click the Train button to train the Model, then follow go to the below functions (Guess, Genrate, Clear)</h2> '+
'<!<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"!>'
AB.msg(thehtml, 2);
thehtml = '<button class="train btn btn-primary btn-lg btn-block" id="train">train</button>';
AB.msg(thehtml, 4);
// 3 Training header
thehtml = '<span class="alert alert-primary" id="training-alert" role="alert">Training...</span>';
AB.msg(thehtml, 7);
thehtml = '<span class="alert1 alert-primary" id="Accuray-alert" role="alert"></span>';
AB.msg(thehtml, 8);
// thehtml = '<textarea class="testpercentage"></textarea>'
// AB.msg ( thehtml, 7 );
thehtml = '<h2>Draw a Bird,Flower, Rainbow or Cat and click the Guess button.</h2> '
AB.msg(thehtml, 9);
// 5 Testing header
thehtml = '<button class="guess btn btn-primary" id="guess">guess</button>';
AB.msg(thehtml, 10);
thehtml = '<button class="btn btn btn-info" id="generate">Generate</button>';
AB.msg(thehtml, 12);
// 7 Demo header
thehtml = '<button class="clear btn" id="clear">clear</button>';
AB.msg(thehtml, 14);
thehtml = '<span id="output" class="alert alert-success" role="alert"></span>';
AB.msg(thehtml, 16);
AB.newDiv('canvas')
AB.newDiv('Chart')
let charts = document.getElementById("Chart");
charts.innerHTML = `<canvas id="myChart" style="width:100%;max-width:600px"></canvas>`;
let dataObjectsArray = [];
let xValues = [];
let yValues = [];
// Contains the arrays of preloaded data
let dataPreload = [];
// Model
let model;
// Tensors
xs = {};
ys = {};
testing_xs = {};
testing_ys = {};
const numberOfEachDoodle = 1000;
const data_proportion = 0.8;
function preload() {
console.log("Preloading data");
let filename;
for (let i = 0; i < doodleLabelList.length; i++) {
filename = doodleLabelList[i].toLowerCase();
dataPreload[i] = loadBytes("/uploads/atharva/" + filename + ".bin");
}
console.log(dataPreload);
console.log("Done");
}
// Setup function of p5.js (called after preload)
async function setup() {
let canvas = createCanvas(280, 280);
canvas.parent("canvas");
background(0);
initializeData();
console.log("Creating training tensors");
let rTensors = prepareData(training_data, training_labels);
xs = rTensors[0];
ys = rTensors[1];
console.log("Done");
console.log("Creating testing tensors");
// TODO: Something less cancerous
rTensors = prepareData(testing_data, testing_labels);
testing_xs = rTensors[0];
testing_ys = rTensors[1];
// Log progress
console.log("Done");
// Log progress
console.log("Creating model");
// Let's build the model
model = buildModel();
// Log progress
console.log("Done");
let trainButton = select("#train");
let trainingAlert = document.getElementById("training-alert");
trainingAlert.style.display = "none";
let accurayalert = document.getElementById("Accuray-alert");
accurayalert.style.display = "none";
trainButton.mousePressed(
// Log progress
() => {
trainingAlert.style.display = "inline";
accurayalert.style.display = "inline";
console.log("Training model");
// Let's train the model (this .then(() => thingy is an application of the
// new ES6 functionnality combined with the js promises).
train(trainingAlert, accurayalert).then(async () => {
// Log progress
console.log("Done");
trainingAlert.style.display = "none";
trainingAlert.className = "btn btn-disabled";
});
}
);
let guessButton = select("#guess");
guessButton.mousePressed(function() {
let inputs = [];
let inputImage = [];
let img = get();
img.resize(28, 28);
img.loadPixels();
// Convert black in white drawings to white in black drawings(training doodles are white on black)
for (let i = 0; i < dataLength; i++) {
let alpha = img.pixels[i * 4];
// normalize the pixels
inputs[i] = alpha / 255.0;
}
// We need to create a 2D array with this pixel because the model has been
// trained with 2D tensors.
inputImage[0] = inputs;
// convert array to tensor
let tensorToPredict = tf.tensor2d(inputImage);
console.log(tensorToPredict);
// predict the doodle
let guess = model.predict(tensorToPredict);
let argMax = guess.argMax(1);
let classifiedLabel = argMax.dataSync()[0];
let classifiedDoodleLabel = doodleLabelList[classifiedLabel];
const output = select("#output");
output.html(classifiedDoodleLabel + "!!!");
console.log("Guessed: " + classifiedDoodleLabel);
});
let clearButton = select("#clear");
clearButton.mousePressed(function() {
background(0);
const output = select("#output");
output.html("");
});
//////////////Genrating a Random image from dataset that is cat,flower,bird,rainbow
let generateButton = select("#generate");
generateButton.mousePressed(function() {
background(0);
const output = select("#output");
output.html("");
let randomIndex = floor(
random(
numberOfEachDoodle * doodleLabelList.length * (1 - data_proportion)
)
);
let offset = randomIndex * dataLength;
let doodlePixels = testing_xs
.dataSync()
.subarray(offset, offset + dataLength);
let otherOffset = randomIndex * doodleLabelList.length;
let labelsResult = testing_ys
.dataSync()
.subarray(otherOffset, otherOffset + doodleLabelList.length);
let doodleIndex;
for (let i = 0; i < labelsResult.length; i++) {
if (labelsResult[i] === 1) {
doodleIndex = i;
}
}
console.log(doodleLabelList[doodleIndex]);
let img = createImage(28, 28);
img.loadPixels();
for (let i = 0; i < dataLength; i++) {
let val = doodlePixels[i] * 255;
img.pixels[i * 4 + 0] = val;
img.pixels[i * 4 + 1] = val;
img.pixels[i * 4 + 2] = val;
img.pixels[i * 4 + 3] = 255;
}
img.updatePixels();
img.resize(280, 280);
image(img, 0, 0);
});
}
function draw() {
strokeWeight(15);
stroke(255);
if (mouseIsPressed) {
line(pmouseX, pmouseY, mouseX, mouseY);
}
}
////////////////////////////////////// dataobject
class DataObject {
constructor(label) {
this.label = label;
this.totalData = [];
this.trainingData = [];
this.testingData = [];
this.trainingLabels = [];
this.testingLabels = [];
this.data_proportion = 0.8;
this.numberOfEachDoodle = 1000;
this.bytesArrayLength = 784;
this.numberOfDoodles = 1000;
}
get trainingData() {
return this._trainingData;
}
get testingData() {
return this._testingData;
}
get trainingLabels() {
return this._trainingLabels;
}
get testingLabels() {
return this._testingLabels;
}
set trainingData(data) {
this._trainingData = data;
}
set testingData(data) {
this._testingData = data;
}
set trainingLabels(data) {
this._trainingLabels = data;
}
set testingLabels(data) {
this._testingLabels = data;
}
loadBytesData() {
let index = doodleLabelList.indexOf(this.label);
let bytesObject = dataPreload[index];
// bytesObject.bytes is the actual bytes array
this.totalData = bytesObject.bytes;
}
splitData() {
console.log(this.numberOfDoodles);
for (let i = 0; i < this.numberOfDoodles; i++) {
// keeping track of index
let offset = i * this.bytesArrayLength;
// threshold for test/train data split
let threshold = floor(this.data_proportion * this.numberOfDoodles);
if (i < threshold) {
// 1 - 800
this.trainingData[i] = this.totalData.subarray(
offset,
offset + this.bytesArrayLength
);
this.trainingLabels[i] = this.label;
} else {
// 1 - 200
this.testingData[i - threshold] = this.totalData.subarray(
offset,
offset + this.bytesArrayLength
);
this.testingLabels[i - threshold] = this.label;
}
}
}
}
//////// training and testing
function buildModel() {
let tempModel = tf.sequential();
const hiddenLayer0_Units = 512;
const hiddenLayer1_Units = 256;
const hiddenLayers_Activation = "sigmoid";
/* const hiddenLayer0 = tf.layers.dense({
units: hiddenLayer0_Units,
inputShape: dataLength,
activation: hiddenLayers_Activation,
});*/
const hiddenLayer1 = tf.layers.dense({
units: hiddenLayer1_Units,
inputShape: dataLength,
activation: hiddenLayers_Activation,
});
const hiddenLayer2_Units = 128;
const hiddenLayer2 = tf.layers.dense({
units: hiddenLayer2_Units,
activation: hiddenLayers_Activation,
});
const hiddenLayer3_Units = 64;
const hiddenLayer3 = tf.layers.dense({
units: hiddenLayer3_Units,
activation: hiddenLayers_Activation,
});
//output layer
const outputLayer_Activation = "softmax";
const output = tf.layers.dense({
units: doodleLabelList.length,
activation: outputLayer_Activation,
});
//tempModel.add(hiddenLayer0);
tempModel.add(hiddenLayer1);
tempModel.add(hiddenLayer2);
tempModel.add(hiddenLayer3);
tempModel.add(output);
const model_LearningRate = 0.5;
const model_Optimizer = tf.train.adagrad(model_LearningRate);
const model_Loss = "meanSquaredError";
tempModel.compile({
optimizer: model_Optimizer,
loss: model_Loss,
metrics: ["accuracy"],
debug: true
});
//tempModel.compile(optimizer=tf.train.adagrad(model_LearningRate), loss=tf.keras.losses.CategoricalCrossentropy(), metrics = ["accuracy"]);
return tempModel;
}
async function train(alert, alert1) {
const training_DoShuffle = true;
const training_ValidationSplit = 0.2;
const training_BatchSize = 16;
const training_NumEpochs = 50;
await model.fit(xs, ys, {
shuffle: training_DoShuffle,
validationSplit: training_ValidationSplit,
batchSize: training_BatchSize,
epochs: training_NumEpochs,
callbacks: {
onEpochEnd: (epochs, logs) => {
console.log("Epoch: " + (epochs + 1));
console.log("Loss: " + logs.loss);
console.log("Accuracy: " + logs.acc.toFixed(2));
alert.innerHTML = `Training ${epochs * 2}% done...`;
alert1.innerHTML = `Accuracy: ${100 * logs.acc.toFixed(2)}`;
var xVal = parseInt(epochs + 1);
xValues.push(xVal);
var yVal = parseInt(100 * logs.acc.toFixed(2));
yValues.push(yVal);
},
},
});
plotchat(xValues,yValues)
}
function plotchat(xValues,yValues){
new Chart("myChart", {
type: "line",
data: {
labels: xValues,
datasets: [{
fill: false,
lineTension: 0,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues
}]
},
options: {
legend: {display: false,label: "Accuracy" },
scales: {
yAxes: [{ticks: {min: 0, max:100}}],
},
title: {
display: true,
text: "Accuracy Chart",
fontSize: 16
}
}
});
//console.log((xValues));
//console.log((yValues));
}