diff --git a/lib/nn.js b/lib/nn.js index 5cce746..0635a02 100644 --- a/lib/nn.js +++ b/lib/nn.js @@ -21,40 +21,44 @@ let tanh = new ActivationFunction( 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(); + // 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)); + this.setLearningRate(); - this.setActivationFunction(); - + } 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.func); - - // Generating the output's output! - let output = Matrix.multiply(this.weights_ho, hidden); - output.add(this.bias_o); - output.map(this.activation_function.func); - - // 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) { @@ -65,80 +69,100 @@ class NeuralNetwork { this.activation_function = func; } - 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.func); - - // Generating the output's output! - let outputs = Matrix.multiply(this.weights_ho, hidden); - outputs.add(this.bias_o); - outputs.map(this.activation_function.func); - - // 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