From 09febb40bf20ae74d25b17f0e27ff5c3d0117f38 Mon Sep 17 00:00:00 2001 From: AR-234 Date: Sun, 11 Feb 2018 15:12:23 +0100 Subject: [PATCH 1/2] Added Multilayer Support --- lib/nn.js | 164 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 85 insertions(+), 79 deletions(-) diff --git a/lib/nn.js b/lib/nn.js index c6e3ad2..3782e13 100644 --- a/lib/nn.js +++ b/lib/nn.js @@ -13,41 +13,47 @@ function dsigmoid(y) { class NeuralNetwork { constructor(input_nodes, hidden_nodes, output_nodes) { this.input_nodes = input_nodes; - this.hidden_nodes = hidden_nodes; + // Checking if hidden nodes is an integer + // If so convert it to an array with one entry + if(Number.isInteger(hidden_nodes)){ + this.hidden_nodes = [hidden_nodes]; + }else{ + this.hidden_nodes = hidden_nodes; + } this.output_nodes = output_nodes; - this.weights_ih = new Matrix(this.hidden_nodes, this.input_nodes); - this.weights_ho = new Matrix(this.output_nodes, this.hidden_nodes); - this.weights_ih.randomize(); - this.weights_ho.randomize(); - - this.bias_h = new Matrix(this.hidden_nodes, 1); - this.bias_o = new Matrix(this.output_nodes, 1); - this.bias_h.randomize(); - this.bias_o.randomize(); this.setLearningRate(); this.setActivationFunction(); this.setDActivationFunction(); + + // Creating the Layers of the Neural Network + // ! The last Layer is the output layer + this.layer = []; + this.layer.push(new NeuralNetworkLayer(this, this.input_nodes, this.hidden_nodes[0])); + // Loop hidden layers except for the first and last, set manuelly + for (let i = 1; i < this.hidden_nodes.length; i++) { + // input_nodes for NeuralNetworkLayer is always the previous Layer + this.layer.push(new NeuralNetworkLayer(this, this.hidden_nodes[i-1],this.hidden_nodes[i])); + } + // hidden_nodes.length is the last entry at that time + this.layer.push(new NeuralNetworkLayer(this, this.hidden_nodes[this.hidden_nodes.length-1],this.output_nodes)); + } predict(input_array) { - // Generating the Hidden Outputs let inputs = Matrix.fromArray(input_array); - let hidden = Matrix.multiply(this.weights_ih, inputs); - hidden.add(this.bias_h); - // activation function! - hidden.map(this.activation_function); - - // Generating the output's output! - let output = Matrix.multiply(this.weights_ho, hidden); - output.add(this.bias_o); - output.map(this.activation_function); - - // Sending back to the caller! - return output.toArray(); + + let prediction = inputs; + // Loop layer over the inputs + for (let i = 0; i < this.layer.length; i++) { + prediction = this.layer[i].predict(prediction); + } + + // Sending prediction to the caller! + return prediction.toArray(); } setLearningRate(learning_rate = 0.1) { @@ -62,80 +68,80 @@ class NeuralNetwork { this.d_activation_function = dFun; } - train(input_array, target_array) { - // Generating the Hidden Outputs + train(input_array, target_array) { + // Convert input arrays to matrix objects let inputs = Matrix.fromArray(input_array); - let hidden = Matrix.multiply(this.weights_ih, inputs); - hidden.add(this.bias_h); - // activation function! - hidden.map(this.activation_function); - - // Generating the output's output! - let outputs = Matrix.multiply(this.weights_ho, hidden); - outputs.add(this.bias_o); - outputs.map(this.activation_function); - - // Convert array to matrix object let targets = Matrix.fromArray(target_array); + let predictions = []; + let prediction = inputs; + // Loop layer over the inputs + for(let i=0;i