# Tensors and Operations

In this article, we are going to discuss tensors and their operation.

**Introduction:** TensorFlow.js is a library to define and run computations using tensors in JavaScript. A tensor is a generalization of vectors and matrices to higher dimensions.

**Tensors:** The central unit of data in TensorFlow.js is the **tf.Tensor **– a set of values shaped into an array of one or more dimensions. **tf.Tensor **are very similar to multidimensional arrays.

A **tf.Tensor **also contains the following properties:

**rank:**Defines how many dimensions the tensor contains.**shape:**Which defines the size of each dimension of the data.**dtype:**Which defines the data type of the tensor.

**Note:** We will use the term “dimension” interchangeably with the rank. Sometimes in machine learning,

“dimensionally” of a tensor can also be referred to as the size of a particular dimension (e.g a matrix of shape[10, 5] is a rank-2 tensor or a 2-dimensional tensor. The dimensionality of the first dimension is 10. This can be confusing, but we put this note here because you will likely come across these dual uses of the term).

A **tf.Tensor** can be created from an array with the **tf.Tensor() **method.

## JavaScript

`// Create a rank-2 tensor (matrix) matrix` `// tensor from a multidimensional array` `const a = tf.tensor([[1,2], [3,4]]);` `console.log(` `'shape:'` `, a.shape);` `a.print();` ` ` `// Or you can create a tensor from a` `// flat array and specify a shape.` `const shape = [2, 2];` `const b = tf.tensor([1,2,3,4], shape);` `console.log(` `'shape:'` `, b.shape);` `b.print();` |

**Output:**

shape: 2,2 Tensor [[1, 2], [3, 4]] shape: 2,2 Tensor [[1, 2], [3, 4]]

By default, **tf.Tensor** will have a **float32** **dtype**. **tf.Tensor **can also be created with bool, int32, complex64, and using dtypes:

## JavaScript

`const a = tf.tensor([[1,2], [3,4]], [2,2], ` `'int32'` `);` `console.log(` `'shape:'` `, a.shape);` `console.log(` `'dtype'` `, a.dtype);` `a.print();` |

**Output:**

shape: 2, 2 dtype int32 Tensor [[1, 2], [3, 4]]

TensorFlow.js also provides a set of convenient methods for creating random tensors, tensors filled with a particular value, tensors from **HTMLImageElement **s, and many more.

**Changing the shape of a Tensor:** The number of elements in a **tf.Tensor **is the product of the size in its shape. Since oftentimes there can be multiple shapes of the same size, it’s often useful to be able to reshape a **tf.Tensor** to another shape of the same size. This can be achieved with the **reshape()** method.

## JavaScript

`const a = tf.tensor([[1,2], [3,4]]);` `console.log(` `'a shape:'` `, a.shape);` `a.print();` `const b = a.redshape([4,1]);` `console.log(` `'b shape:'` `, b.shape);` `b.print();` |

**Output:**

a=array([1, 2, 3, 4])

**Getting values from a Tensor:** You can also get the values form a **tf.Tensor** using th**e Tensor.array() **or ** Tensor.data() ** methods:

## JavaScript

`const a = tf.tensor([[1,2], [3,4]]);` `// Returns the multi-dimensional array of values` `a.array().then(array => console.log(array));` `// Returns the flattened data that backs the tensor` `a.data().then(data => console.log(data));` |

**Output:**

Tensor [1, 2, 3, 4]

We also provide synchronous versions of this method which are simpler to use but will cause performance issues in your application. You should always prefer the synchronous methods in production applications.

## JavaScript

`const a = tf.tensor([[1,2],[3,4]]);` `// Returns the multi dimensional array of values` `console.log(a.arraySync());` `// Returns the flattened data that backs the tensor` `console.log(a.dataSync());` |

**Output:**

a = [1, 2, 3, 4]

**Operations:** While tensors allow you to store data, operations (ops) allow you to manipulate that data. TensorFlow.js provides a wide variety of ops suitable for linear algebra and machine learning that can be performed on tensors.

**Example:** Computing x^2 of al element in a **tf.Tensor:**

## JavaScript

`const x = tf.tensor([1,2,3,4]);` `// Equivalent to tf.square(x)` `const y = x.square(); ` `y.print();` |

Output for the above code: y=x([1, 4, 9, 16 ] )

**Example:** Adding elements of two **tf.Tensor **element-wise:

## JavaScript

`const a = tf.tensor([1,2,3,4]);` `const b = tf.tensor([10,20,30,40]);` `// Equivalent to tf.add(a,b)` `const y = a.add(b);` `y.print();` |

**Output:**

numpy = array([ 11, 22, 33, 44 ])

Because tensors are immutable, these ops do not change their values. Instead, ops return always return new **tf.Tensor **s.

**Memory:** When using the WebGL backend, **tf.Tensor **memory must be managed explicitly (it is not **sufficient** to let a **tf.tensor** go out of scope for its memory to be released).

To destroy the memory of a tf.Tensor, you can use the **dispose() **method or **tf.dispose()**:

It is very common to chain operations together in an application. Holding a reference to all of the intermediate variables to dispose of them can reduce code readability. To solve this problem, TensorFlow.js provides a **tf.tidy() **method which cleans up all **tf.Tensor **s that are not returned by a function after executing it, similar to the way local variables are cleaned up when a function is executed:

## JavaScript

`const a = tf.tensor([[1,2],[3,4]]);` `const y = tf.tidy(() => {` `const result = a.square().log().neg();` `return` `result;` `});` |

**Output:**

In this example, the result of square() and log() will automatically be disposed of. The result of neg() will not be disclosed as it is the return value of the tf.tidy().

You can also get the number of Tensors tracked by TensorFlow.js:

## JavaScript

`console.log(tf.memory());` |

**Output:**

It will display a message on the console while debugging. e.g console.log("Hello World"); Now if we run this using -- node helloworld.js It will print--- Hello World

The object printed by **tf.memory() ** will contain information about how much memory is currently allocated.