javascriptneural-networkbrain.js

Neural Network in JavaScript


I'm having a little trouble with my neural network. I've set it up so it generates an array with 5 values; 0 or 1, i.e [1,1,0,1,0]. And using Node.js I console log the random array, and if I reply with y it will add it to the training with the correct output, and vice versa. Once I have responded, the genRan() runs and creates a new random array and saves the "guess" to var guess. However, after the first run, it no longer gives me a guess value, instead: [object Object].

Here is the code:

var brain = require('brain.js');
var net = new brain.NeuralNetwork();
const readline = require('readline');

const r1 = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

var ca = 0,
    wa = 0;

net.train([
    {input: [0,0,0,0,0], output: [0]}
]);

function genRan(){
    var a,b,c,d,e;
    var array = [];
    a = Math.round(Math.random());
    b = Math.round(Math.random());
    c = Math.round(Math.random());
    d = Math.round(Math.random());
    e = Math.round(Math.random());

    array.push(a,b,c,d,e);
    var guess = net.run(array);
    ask(array,guess);
}

function ask(a,b){
    var array = a,
        guess = b;
    r1.question((wa+ca) + ") input: " + array + " We think: " + guess + ". Am I correct? (Y/N)", (answer) => {

        if(answer == "Y" || answer == "y"){
            ca++;
            net.train([
                {input : array, output : Math.round(guess)}
            ]);
        }else if(answer == "N" || answer == "n"){
            wa++;
            var roundGuess = Math.round(guess);
            var opposite;
            switch (roundGuess){
                case 1:
                    opposite = 0;
                    break;
                case 0:
                    opposite = 1;
                    break;
                default:
                    opposite = null
            }
            net.train([
                {input : array, output : opposite}
            ]);     
        }
        console.log("Success percent: " + (100 *ca/(ca+wa)) + "% " + (ca+wa) +" attempts\n\r");
        genRan();
    })

}
genRan();

The first question works fine, and presents this:

0) input: 0,0,0,0,0 We think: 0.07046. Am I correct? (Y/N)

When I respond, I get:

Success percent: 100% 1 attempts

1) input 1,1,1,0,1 We think: [object Object]. Am I correct? (Y/N)

For some reason, when it goes to "guess" it doesn't give me a value. Any ideas why?


Solution

  • The reason its gone wrong is twofold

    1. The output of net.run is an array - you probably want the first item from it.
    2. The input to output in net.train is an array - you're passing it a distinct value

    With a few changes your code works as (I think) you expect it:

    1. Use guess[0] in your ask method throughout
    2. Wrap the oposite variable in square braces to make it an array

       net.train([
              {input : array, output : [opposite]}
          ]);     
      

    Working code below for reference (Will not work in stacksnippet though)

    var brain = require('brain.js');
    var net = new brain.NeuralNetwork();
    const readline = require('readline');
    
    const r1 = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });
    
    var ca = 0,
        wa = 0;
    
    net.train([
        {input: [0,0,0,0,0], output: [0]}
    ]);
    
    function genRan(){
        var a,b,c,d,e;
        var array = [];
        a = Math.round(Math.random());
        b = Math.round(Math.random());
        c = Math.round(Math.random());
        d = Math.round(Math.random());
        e = Math.round(Math.random());
    
        array.push(a,b,c,d,e);
        //console.log(array);
        var guess = net.run(array);
        ask(array,guess);
    }
    
    function ask(a,b){
        var array = a,
            guess = b;
        r1.question((wa+ca) + ") input: " + array + " We think: " + guess[0] + ". Am I correct? (Y/N)", (answer) => {
    
            if(answer == "Y" || answer == "y"){
                ca++;
                net.train([
                    {input : array, output : Math.round(guess[0])}
                ]);
            }else if(answer == "N" || answer == "n"){
                wa++;
                var roundGuess = Math.round(guess[0]);
                var opposite;
                switch (roundGuess){
                    case 1:
                        opposite = 0;
                        break;
                    case 0:
                        opposite = 1;
                        break;
                    default:
                        opposite = null
                }
                net.train([
                    {input : array, output : [opposite]}
                ]);     
            }
            console.log("Success percent: " + (100 *ca/(ca+wa)) + "% " + (ca+wa) +" attempts\n\r");
            genRan();
        })
    
    }
    genRan();