Learn and Play with TensorFlow.js [Part 2: Binary Classifier]

After we tried training a linear regression model with TensorFlow.js in previous chapter, let’s try to move on to the next case, which is the classification for two data classes using a 2-layer Artificial Neural Network.

2-Layer Neural Network

Artificial Neural Networks can be seen as a stack of several linear functions, as in the regression function that we have tried before. At the end of each linear function is given a non-linear function called the activation function. A linear function along with its activation function is called a Neuron. A group of neurons is called a Layer.

Using only one Layer of neurons is called a Single-layer Neural Networks. And stacks those layers together, we get a Multi-layered Neural Networks. By stacking multiple layers together, it will give us a model that has better capabilities than just using one layer.

The first layer in Neural Network is called Input Layer, which is not a neuron layer. It does not do any computation, it is just a layer to receive input data. The last layer is called Output layer. And all layers stacked between input and output is usually called Hidden Layer.

Here we will use a simple 2 Layer Artificial Neural Network. This means that there are 2 stacks of linear functions (dense) with activation functions in between. Generally the activation function used is the sigmoid function.

To build this example, first let’s create a new directory called part_2

Binary Class Data Generator

For this classification example, we need to generate a set of training data. So create a new Javascript file, named data.js and put it inside part_2 directory.

Because JavaScript can only do normal random function, let’s define a function to perform peudo-gaussian random inside data.js. Here we also define generateData() function to produce a number of two-dimensional data with class proportions between classes 0 and 1 equal to frac.

Data is generated in data points, then 30% of the data will be used as Validation Data. Data is returned in arrays for the training process and in point format for visualization.

Main Page

Next, create a new index.html file and put it inside part_2 directory as well. The main page will consist of 3 parts:

  • The first part is where we display the distribution of training and validation data. Here we’ll use Chart.js.
  • We use the second part to initialize, train, and test network model. The training and testing section is put each in a column.
  • While the third part will be used to display progress during the training process using tfjs-vis.

Data Visualization

In data visualization section, create two canvas inside columns to show the training and validation data.

Training Section

In this classification case, we will use a 2-layered network architecture. The last layer has 1 neuron (since it’s binary class), while neuron in the first hidden layer is set to a dynamic number according to user input. For that, add input text to change the number of hidden neurons. We also add a couple other input to change the learning rate and maximum epoch. In addition to that, add two buttons to initialize the model and start training, and two badges to show train and validation accuracy after training.

Testing Section

In the test column, add two input texts to receive a new data and a button to do the test. We also include a badge to display the predicted class.

Again, initially, we disabled both the Train and Test buttons. Train button will be activated after model has been initialized, while the Test button will be activated when the model has been trained.

Training Progress Visualization

In this third part, we visualize loss and accuracy during the training.

index.js

Just as before, add new index.js file in part_2 directory. In this .js file we import all the libraries we need. Don’t forget to import the generateData() function from data.js.

As we’re going to display the loss and accuracy graph during training, we’ll use await keyword to execute asynchronous fit() function. For that, we’ll use babel-polyfill library to process the asynchronous functions. To download and use the library, we simply add require in index.js file.

At this stage we can try and deploy web application by executing command below.

\ai_tfjs> parcel part_2\index.html

Generate and Visualize Dataset

But at this point, you can see that there’s still no data to display. So then let’s generate 100 data using the generateData() function. For this example, we set the class ratio between class 0 and 1 to be 60:40. Then data generated, cast it to tensor according to their respective sizes.

After we generate the dataset, let’s visualize it on the canvas by adding codes below.

Note that in the visualization of validation data, we provide space for three data each to visualize data class 0, class 1, and new data test to be entered by user during testing.

Init Button

Now let’s add the Event Listener to initialize the model. Like before, we define model as global variable. When the button is pressed, take the integer number of hidden neuron and the float learning rate, then define the model.
After being defined, compile the model using SGD as the optimizer, binary cross entropy for loss calculation, and accuracy as the metrics. Lastly, activate the Train button.

Train Button

To display the history of training progress during the asynchronous fit() function is executed, we’ll use await keyword. Executing await keyword must be done inside another asynchronous function. Therefore, we define click action event on train-btn as asynchronous.

When the button is clicked, first show the message saying that the model is being trained. Next get div section for loss and accuracy graph visualization, and get the maximum epoch input from user. Finally call model.fit() function and pass x_train and y_train tensor as the training data. Along with that, pass additional attribute epochs, as well x_val and y_val as validationData.

Here, we’re introduced to callbacks. A callback is a set of functions to be applied at given stages of the training procedure. It is usually used to get a view on internal states and statistics of the model during training. We set the callback to be executed each time an epoch is finished. Inside the callback, we’ll use tfjs-vis library to show the history of loss and accuracy to their respective visualization section using show.history() function.

After fit() function is executed, add code to evaluate the model and get the trainset and validationset accuracy. Lastly, change the message saying that the training has finished, display the accuracy, and turn on the prediction button.

Predict Button

Now we add the event listener to the predict button. When the button is pressed, take and parse the new data entered by user, then display the new data point in the validation data scatter chart. Finally, predict the class of the new data using the model that we have trained by calling predict() function.

Final Result

Our Binary classifier application is ready to try. Executing command below to deploy the application.

\ai_tfjs> parcel part_2\index.html

If you initialize the model, and start the training followed by testing the model, the application view will look like the one shown below

And that’s all for the second chapter. For the next chapter, we’ll see a popular example in every Machine Learning Tutorial. It’s very popular since it’s fairly easy, yet it gives a bit more challenge in Classification.

The MNIST Digit Classification case

See you in the next chapter

--

--

anditya.arifianto
Artificial Intelligence Laboratory — Telkom University

Lecturer at Telkom University, Software Engineer, Artificial Intelligence and Deep Learning Enthusiast