TensorFlowJS :  Introduction To TensorFlowJS For JavaScript Developers

Mohamad MahmoodMohamad Mahmood
6 min read

What is TensorFlowJS?

TensorFlow.js is an open-source, hardware-accelerated JavaScript library that enables developers to build, train, and deploy machine learning models directly in web browsers and Node.js environments, allowing for the creation of interactive client-side AI applications, seamless model conversion from other deep learning frameworks, and hardware-accelerated model execution, all while integrating well with popular JavaScript frameworks like React and Angular, and supporting deployment to mobile devices through TensorFlow Lite.


Literally, TENSOR is a muscle that stretches a part. (https://www.merriam-webster.com/dictionary/tensor)

In Math, it is a mathematical entity with components that change in a particular way in a transformation from one coordinate system to another. (https://www.dictionary.com/browse/tensor)


TensorFlowJS Concept

In TensorFlow.js, the core concept of a tensor is implemented through the tf.Tensor class. A tensor in TensorFlow.js is a multi-dimensional array.

The following is an example of creating a tensor in TensorFlow.js:

<html>
<head>
  <title>TensorFlow.js Example</title>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.18.0/dist/tf.min.js"></script>
</head>
<body>
  <h1>TensorFlow.js Example</h1>
  <script>
    // Create a 2x3 tensor
    const tensor = tf.tensor([
      [1, 2, 3],
      [4, 5, 6]
    ]);
    console.log(tensor);
  </script>
</body>
</html>

Console output:

Tensor
   [[1, 2, 3],
    [4, 5, 6]]

Inside the <script> block in the above example, we create a 2-dimensional tensor (a matrix) with 2 rows and 3 columns by passing a nested array to the tf.tensor() function, just like in the previous examples. The resulting tensor variable is an instance of the tf.Tensor class, which we can log to the console to inspect its contents.

Why use Tensor?

The main benefit of holding values in a matrix representation, or as tensors, is that it allows for efficient and powerful data manipulation and processing, particularly in the context of machine learning and deep learning.

Case Study: A Simple Prediction Using TensorFlowJS

This case study is based on the official tutorial at https://www.tensorflow.org/js/tutorials

Full code:

<html>

<head>
  <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"> </script>
</head>

<body>
  <h4>Tiny TFJS example
    <hr />
  </h4>
  <div id="micro-out-div">Training...</div>
  <script>
    // Tiny TFJS train / predict example.
    async function run() {
      // [1] Create a simple model.
      const model = tf.sequential();
      model.add(tf.layers.dense({
        units: 1,
        inputShape: [1]
      }));
      // [2] Prepare the model for training: Specify the loss and the optimizer.
      model.compile({
        loss: 'meanSquaredError',
        optimizer: 'sgd'
      });
      // [3] Generate some synthetic data for training. (y = 2x - 1)
      const xs = tf.tensor2d([-1, 0, 1, 2, 3, 4], [6, 1]);
      const ys = tf.tensor2d([-3, -1, 1, 3, 5, 7], [6, 1]);
      // Train the model using the data.
      await model.fit(xs, ys, {
        epochs: 250
      });
      // [4] Use the model to predict
      // i.e. do inference on a data point the model hasn't seen.
      // Should print approximately 39.
      document.getElementById('micro-out-div').innerText =
        model.predict(tf.tensor2d([20], [1, 1])).dataSync();
    }
    run();
  </script>
</body>

</html>

Code Explanation:

[1] Create a simple model

// [1] Create a simple model.
      const model = tf.sequential();
      model.add(tf.layers.dense({
        units: 1,
        inputShape: [1]
      }));

This code creates a simple sequential model in TensorFlow.js with a single dense (fully connected) layer. The model takes a 1-dimensional input tensor (a vector with a single value) and has a single output neuron, essentially learning a linear function that maps the input to the output. This basic model structure is a common starting point for simple machine learning tasks, where the goal is to learn a relationship between a single input feature and a single output or target variable.

[2] Prepare the model for training: Specify the loss and the optimizer

// [2] Prepare the model for training: Specify the loss and the optimizer.
      model.compile({
        loss: 'meanSquaredError',
        optimizer: 'sgd'
      });

This code configures the training setup for the TensorFlow.js model by specifying the loss function and the optimization algorithm. The loss function is set to meanSquaredError, which calculates the average of the squared differences between the predicted outputs and the true outputs, and the model will aim to minimize this loss during training. The optimizer is set to sgd, which stands for Stochastic Gradient Descent, a widely used optimization algorithm that adjusts the model’s internal parameters (weights and biases) in the direction of the negative gradient of the loss function to gradually improve the model’s performance and make its predictions as close as possible to the true outputs.

[3] Generate some synthetic data for training (y = 2x — 1)

// [3] Generate some synthetic data for training. (y = 2x - 1)
      const xs = tf.tensor2d([-1, 0, 1, 2, 3, 4], [6, 1]);
      const ys = tf.tensor2d([-3, -1, 1, 3, 5, 7], [6, 1]);
      // Train the model using the data.
      await model.fit(xs, ys, {
        epochs: 250
      });

This code block first generates a synthetic dataset for training, where the input feature xs is a 6x1 tensor of values -1, 0, 1, 2, 3, and 4, and the corresponding output or target values ys are calculated using the linear formula y = 2x — 1, resulting in a 6x1 tensor of values -3, -1, 1, 3, 5, and 7. It then trains the previously created TensorFlow.js model on this dataset by calling the fit() method, specifying the input features xs, the target values ys, and the number of training iterations (epochs) as 250, allowing the model to learn the underlying linear relationship between the input and output variables.

You can omit the [6, 1] shape specification when creating the tensors, and TensorFlow.js will automatically infer the shape. The benefit of omitting the shape specification is that your code becomes more concise and easier to read. However, explicitly specifying the shape can be useful in certain cases, such as:

  1. When the shape is not immediately obvious from the input data.

  2. When you want to ensure that the tensor has a specific shape, and you want to catch any shape mismatch errors early.

  3. When you’re dealing with higher-dimensional tensors, where specifying the shape can make the code more readable.

[4] Use the model to predict

// [4] Use the model to predict
      // i.e. do inference on a data point the model hasn't seen.
      // Should print approximately 39.
      document.getElementById('micro-out-div').innerText =
        model.predict(tf.tensor2d([20], [1, 1])).dataSync();

This code demonstrates how to use the trained TensorFlow.js model to make a prediction on a new, unseen data point by creating a 1x1 tensor with the value 20, passing it through the predict() method of the model, and extracting the predicted output value using the dataSync() method, which is then displayed in an HTML element with the ID ’micro-out-div’. This showcases how the model can be applied for inference, leveraging the linear relationship y = 2x — 1 that it has learned during the previous training process on the synthetic dataset.

Equivalent Python codes

import tensorflow as tf
import numpy as np

# Tiny TensorFlow example
def run():
    # [1] Create a simple model.
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(units=1, input_shape=[1]))

    # [2] Prepare the model for training: Specify the loss and the optimizer.
    model.compile(loss='mean_squared_error', optimizer='sgd')

    # [3] Generate some synthetic data for training. (y = 2x - 1)
    xs = np.array([-1, 0, 1, 2, 3, 4], dtype=float).reshape(-1, 1)
    ys = np.array([-3, -1, 1, 3, 5, 7], dtype=float).reshape(-1, 1)

    # Train the model using the data.
    model.fit(xs, ys, epochs=250)

    # [4] Use the model to predict
    # i.e., do inference on a data point the model hasn't seen.
    # Should print approximately 39.
    prediction = model.predict(np.array([[20]]))
    print(prediction)

# Run the function
run()

Colab Notebook:

https://colab.research.google.com/drive/1-ApBQVpWfND7l2tyVUWW1oDKkd6c-Veq?usp=sharing

0
Subscribe to my newsletter

Read articles from Mohamad Mahmood directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mohamad Mahmood
Mohamad Mahmood

Mohamad's interest is in Programming (Mobile, Web, Database and Machine Learning). He studies at the Center For Artificial Intelligence Technology (CAIT), Universiti Kebangsaan Malaysia (UKM).