diff --git a/AutoEncoder_TrainingData/AutoEncoder_TrainingData.pde b/AutoEncoder_TrainingData/AutoEncoder_TrainingData.pde index b6b41e1..cffdb79 100644 --- a/AutoEncoder_TrainingData/AutoEncoder_TrainingData.pde +++ b/AutoEncoder_TrainingData/AutoEncoder_TrainingData.pde @@ -1,31 +1,52 @@ int counter = 0; int W = 28; + void setup() { size(280, 280); + } void draw() { + translate(width/2, height/2); background(255); //frameRate(5); float r = random(0, width); strokeWeight(16); rectMode(CENTER); - //float x = random(width); - //float y = random(height); + //star(0, 0, r/5, r/2, 6); + //star(width/2, height/2, r, r, 4); if (random(1) < 0.5) { - square(width/2, width/2, r); + stroke(255,0,255); + star(0, 0, r/5, r/2, 6); + //square(width/2, height/2, r); } else { - circle(width/2, width/2, r); + stroke(0,0,255); + circle(0, 0, r); } PImage img = get(); //img.resize(28, 28); img.resize(W, W); - img.save("data/square" + nf(counter, 4) + ".png"); + //img.save("Auto-Encoder-Demo/public/data/shape" + nf(counter, 4) + ".png"); counter++; - if (counter == 5100) { + if (counter == 1100) { exit(); } - // noLoop(); + //noLoop(); } +//star function taken from Processing website +function star(float x, float y, float radius1, float radius2, int npoints) { + float angle = TWO_PI / npoints; + float halfAngle = angle/2.0; + beginShape(); + for (float a = 0; a < TWO_PI; a += angle) { + float sx = x + cos(a) * radius2; + float sy = y + sin(a) * radius2; + vertex(sx, sy); + sx = x + cos(a+halfAngle) * radius1; + sy = y + sin(a+halfAngle) * radius1; + vertex(sx, sy); + } + endShape(CLOSE); +} \ No newline at end of file diff --git a/README.md b/README.md index de39e07..12237c3 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,112 @@ Exploring autoencoders with p5 and tensorflow js ## Related topics * [Coding train tensorflow.js playlist](https://www.youtube.com/playlist?list=PLRqwX-V7Uu6YIeVA3dNxbR9PYj4wV31oQ) * [Coding train neural network playlist](https://www.youtube.com/playlist?list=PLRqwX-V7Uu6aCibgK1PTWWu9by6XFdCfh) + +## Introduction + +This definition of machine learning, adapted from "Deep Learning with Javascript: Neural Networks in Tensorflow.js", encapsulates the purpose of the autoencoder nicely: "finding an appropriate transformation that turns the old representation of the input data into a new one". In this case, the data is the pixel values in a (28*28 or 56*56) image of randomly sized circles or aquares generated in Processing. The role of the autoencoder is to develop a model which will learn how to produce new images based on a new input (a new shape, random noise, etc.). The model consists of weights that will be applied to each neuron (pixel) in each layer. Starting at the final layer, the weights are determined by calculating the difference between the predicted pixel array and the actual pixel array (error), for each image in a random batch of 32 images in the training data. Epochs specify how many times this process is repeated. This calculation is repeated in backwards fashion for each layer of the autoencoder. + + Once the weights are calculated, they are stored in a json file in the model folder. Given the model weights, the model is then tested by imputing the test images. Once the model is built, the weights are frozen, and the decoder model can be used to regerate new images based on the input fed to the decoder. This input could be images of circles or squares (with or without noise) or pure random noise. A practical example of this is an activity tracker. + +Key concepts: + +1. Neural Network: composed of an input layer, one or more hidden layers, and an output layer. Our input layer is the array containing the normalized r values for each pixel + +2. Sequential model: the layers are architacked in a linear sequence. + +``const autoencoder = tf.sequential();`` + +3. Fullly-Connected or Dense Layer: defined as "deeply connected" to the preceding layer (ie. every neuron of the layer is connected to every neuron in its preceding layer.) The input to a dense layer must be a 1d array. + +`` autoencoder.add(tf.layers.dense{}));`` + +3. Convolutional Layer: this algorithm takes subsets of the tensor (based on the size of the kernal). Only the nodes within the subsample are fully connected. + +``autoencoder.add(tf.layers.conv2d({}));`` + +4. Pooling layer, which downsamples the nodes, is often used is conjuction with the convolutional layer + +A convolutional layer and pooling layer used together are referred to as a convolutional block. + +``autoencoder.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2}));`` + +If your images are grey scale (and therefore you are only using the r channel), it is OK to start with dense layers. However, if you want to include 3 channels, you need to use a convolutional network. Because the images each have an input shape of W*W*3, the number of neurons gets very large as the resolution of the image increases. + + +4. Gradient Descent: A really good analogy is descending a steep mountain trail in the dark, when you only have the narrow beam of a flashlight to guide you. You will make small steps trying to get to the bottom of the mountain, taken from "Make Your Own Neural Network". Each small step is analogous to the learning rate. If there is only one mountain peak, given enough time you will eventually reach the bottom. However, if there are many peaks with valleys, it is possible you will not reach the local value but not reach the base of the mountain. For this reason, it is a best practice to train on small groups of samples (batches) and shuffle the samples. + +5. Normalization: The inputs into the last layer of the model are passed throught the sigmoid activation function, which is bounded between -1 and 1, therefore we divide by 255: + +``rawData[n*c+cidx] = p[n*c+cidx] / 255.0;`` + +## Key Model Hyperparameters for neural network + +1. Activation Function The activation function is a nonlinear, differentiable function that is used to improve the efficiency of the model(relu, sigmoid) over plain linear regression. +2. Learning Rate: the rate at which the weights are adjusted. +3. Optimizer: adam +4. Kernal size: subset of the image tensor +5. Input Shape: number of nodes going into each layer +6. Units: number of nodes coming out of each layer. +7. Accuracy: perceptange of correct predictions + Note: can be misleading which is why loss is used to monitor how well the model is doing +8. Loss: "MeanSquaredError", a measure of the difference between the actual image and predicted image. +9. Drop out rate - percentage of inputs that are dropped from a layer to add randomness to the training and help prevent overfitting + +## Hyperparameters that control output size (units) of convolutional blocks + +1. depth: corresponds the the number of filters (can be thought of as separate parameters, i.e. shape, radius, colors) +2. stride: number of pixels by which the filter is moved across the array to sample +3. zero-padding: do you want to pad with zeros around the outside of the tensor. This is helpful if you want to ensure that you are capturing the information at the perimeter of the tensor. +4. The formula to determine output size of convolutional layer, W1*W1*D1, where W1 = (W - F + 2 * P)/S + 1 + +W1 = width of image +F = number of filters +P = amount of zero padding +S = strides ++1 accounts for the bias +D = depth (# of colors) + +5. The formula to determine the output shape of the pooling layer is W2*W2*D, where + +W2 = (W1 - F)/S + 1 + +A detailed explanation of these formulas and a very nice animation can be found here at https://cs231n.github.io/convolutional-networks/#conv + +## Training with grey scale versus color images + +Each image is a 3D tensor with (height-width-channel). A batch of images is a 4D tensor, where the additional dimension is the number of images (NHWC). + +--If you are training/testing grey scale images, declare 2d tensors. + +``const x_train = tf.tensor2d(images.slice(0, 1000), [ 1, W, W, c ]);`` + +--If you are training/testing color images, declare 4d tensors. + +``const x_train = tf.tensor4d(images.slice(1000), [ 1, W , W, c ]);`` + +## p5.js implementation + +createGraphics(w, h, [renderer]) creates an off-screen graphics buffer. (In example in p5.js appearance of object changes. + +## Libraries + +1. tensorflow.js + +1. Jimp: used to read in pixel data from the images created in Processing/P5JS and write new images to a file. + +2. Numeral: used to efficiently refer to each image during the read/write process + + +## Important + +1. Each time the program is run, tensors are created. You need to make sure that you are disposing of them using tidy() or your computer memory will fill up with tensors and slow down your computer. + +2. Each layer of stacking convolutional blocks will reduce the number of nodes. It is possible to go too far (especially if you start with a small resolution) and you will get a somewhat cryptic error that you have passed a null tensor. The output of the last convolutional layer needs to be [1,1, number of filters], ie you must pass a 1d array to the first dense layer. + +## Additional Reading + +Deep Learning with Javascript: Neural Networks in Tensorflow.js, Shanging Cai, Stanley Bileschi, Eric Nielsen, Fransois Chollet + +Make Your Own Neural Network, Tariq Rashid + +Understanding and implementing a fully convolutional network (FCN), Himanshu Rawiani, https://towardsdatascience.com/implementing-a-fully-convolutional-network-fcn-in-tensorflow-2-3c46fb61de3b \ No newline at end of file diff --git a/index.js b/index.js index 6ee0bb1..9368a5d 100644 --- a/index.js +++ b/index.js @@ -1,30 +1,43 @@ console.log("Hello Autoencoder 🚂"); import * as tf from "@tensorflow/tfjs-node"; -// import canvas from "canvas"; -// const { loadImage } = canvas; import Jimp from "jimp"; import numeral from "numeral"; +//size of images const W = 28; +// variable for # of colors: 1 for greyscale and 3 for color +const c = 3; + +//const images = await loadImages(5); +//const images = await loadImageAsTensor(5); main(); async function main() { // Build the model - const { decoderLayers, autoencoder } = buildModel(); + const { + decoderLayers, + autoencoder + } = buildModel(); // load all image data - const images = await loadImages(5100); + const images = await loadImages(50); + // train the model - const x_train = tf.tensor2d(images.slice(0, 5000)); - await trainModel(autoencoder, x_train, 200); + + //Error: tensor4d() requires values to be number[][][][] or flat/TypedArray + const x_train = tf.tensor4d(images.slice(0, 40), [40, W, W, c]); + + //last parameter is number of epochs + await trainModel(autoencoder, x_train, 5); const saveResults = await autoencoder.save("file://public/model/"); console.log(autoencoder.summary()); - // const autoencoder = await tf.loadLayersModel("file://public/model/model.json"); + //const autoencoder = await tf.loadLayersModel("file://public/model/model.json"); // test the model - const x_test = tf.tensor2d(images.slice(5000)); + const x_test = images.slice(40); + //const x_test = tf.tensor4d(images.slice(50), [1, W, W, c]); await generateTests(autoencoder, x_test); // Create a new model with just the decoder @@ -34,33 +47,62 @@ async function main() { async function generateTests(autoencoder, x_test) { const output = autoencoder.predict(x_test); - // output.print(); + //original code + // const newImages = await output.array(); + // for (let i = 0; i < newImages.length; i++) { + // const img = newImages[i]; + + // image files identical??? something must be wrong + //console.log(img); + // const buffer = []; + // for (let n = 0; n < img.length; n++) { + + // const val = Math.floor(img[n] * 255); + // buffer[n * 4 + 0] = val; + // buffer[n * 4 + 1] = val; + // buffer[n * 4 + 2] = val; + // buffer[n * 4 + 3] = 255; + // } + + //new code getting r,g,b values + // const newImages = await output.array(); + // for (let i = 0; i < newImages.length; i++) { + // const img = newImages[i]; + // const buffer = []; + // for (let n = 0; n < img.length; n++) { + // buffer[n * 4 + 0] = Math.round(img[n * c + 0] * 255); + // buffer[n * 4 + 1] = Math.round(img[n * c + 1] * 255); + // buffer[n * 4 + 2] = Math.round(img[n * c + 2] * 255); + // buffer[n * 4 + 3] = 255; + // } + + // const newImages = await output.array(); - for (let i = 0; i < newImages.length; i++) { + for (let i = 0; i < 1; i++) { //newImages.length; i++) { const img = newImages[i]; const buffer = []; for (let n = 0; n < img.length; n++) { - const val = Math.floor(img[n] * 255); - buffer[n * 4 + 0] = val; - buffer[n * 4 + 1] = val; - buffer[n * 4 + 2] = val; - buffer[n * 4 + 3] = 255; - } - const image = new Jimp( - { - data: Buffer.from(buffer), - width: W, - height: W, - }, - (err, image) => { - const num = numeral(i).format("0000"); - image.write(`output/square${num}.png`); + for (let cidx = 0; cidx < 3; cidx++) { + buffer[n * 4 + cidx] = Math.round(img[n * c + cidx] * 255); + buffer[n * 4 + 3] = 255; } - ); + console.log(buffer); + } } + const image = new Jimp({ + data: Buffer.from(buffer), + width: W, + height: W, + }, + (err, image) => { + const num = numeral(i).format("0000"); + image.write(`output/shape${num}.png`); + } + ); } + function createDecoder(decoderLayers) { const decoder = tf.sequential(); for (let layer of decoderLayers) { @@ -86,68 +128,86 @@ function buildModel() { // Build the model // Encoder + + //! Commnet out the following code for greyscale images + autoencoder.add(tf.layers.conv2d({ + inputShape: [W, W, c], + // we are adding number of colors last + dataFormat: 'channelsLast', + kernelSize: 3, + filters: 3, // recommended 3 because there are 3 colors + activation: 'relu' + })); + + //autoencoder.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2})); + + // the input into a dense layer must be a 1d array + autoencoder.add(tf.layers.flatten({})); + + // !!Uncomment the following lines if you are using grey scale images + // autoencoder.add( + // tf.layers.dense({ + // units: 256*c, + // //inputShape: [ W*W*c ], + // activation: "relu", + // }) + // ); + // autoencoder.add( + // tf.layers.dense({ + // units: 128*c, + // activation: "relu", + // }) + // ); + + // autoencoder.add( + // tf.layers.dense({ + // units: 64*c, + // activation: "relu", + // }) + // ); autoencoder.add( tf.layers.dense({ - units: 256, - inputShape: [W * W], - activation: "relu", - }) - ); - autoencoder.add( - tf.layers.dense({ - units: 128, - activation: "relu", - }) - ); - autoencoder.add( - tf.layers.dense({ - units: 64, - activation: "relu", - }) - ); - autoencoder.add( - tf.layers.dense({ - units: 16, + units: 16 * c, activation: "relu", }) ); autoencoder.add( tf.layers.dense({ - units: 4, + units: 4 * c, activation: "sigmoid", }) ); - // How do I start from here? - // Decoder + // // How do I start from here? + // // Decoder let decoderLayers = []; decoderLayers.push( tf.layers.dense({ - units: 16, + units: 16 * c, activation: "relu", }) ); decoderLayers.push( tf.layers.dense({ - units: 64, + units: 64 * c, activation: "relu", }) ); decoderLayers.push( tf.layers.dense({ - units: 128, + units: 128 * c, activation: "relu", }) ); decoderLayers.push( tf.layers.dense({ - units: 256, + units: 256 * c, activation: "relu", }) ); decoderLayers.push( tf.layers.dense({ - units: W * W, + units: W * W * c, activation: "sigmoid", }) ); @@ -155,14 +215,16 @@ function buildModel() { for (let layer of decoderLayers) { autoencoder.add(layer); } - // const learningRate = 0.001; // const optimizer = tf.train.adam(learningRate); autoencoder.compile({ optimizer: "adam", loss: "meanSquaredError", }); - return { decoderLayers, autoencoder }; + return { + decoderLayers, + autoencoder + }; } async function trainModel(autoencoder, x_train, epochs) { @@ -174,23 +236,139 @@ async function trainModel(autoencoder, x_train, epochs) { }); } +// load images of shapes async function loadImages(total) { const allImages = []; + let rawData = []; for (let i = 0; i < total; i++) { const num = numeral(i).format("0000"); const img = await Jimp.read( - `AutoEncoder_TrainingData/data/square${num}.png` - ); + `public/data/shape${num}.png`) + .then(img => { + return img + //.write('color.jpg'); + }) + .catch(err => { + console.error(err); + }); + //strategy 1: based on your original code let rawData = []; + let rbit = []; + let gbit = []; + let bbit = []; for (let n = 0; n < W * W; n++) { let index = n * 4; let r = img.bitmap.data[index + 0]; - // let g = img.bitmap.data[n + 1]; - // let b = img.bitmap.data[n + 2]; - rawData[n] = r / 255.0; + let g = img.bitmap.data[index + 1]; + let b = img.bitmap.data[index + 2]; + //normalize data + rbit[n] = r / 255.0; + gbit[n] = g / 255.0; + bbit[n] = b / 255.0; + + // add each color array to rawData + rawData.push(rbit); + rawData.push(gbit); + rawData.push(bbit); } allImages[i] = rawData; + //console.log(rawData.length); //get 2352 } + console.log(allImages.length); //getting batch size return allImages; } +// //strategy 2: slight modification; try casting to tensors and stacking +// let rawData = []; +// let rbit = []; +// let gbit = []; +// let bbit = []; +// for (let n = 0; n < W * W; n++) { +// let index = n * 4; +// let r = img.bitmap.data[index + 0]; +// let g = img.bitmap.data[index + 1]; +// let b = img.bitmap.data[index + 2]; +// const shape = [W, W]; + +// // get the following Error: Based on the provided shape, [28,28], +// // the tensor should have 784 values but has 1 + +// rbit[n] = tf.tensor((r / 255.0), shape); +// // console.log(rbit.length); // get 784 +// console.log('shape:', rbit.shape); +// // gbit[n] = tf.tensor(g / 255.0); +// // bbit[n] = tf.tensor(b / 255.0); +// // tf.stack(rbit, gbit, bbit); +//} + +// console.log(rawData.length); +// allImages[i] = rawData; +// } +// console.log(allImages.length); +// //must return allImages here!! +// return allImages; +// //console.log(tf.memory()); +// } +// } + +// // strategy 3 I think this is based on code from tensorflow/tfjs-examples.git +// async function loadImageAsTensor(total) { +// const allImages = []; +// let rawData = []; +// for (let i = 0; i < total; i++) { +// const num = numeral(i).format("0000"); +// const img = await Jimp.read( +// `public/data/shape${num}.png`) +// .then(img => { +// return img +// //.write('color.jpg'); +// }) +// const buffer = tf.buffer([1, W, W, 3], 'float32'); +// img.scan(0, 0, W, W, function (x, y, index) { +// buffer.set(img.bitmap.data[index], 0, y, x, 0); +// buffer.set(img.bitmap.data[index + 1], 0, y, x, 1); +// buffer.set(img.bitmap.data[index + 2], 0, y, x, 2); +// }); +// rawData = tf.tidy(() => tf.image.resizeBilinear( +// buffer.toTensor(), [W, W]).div(255)); +// console.log(rawData.length); // getting undefined +// } +// } + +// //strategy 4: based on code in stack exchange +// const values = img.bitmap.data; +// const outShape = [1, img.bitmap.width, img.bitmap.height, 4]; +// let d = tf.tensor4d(values, outShape, 'float32'); +// // Slice away alpha +// d = d.slice([0, 0, 0, 0], [1, img.bitmap.width, img.bitmap.height, c]); +// rawData = d / 255.0; +// allImages[i] = rawData; +// //allImages.push(rawData) +// //console.log(rawData.length); +// return allImages; +// //console.log(allImages.length); +// } +// } + +//strategy 5: input as one long tensor shape [batchsize, 1,2352] +// I don't think this is the right approach, however, as number of colors provides +// important features?? + +// const p = []; +// for (let n = 0; n < W * W; n++) { +// let idx = n * 4; +// for (let cidx = 0; cidx < c; cidx++) { +// let d = tf.tensor2d(img.bitmap.data[idx + cidx]); +// p.push(img.bitmap.data[idx + cidx]); +// rawData[n * c + cidx] = p[n * c + cidx] / 255.0; +// } +// } +// console.log(rawData); + +// allImages[i] = tf.tensor3d(rawData, [1, W * W * c]); +// rd = tf.tensor1d(rawData); +// allImages = tf.stack(rd); +// console.log(allImages[0]); +// } +// return allImages; +// } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 37a711d..ba3a0cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,10 @@ "version": "0.0.1", "license": "ISC", "dependencies": { - "@tensorflow/tfjs-node": "^3.11.0", + "@tensorflow/tfjs": "^3.12.0", + "@tensorflow/tfjs-node": "^3.12.0", "canvas": "^2.8.0", + "http-server": "^14.0.0", "jimp": "^0.16.1", "numeral": "^2.0.6" } @@ -594,16 +596,16 @@ } }, "node_modules/@tensorflow/tfjs": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-3.11.0.tgz", - "integrity": "sha512-TTYrKdkoh1sHnt4vn6MboLbpi1Es4U1Aw+L3PqwadRvXW4+7ySUtc00McrQ+ooK0q3Qhl3N7cvgchgM7nED3Mg==", - "dependencies": { - "@tensorflow/tfjs-backend-cpu": "3.11.0", - "@tensorflow/tfjs-backend-webgl": "3.11.0", - "@tensorflow/tfjs-converter": "3.11.0", - "@tensorflow/tfjs-core": "3.11.0", - "@tensorflow/tfjs-data": "3.11.0", - "@tensorflow/tfjs-layers": "3.11.0", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-3.12.0.tgz", + "integrity": "sha512-Gpala8Lf2DJ3j2hY43gPQ8TIJzw5sYrxfpQF0SBX26/zuHUMaF/DQz4koeRqf9s1t6MAjVbbkXdYKtGeEz4Jrg==", + "dependencies": { + "@tensorflow/tfjs-backend-cpu": "3.12.0", + "@tensorflow/tfjs-backend-webgl": "3.12.0", + "@tensorflow/tfjs-converter": "3.12.0", + "@tensorflow/tfjs-core": "3.12.0", + "@tensorflow/tfjs-data": "3.12.0", + "@tensorflow/tfjs-layers": "3.12.0", "argparse": "^1.0.10", "chalk": "^4.1.0", "core-js": "3", @@ -615,9 +617,9 @@ } }, "node_modules/@tensorflow/tfjs-backend-cpu": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-3.11.0.tgz", - "integrity": "sha512-ShLkrZ4/rmhZwzGKenMFDfQnaEbyZgWA5F8JRa52Iob/vptlZeuOzjq87CZKmZMUmDswR9A2kjzovT/H1bJdWQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-3.12.0.tgz", + "integrity": "sha512-UMf/OHHCzm/+oKXtTDnanlyYFNNKKU5u2hJooKak1JqSOEKChBOPYKmxf9VWmY7Pos4GbbKH/V1pLzfLnLq+Bg==", "dependencies": { "@types/seedrandom": "2.4.27", "seedrandom": "2.4.3" @@ -626,7 +628,7 @@ "yarn": ">= 1.3.2" }, "peerDependencies": { - "@tensorflow/tfjs-core": "3.11.0" + "@tensorflow/tfjs-core": "3.12.0" } }, "node_modules/@tensorflow/tfjs-backend-cpu/node_modules/seedrandom": { @@ -635,11 +637,11 @@ "integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=" }, "node_modules/@tensorflow/tfjs-backend-webgl": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-3.11.0.tgz", - "integrity": "sha512-rNnc/dZ7LIl9O/Pn9W24I1h8kgpJ+XvG8NrdNSfIoWPCW4fvPSlU7B3yMeZXvRneny+z+T3xRs96nWyU2mZBJw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-3.12.0.tgz", + "integrity": "sha512-nFiPS7AiDZ+H4RXpx8dSYPWzy3B1zC/aRKwH9uz9MUp1WiHHbYr90+E0ut9HFrIz0cMb0sR7vGU+zkjSZ1rLsA==", "dependencies": { - "@tensorflow/tfjs-backend-cpu": "3.11.0", + "@tensorflow/tfjs-backend-cpu": "3.12.0", "@types/offscreencanvas": "~2019.3.0", "@types/seedrandom": "2.4.27", "@types/webgl-ext": "0.0.30", @@ -650,7 +652,7 @@ "yarn": ">= 1.3.2" }, "peerDependencies": { - "@tensorflow/tfjs-core": "3.11.0" + "@tensorflow/tfjs-core": "3.12.0" } }, "node_modules/@tensorflow/tfjs-backend-webgl/node_modules/seedrandom": { @@ -659,17 +661,17 @@ "integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=" }, "node_modules/@tensorflow/tfjs-converter": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.11.0.tgz", - "integrity": "sha512-rTRIKvBoqL0qdPYpm8UXauZycOiaBHZB2E2v3OoXoHnjvle/Xn/09uZJdrixgGhR+Kahs3Vz27BEEFz6RI5j2w==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.12.0.tgz", + "integrity": "sha512-WO6FreEB83CgFwvcyrzyaWG5WshanfyhTI6rOqSbjY86+MlJprTn4fuY9qbnYk/gDLhxEaUpYgubamY4g4L76g==", "peerDependencies": { - "@tensorflow/tfjs-core": "3.11.0" + "@tensorflow/tfjs-core": "3.12.0" } }, "node_modules/@tensorflow/tfjs-core": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-3.11.0.tgz", - "integrity": "sha512-JOp+1+LCd0Xg3hu7fu6iQPWZnN8Hc6ssfP7B+625XH5GYY1/OhVASa7Ahe2mJr9gZovY2lw8FUejLh1jMmBb1Q==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-3.12.0.tgz", + "integrity": "sha512-0rXf+aMjfkFLan7qna+L7DjfSZaaRibKgq9XuorjSy9rZcdZLE2IHFTzYR7B8mdlnq2szArKzm+JXqa9grTl7w==", "dependencies": { "@types/long": "^4.0.1", "@types/offscreencanvas": "~2019.3.0", @@ -689,34 +691,34 @@ "integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=" }, "node_modules/@tensorflow/tfjs-data": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-3.11.0.tgz", - "integrity": "sha512-+cUHUHzjM/zs0JVOwHQm9wP15Y+BZdRcUpMoYWia8r3kaGSyvoz6WqzacEP1PeXgJVnr2gtU3D+bF32th8fZfQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-3.12.0.tgz", + "integrity": "sha512-Q5S0pYgjqqLeFPaoHaEt9KeNFf5BrobcYmLZ9bsUnSowY0Kxz6RvnPWNNaOI3FhgqCF/e+RmGX20J0wx3Ty04Q==", "dependencies": { "@types/node-fetch": "^2.1.2", "node-fetch": "~2.6.1" }, "peerDependencies": { - "@tensorflow/tfjs-core": "3.11.0", + "@tensorflow/tfjs-core": "3.12.0", "seedrandom": "~2.4.3" } }, "node_modules/@tensorflow/tfjs-layers": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-3.11.0.tgz", - "integrity": "sha512-BtLgLucJZHv5te1K3yjT3iZdHXgMJArrLuOb/oRPOtTp4R2ad5N0V2m5RtuZJ3sI5/ah0h72xtmTWNyTv3/5dw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-3.12.0.tgz", + "integrity": "sha512-GlU9LxDnPg3I3p+MMOYzKgr2NZK2vVmT4/EotwMVIAyhR2WbVFTRP0AXkIrWSoNIJ9v/ryvFEvNNPyNfkXM/xQ==", "peerDependencies": { - "@tensorflow/tfjs-core": "3.11.0" + "@tensorflow/tfjs-core": "3.12.0" } }, "node_modules/@tensorflow/tfjs-node": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-3.11.0.tgz", - "integrity": "sha512-EFBAkwJDoP4WuiWqjT9ER80dUvilvVFXULlU3WpmVGDluIL/Yq18xEKHvPaYHW5jLq/mvMljLtUBlHqigfvAhw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-3.12.0.tgz", + "integrity": "sha512-Tl4dil1k9Mjj8A4vLxZJqwOhcV8zo2ZE8XCbKCF+B5i0sBJNqej4WzxJvdA5v3xu36D0UrEaWC5miqaX7ODQFw==", "hasInstallScript": true, "dependencies": { "@mapbox/node-pre-gyp": "1.0.4", - "@tensorflow/tfjs": "3.11.0", + "@tensorflow/tfjs": "3.12.0", "adm-zip": "^0.5.2", "google-protobuf": "^3.9.2", "https-proxy-agent": "^2.2.1", @@ -734,9 +736,9 @@ "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "node_modules/@types/node": { - "version": "16.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz", - "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==" + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.5.tgz", + "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" }, "node_modules/@types/node-fetch": { "version": "2.5.12", @@ -840,6 +842,14 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -869,6 +879,17 @@ } ] }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/bmp-js": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", @@ -914,6 +935,18 @@ "node": ">=0.4.0" } }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/canvas": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz", @@ -1022,6 +1055,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1058,6 +1099,14 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -1132,6 +1181,11 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "node_modules/exif-parser": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", @@ -1145,6 +1199,25 @@ "node": ">=6" } }, + "node_modules/follow-redirects": { + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", + "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -1171,6 +1244,11 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, "node_modules/gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -1194,6 +1272,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gifwrap": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz", @@ -1236,6 +1327,17 @@ "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.1.tgz", "integrity": "sha512-Isv1RlNC+IzZzilcxnlVSf+JvuhxmY7DaxYCBy+zPS9XVuJRtlTTIXR9hnZ1YL1MMusJn/7eSy2swCzZIomQSg==" }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1244,11 +1346,80 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.0.0.tgz", + "integrity": "sha512-XTePIXAo5x72bI8SlKFSqsg7UuSHwsOa4+RJIe56YeMUvfTvGDy7TxFkTEhfIRmM/Dnf6x29ut541ythSBZdkQ==", + "dependencies": { + "basic-auth": "^2.0.1", + "colors": "^1.4.0", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.5", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", @@ -1261,6 +1432,17 @@ "node": ">= 4.5.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -1355,6 +1537,11 @@ "xtend": "^4.0.0" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -1561,6 +1748,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/omggif": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", @@ -1574,6 +1769,14 @@ "wrappy": "1" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -1635,6 +1838,19 @@ "node": ">=4.0.0" } }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -1656,6 +1872,20 @@ "node": ">=0.4.0" } }, + "node_modules/qs": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", + "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -1683,6 +1913,11 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -1699,11 +1934,21 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=" + }, "node_modules/seedrandom": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", @@ -1729,6 +1974,19 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", @@ -1870,6 +2128,22 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "node_modules/utif": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", @@ -1888,6 +2162,17 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -2524,16 +2809,16 @@ } }, "@tensorflow/tfjs": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-3.11.0.tgz", - "integrity": "sha512-TTYrKdkoh1sHnt4vn6MboLbpi1Es4U1Aw+L3PqwadRvXW4+7ySUtc00McrQ+ooK0q3Qhl3N7cvgchgM7nED3Mg==", - "requires": { - "@tensorflow/tfjs-backend-cpu": "3.11.0", - "@tensorflow/tfjs-backend-webgl": "3.11.0", - "@tensorflow/tfjs-converter": "3.11.0", - "@tensorflow/tfjs-core": "3.11.0", - "@tensorflow/tfjs-data": "3.11.0", - "@tensorflow/tfjs-layers": "3.11.0", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-3.12.0.tgz", + "integrity": "sha512-Gpala8Lf2DJ3j2hY43gPQ8TIJzw5sYrxfpQF0SBX26/zuHUMaF/DQz4koeRqf9s1t6MAjVbbkXdYKtGeEz4Jrg==", + "requires": { + "@tensorflow/tfjs-backend-cpu": "3.12.0", + "@tensorflow/tfjs-backend-webgl": "3.12.0", + "@tensorflow/tfjs-converter": "3.12.0", + "@tensorflow/tfjs-core": "3.12.0", + "@tensorflow/tfjs-data": "3.12.0", + "@tensorflow/tfjs-layers": "3.12.0", "argparse": "^1.0.10", "chalk": "^4.1.0", "core-js": "3", @@ -2542,9 +2827,9 @@ } }, "@tensorflow/tfjs-backend-cpu": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-3.11.0.tgz", - "integrity": "sha512-ShLkrZ4/rmhZwzGKenMFDfQnaEbyZgWA5F8JRa52Iob/vptlZeuOzjq87CZKmZMUmDswR9A2kjzovT/H1bJdWQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-3.12.0.tgz", + "integrity": "sha512-UMf/OHHCzm/+oKXtTDnanlyYFNNKKU5u2hJooKak1JqSOEKChBOPYKmxf9VWmY7Pos4GbbKH/V1pLzfLnLq+Bg==", "requires": { "@types/seedrandom": "2.4.27", "seedrandom": "2.4.3" @@ -2558,11 +2843,11 @@ } }, "@tensorflow/tfjs-backend-webgl": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-3.11.0.tgz", - "integrity": "sha512-rNnc/dZ7LIl9O/Pn9W24I1h8kgpJ+XvG8NrdNSfIoWPCW4fvPSlU7B3yMeZXvRneny+z+T3xRs96nWyU2mZBJw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-3.12.0.tgz", + "integrity": "sha512-nFiPS7AiDZ+H4RXpx8dSYPWzy3B1zC/aRKwH9uz9MUp1WiHHbYr90+E0ut9HFrIz0cMb0sR7vGU+zkjSZ1rLsA==", "requires": { - "@tensorflow/tfjs-backend-cpu": "3.11.0", + "@tensorflow/tfjs-backend-cpu": "3.12.0", "@types/offscreencanvas": "~2019.3.0", "@types/seedrandom": "2.4.27", "@types/webgl-ext": "0.0.30", @@ -2578,15 +2863,15 @@ } }, "@tensorflow/tfjs-converter": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.11.0.tgz", - "integrity": "sha512-rTRIKvBoqL0qdPYpm8UXauZycOiaBHZB2E2v3OoXoHnjvle/Xn/09uZJdrixgGhR+Kahs3Vz27BEEFz6RI5j2w==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.12.0.tgz", + "integrity": "sha512-WO6FreEB83CgFwvcyrzyaWG5WshanfyhTI6rOqSbjY86+MlJprTn4fuY9qbnYk/gDLhxEaUpYgubamY4g4L76g==", "requires": {} }, "@tensorflow/tfjs-core": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-3.11.0.tgz", - "integrity": "sha512-JOp+1+LCd0Xg3hu7fu6iQPWZnN8Hc6ssfP7B+625XH5GYY1/OhVASa7Ahe2mJr9gZovY2lw8FUejLh1jMmBb1Q==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-3.12.0.tgz", + "integrity": "sha512-0rXf+aMjfkFLan7qna+L7DjfSZaaRibKgq9XuorjSy9rZcdZLE2IHFTzYR7B8mdlnq2szArKzm+JXqa9grTl7w==", "requires": { "@types/long": "^4.0.1", "@types/offscreencanvas": "~2019.3.0", @@ -2605,27 +2890,27 @@ } }, "@tensorflow/tfjs-data": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-3.11.0.tgz", - "integrity": "sha512-+cUHUHzjM/zs0JVOwHQm9wP15Y+BZdRcUpMoYWia8r3kaGSyvoz6WqzacEP1PeXgJVnr2gtU3D+bF32th8fZfQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-3.12.0.tgz", + "integrity": "sha512-Q5S0pYgjqqLeFPaoHaEt9KeNFf5BrobcYmLZ9bsUnSowY0Kxz6RvnPWNNaOI3FhgqCF/e+RmGX20J0wx3Ty04Q==", "requires": { "@types/node-fetch": "^2.1.2", "node-fetch": "~2.6.1" } }, "@tensorflow/tfjs-layers": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-3.11.0.tgz", - "integrity": "sha512-BtLgLucJZHv5te1K3yjT3iZdHXgMJArrLuOb/oRPOtTp4R2ad5N0V2m5RtuZJ3sI5/ah0h72xtmTWNyTv3/5dw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-3.12.0.tgz", + "integrity": "sha512-GlU9LxDnPg3I3p+MMOYzKgr2NZK2vVmT4/EotwMVIAyhR2WbVFTRP0AXkIrWSoNIJ9v/ryvFEvNNPyNfkXM/xQ==", "requires": {} }, "@tensorflow/tfjs-node": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-3.11.0.tgz", - "integrity": "sha512-EFBAkwJDoP4WuiWqjT9ER80dUvilvVFXULlU3WpmVGDluIL/Yq18xEKHvPaYHW5jLq/mvMljLtUBlHqigfvAhw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tensorflow/tfjs-node/-/tfjs-node-3.12.0.tgz", + "integrity": "sha512-Tl4dil1k9Mjj8A4vLxZJqwOhcV8zo2ZE8XCbKCF+B5i0sBJNqej4WzxJvdA5v3xu36D0UrEaWC5miqaX7ODQFw==", "requires": { "@mapbox/node-pre-gyp": "1.0.4", - "@tensorflow/tfjs": "3.11.0", + "@tensorflow/tfjs": "3.12.0", "adm-zip": "^0.5.2", "google-protobuf": "^3.9.2", "https-proxy-agent": "^2.2.1", @@ -2640,9 +2925,9 @@ "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "@types/node": { - "version": "16.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz", - "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==" + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.5.tgz", + "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==" }, "@types/node-fetch": { "version": "2.5.12", @@ -2731,6 +3016,14 @@ "sprintf-js": "~1.0.2" } }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2746,6 +3039,14 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, "bmp-js": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", @@ -2774,6 +3075,15 @@ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "canvas": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz", @@ -2856,6 +3166,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2884,6 +3199,11 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=" + }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", @@ -2943,6 +3263,11 @@ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, "exif-parser": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", @@ -2953,6 +3278,11 @@ "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" }, + "follow-redirects": { + "version": "1.14.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.6.tgz", + "integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==" + }, "form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -2976,6 +3306,11 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -2996,6 +3331,16 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "gifwrap": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz", @@ -3032,16 +3377,72 @@ "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.1.tgz", "integrity": "sha512-Isv1RlNC+IzZzilcxnlVSf+JvuhxmY7DaxYCBy+zPS9XVuJRtlTTIXR9hnZ1YL1MMusJn/7eSy2swCzZIomQSg==" }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.0.0.tgz", + "integrity": "sha512-XTePIXAo5x72bI8SlKFSqsg7UuSHwsOa4+RJIe56YeMUvfTvGDy7TxFkTEhfIRmM/Dnf6x29ut541ythSBZdkQ==", + "requires": { + "basic-auth": "^2.0.1", + "colors": "^1.4.0", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.5", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + } + }, "https-proxy-agent": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", @@ -3051,6 +3452,14 @@ "debug": "^3.1.0" } }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -3125,6 +3534,11 @@ "xtend": "^4.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -3281,6 +3695,11 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + }, "omggif": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", @@ -3294,6 +3713,11 @@ "wrappy": "1" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + }, "pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -3346,6 +3770,16 @@ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + } + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -3361,6 +3795,14 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, + "qs": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", + "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", + "requires": { + "side-channel": "^1.0.4" + } + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -3385,6 +3827,11 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -3398,11 +3845,21 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha1-8aAymzCLIh+uN7mXTz1XjQypmeM=" + }, "seedrandom": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", @@ -3422,6 +3879,16 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", @@ -3522,6 +3989,19 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, + "union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "requires": { + "qs": "^6.4.0" + } + }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, "utif": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", @@ -3540,6 +4020,14 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "requires": { + "iconv-lite": "0.6.3" + } + }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", diff --git a/package.json b/package.json index f5ec99c..554e2b3 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,16 @@ "main": "index.js", "type": "module", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "server": "http-server" }, "author": "", "license": "ISC", "dependencies": { - "@tensorflow/tfjs-node": "^3.11.0", + "@tensorflow/tfjs": "^3.12.0", + "@tensorflow/tfjs-node": "^3.12.0", "canvas": "^2.8.0", + "http-server": "^14.0.0", "jimp": "^0.16.1", "numeral": "^2.0.6" } diff --git a/public/decoder/model/model.json b/public/decoder/model/model.json index 525fea4..f9c2b3b 100644 --- a/public/decoder/model/model.json +++ b/public/decoder/model/model.json @@ -1 +1 @@ -{"modelTopology":{"class_name":"Sequential","config":{"name":"sequential_2","layers":[{"class_name":"Dense","config":{"units":16,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense11","trainable":true,"batch_input_shape":[null,4],"dtype":"float32"}},{"class_name":"Dense","config":{"units":64,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense12","trainable":true,"batch_input_shape":[null,16],"dtype":"float32"}},{"class_name":"Dense","config":{"units":128,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense13","trainable":true,"batch_input_shape":[null,64],"dtype":"float32"}},{"class_name":"Dense","config":{"units":256,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense14","trainable":true,"batch_input_shape":[null,128],"dtype":"float32"}},{"class_name":"Dense","config":{"units":784,"activation":"sigmoid","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense15","trainable":true,"batch_input_shape":[null,256],"dtype":"float32"}}]},"keras_version":"tfjs-layers 3.11.0","backend":"tensor_flow.js"},"weightsManifest":[{"paths":["weights.bin"],"weights":[{"name":"dense_Dense11/kernel","shape":[4,16],"dtype":"float32"},{"name":"dense_Dense11/bias","shape":[16],"dtype":"float32"},{"name":"dense_Dense12/kernel","shape":[16,64],"dtype":"float32"},{"name":"dense_Dense12/bias","shape":[64],"dtype":"float32"},{"name":"dense_Dense13/kernel","shape":[64,128],"dtype":"float32"},{"name":"dense_Dense13/bias","shape":[128],"dtype":"float32"},{"name":"dense_Dense14/kernel","shape":[128,256],"dtype":"float32"},{"name":"dense_Dense14/bias","shape":[256],"dtype":"float32"},{"name":"dense_Dense15/kernel","shape":[256,784],"dtype":"float32"},{"name":"dense_Dense15/bias","shape":[784],"dtype":"float32"}]}],"format":"layers-model","generatedBy":"TensorFlow.js tfjs-layers v3.11.0","convertedBy":null} \ No newline at end of file +{"modelTopology":{"class_name":"Sequential","config":{"name":"sequential_2","layers":[{"class_name":"Dense","config":{"units":16,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense11","trainable":true,"batch_input_shape":[null,4],"dtype":"float32"}},{"class_name":"Dense","config":{"units":64,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense12","trainable":true,"batch_input_shape":[null,16],"dtype":"float32"}},{"class_name":"Dense","config":{"units":128,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense13","trainable":true,"batch_input_shape":[null,64],"dtype":"float32"}},{"class_name":"Dense","config":{"units":256,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense14","trainable":true,"batch_input_shape":[null,128],"dtype":"float32"}},{"class_name":"Dense","config":{"units":784,"activation":"sigmoid","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense15","trainable":true,"batch_input_shape":[null,256],"dtype":"float32"}}]},"keras_version":"tfjs-layers 3.12.0","backend":"tensor_flow.js"},"weightsManifest":[{"paths":["weights.bin"],"weights":[{"name":"dense_Dense11/kernel","shape":[4,16],"dtype":"float32"},{"name":"dense_Dense11/bias","shape":[16],"dtype":"float32"},{"name":"dense_Dense12/kernel","shape":[16,64],"dtype":"float32"},{"name":"dense_Dense12/bias","shape":[64],"dtype":"float32"},{"name":"dense_Dense13/kernel","shape":[64,128],"dtype":"float32"},{"name":"dense_Dense13/bias","shape":[128],"dtype":"float32"},{"name":"dense_Dense14/kernel","shape":[128,256],"dtype":"float32"},{"name":"dense_Dense14/bias","shape":[256],"dtype":"float32"},{"name":"dense_Dense15/kernel","shape":[256,784],"dtype":"float32"},{"name":"dense_Dense15/bias","shape":[784],"dtype":"float32"}]}],"format":"layers-model","generatedBy":"TensorFlow.js tfjs-layers v3.12.0","convertedBy":null} \ No newline at end of file diff --git a/public/decoder/model/weights.bin b/public/decoder/model/weights.bin index a5032ae..bac4c40 100644 Binary files a/public/decoder/model/weights.bin and b/public/decoder/model/weights.bin differ diff --git a/public/index.html b/public/index.html index fb0442d..9d66557 100644 --- a/public/index.html +++ b/public/index.html @@ -11,5 +11,6 @@ + diff --git a/public/model/model.json b/public/model/model.json index cff27a1..0f641af 100644 --- a/public/model/model.json +++ b/public/model/model.json @@ -1 +1 @@ -{"modelTopology":{"class_name":"Sequential","config":{"name":"sequential_1","layers":[{"class_name":"Dense","config":{"units":256,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense1","trainable":true,"batch_input_shape":[null,784],"dtype":"float32"}},{"class_name":"Dense","config":{"units":128,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense2","trainable":true}},{"class_name":"Dense","config":{"units":64,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense3","trainable":true}},{"class_name":"Dense","config":{"units":16,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense4","trainable":true}},{"class_name":"Dense","config":{"units":4,"activation":"sigmoid","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense5","trainable":true}},{"class_name":"Dense","config":{"units":16,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense6","trainable":true}},{"class_name":"Dense","config":{"units":64,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense7","trainable":true}},{"class_name":"Dense","config":{"units":128,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense8","trainable":true}},{"class_name":"Dense","config":{"units":256,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense9","trainable":true}},{"class_name":"Dense","config":{"units":784,"activation":"sigmoid","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense10","trainable":true}}]},"keras_version":"tfjs-layers 3.11.0","backend":"tensor_flow.js"},"weightsManifest":[{"paths":["weights.bin"],"weights":[{"name":"dense_Dense1/kernel","shape":[784,256],"dtype":"float32"},{"name":"dense_Dense1/bias","shape":[256],"dtype":"float32"},{"name":"dense_Dense2/kernel","shape":[256,128],"dtype":"float32"},{"name":"dense_Dense2/bias","shape":[128],"dtype":"float32"},{"name":"dense_Dense3/kernel","shape":[128,64],"dtype":"float32"},{"name":"dense_Dense3/bias","shape":[64],"dtype":"float32"},{"name":"dense_Dense4/kernel","shape":[64,16],"dtype":"float32"},{"name":"dense_Dense4/bias","shape":[16],"dtype":"float32"},{"name":"dense_Dense5/kernel","shape":[16,4],"dtype":"float32"},{"name":"dense_Dense5/bias","shape":[4],"dtype":"float32"},{"name":"dense_Dense6/kernel","shape":[4,16],"dtype":"float32"},{"name":"dense_Dense6/bias","shape":[16],"dtype":"float32"},{"name":"dense_Dense7/kernel","shape":[16,64],"dtype":"float32"},{"name":"dense_Dense7/bias","shape":[64],"dtype":"float32"},{"name":"dense_Dense8/kernel","shape":[64,128],"dtype":"float32"},{"name":"dense_Dense8/bias","shape":[128],"dtype":"float32"},{"name":"dense_Dense9/kernel","shape":[128,256],"dtype":"float32"},{"name":"dense_Dense9/bias","shape":[256],"dtype":"float32"},{"name":"dense_Dense10/kernel","shape":[256,784],"dtype":"float32"},{"name":"dense_Dense10/bias","shape":[784],"dtype":"float32"}]}],"format":"layers-model","generatedBy":"TensorFlow.js tfjs-layers v3.11.0","convertedBy":null} \ No newline at end of file +{"modelTopology":{"class_name":"Sequential","config":{"name":"sequential_1","layers":[{"class_name":"Dense","config":{"units":256,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense1","trainable":true,"batch_input_shape":[null,784],"dtype":"float32"}},{"class_name":"Dense","config":{"units":128,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense2","trainable":true}},{"class_name":"Dense","config":{"units":64,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense3","trainable":true}},{"class_name":"Dense","config":{"units":16,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense4","trainable":true}},{"class_name":"Dense","config":{"units":4,"activation":"sigmoid","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense5","trainable":true}},{"class_name":"Dense","config":{"units":16,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense6","trainable":true}},{"class_name":"Dense","config":{"units":64,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense7","trainable":true}},{"class_name":"Dense","config":{"units":128,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense8","trainable":true}},{"class_name":"Dense","config":{"units":256,"activation":"relu","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense9","trainable":true}},{"class_name":"Dense","config":{"units":784,"activation":"sigmoid","use_bias":true,"kernel_initializer":{"class_name":"VarianceScaling","config":{"scale":1,"mode":"fan_avg","distribution":"normal","seed":null}},"bias_initializer":{"class_name":"Zeros","config":{}},"kernel_regularizer":null,"bias_regularizer":null,"activity_regularizer":null,"kernel_constraint":null,"bias_constraint":null,"name":"dense_Dense10","trainable":true}}]},"keras_version":"tfjs-layers 3.12.0","backend":"tensor_flow.js"},"weightsManifest":[{"paths":["weights.bin"],"weights":[{"name":"dense_Dense1/kernel","shape":[784,256],"dtype":"float32"},{"name":"dense_Dense1/bias","shape":[256],"dtype":"float32"},{"name":"dense_Dense2/kernel","shape":[256,128],"dtype":"float32"},{"name":"dense_Dense2/bias","shape":[128],"dtype":"float32"},{"name":"dense_Dense3/kernel","shape":[128,64],"dtype":"float32"},{"name":"dense_Dense3/bias","shape":[64],"dtype":"float32"},{"name":"dense_Dense4/kernel","shape":[64,16],"dtype":"float32"},{"name":"dense_Dense4/bias","shape":[16],"dtype":"float32"},{"name":"dense_Dense5/kernel","shape":[16,4],"dtype":"float32"},{"name":"dense_Dense5/bias","shape":[4],"dtype":"float32"},{"name":"dense_Dense6/kernel","shape":[4,16],"dtype":"float32"},{"name":"dense_Dense6/bias","shape":[16],"dtype":"float32"},{"name":"dense_Dense7/kernel","shape":[16,64],"dtype":"float32"},{"name":"dense_Dense7/bias","shape":[64],"dtype":"float32"},{"name":"dense_Dense8/kernel","shape":[64,128],"dtype":"float32"},{"name":"dense_Dense8/bias","shape":[128],"dtype":"float32"},{"name":"dense_Dense9/kernel","shape":[128,256],"dtype":"float32"},{"name":"dense_Dense9/bias","shape":[256],"dtype":"float32"},{"name":"dense_Dense10/kernel","shape":[256,784],"dtype":"float32"},{"name":"dense_Dense10/bias","shape":[784],"dtype":"float32"}]}],"format":"layers-model","generatedBy":"TensorFlow.js tfjs-layers v3.12.0","convertedBy":null} \ No newline at end of file diff --git a/public/model/weights.bin b/public/model/weights.bin index e8ec63d..7ea3063 100644 Binary files a/public/model/weights.bin and b/public/model/weights.bin differ