JavaScript Artificial Intelligence

There’s a good chance that you don’t think of JavaScript when you think of artificial intelligence. Instead, you might think of Python and popular libraries like Google’s Tensorflow. While TensorFlow is very powerful and complex, it does require a steep learning curve. Personally, I’m just looking to get my feet wet in some simple AI programming. However, I came across a javascript library called Brain.js. This library makes javascript artificial intelligence plausible and testable.It’s very easy to get started and works within your browser (not recommended though) and NodeJS.

So for this javascript tutorial, I want to create a simple neural network that will be able to predict how long it will take me to run a certain distance. I already have a log of my previous runs that I can feed to the neural network.

Start Node Project

Let’s start by initializing a new node project. Assuming you already have NodeJS installed, type the following in the terminal:

npm init

After going through the package setup, begin by installing the Brain.js module:

npm install brain.js --save

Make sure to include the save parameter so that it is listed in your devDependencies. Awesome, now create an index.js file in your project and you are ready to begin coding.

Javascript Artificial Intelligence

In your index.js file, begin by importing the brain.js module:

const brain = require('brain.js)

Now we need to create a network variable. Brain.js allows you to choose between a feedforward network and recurrent network. For this tutorial, we are just going to use a feedforward network.

var net = new brain.NeuralNetwork()

Neural Network Training

The next thing you need to do is feed data to your network. This data should consist of inputs along with their ideal outputs. However, neural networks are very picky when it comes to their accepted data input. You can only input and output data that is an array of values consisting of the numbers between 0 and 1 (or -1 and 1 in some cases, but not Brain.js).

An acceptable input and output could match one of these examples:

input: [0], output: [1]

input:[0.5], output: [0.7]

input: {r: 1, b:0}, output: {r:0.5,b:0.2}

If we were working with strings, then we would need to find a way to encode the strings so that they satisfy the input/output requirements.

So what I need to do is give the miles I ran as input to the neural network, and the time (in minutes) it took as output. Essentially, I want the following:

input:[3.2], output: [30]

Unfortunately, this does not satisfy the requirement and you will receive an error if you try to use those values as inputs. Therefore, we need to normalize the data. The best way to do this is put these numbers are percentages. So let’s say I can run between 0 – 5 miles on any given day and it would take me between 0 – 60 minutes. Therefore, if I ran 3.2 miles I ran 0.64 (3.2/5) percent and my time was 0.5 (30/60) percent. Got it? Good! Let’s continue coding.

Create an array that will hold  objects of training data:

Now that you have the array, let’s send it to the network:

In the previous line, we sent the ops array as the data for the network to train with. We also enabled logging so that we can see the output as it’s iterating. Since we are working with a small dataset set, we might not get accurate results. Therefore, I set the error threshold to a really small value. The goal is to get it as close to zero as possible. However, if we don’t specify the iterations then the program will keep looping through to try to get below that error threshold which will never happen. So to prevent this from happening we are setting the iterations to 50. If we had a much larger dataset then we would not need to worry about this.

Finally, let’s test the network. I want it to predict how long it’s going to take me to run 3.1 miles (or 0.62 of the range):

console.log(net.run([0.62]))

The output I got is 0.51 which translates to 30 minutes. I run an average of 10 minutes a mile, so I can say this result is accurate. Here is our final project:

Bonus

As a little experiment, I added in over 20,000 entries. Of course, I didn’t hard code this. I used the following lines:

The following lines add more training data to the array. For the inputs and outputs, I generate random numbers within a given range. Therefore, my inputs consist of numbers whose range is between 3.25 miles and 3.75 (exclusive) miles. My output consists of minutes between 28.8 and 35.4 minutes. Now when I run the network with the same 0.62 input, I get 0.53 as my output which translates to 31.8 minutes. Considering that this was arbitrary data, the result is still accurate.