# Tensor Operations

### Let's get **physical**

Sometimes, nothing beats holding a copy of a book in your hands. Writing in the margins, highlighting sentences, folding corners. So this book is also available from Amazon as a paperback.

You can perform operations on Tensors, such as addition, which return new Tensors. TensorFlow.js has an extensive library^{[1]} of available operations, which you are encouraged to review. In this course, we will only be covering the *essential* operations required to understand the example applications we are building.

## Addition

We perform element-wise addition via the `add`

function; this sums two Tensors together using *pair wise* addition, like so:

```
var a = tf.tensor([3, 8, 4, 6], [2, 2]);
var b = tf.tensor([4, 0, 1, -9], [2, 2]);
a.add(b).print();
```

The shape of both the Tensors should be the same to perform element wise addition otherwise it will print an error to the console, like so:

```
var a = tf.tensor([3, 8, 4, 6], [2, 2]);
var b = tf.tensor([4, 0, 1], [2, 1]);
a.add(b).print(); // This will print an error
```

## Broadcasting

When the shapes allow, TensorFlow.js will perform an action called *broadcasting* instead of reporting an error, like so:

```
var a = tf.tensor([3, 8, 4, 6], [2, 2]);
var b = tf.tensor([4, 0], [2]);
a.add(b).print();
```

Even though the shape of `a`

and `b`

are different, the `add`

operation completed successfully and resulted in a Tensor like so:

Tensor [[7, 8], [8, 6]]

Broadcasting is the process of *automatically adjusting* matrices to have compatible shapes for arithmetic operations.

Broadcasting means that an operation like so:

```
var a = tf.tensor([3, 8, 4, 6], [2, 2]);
var b = tf.tensor([4, 0], [2]);
a.add(b).print();
```

Was transformed internally into:

```
var a = tf.tensor([3, 8, 4, 6], [2, 2]);
var b = tf.tensor([4, 0, 4, 0], [2, 2]);
a.add(b).print();
```

The data was copied in `b`

, so the shape of `b`

ended up matching the shape of `a`

.

There are specific rules that broadcasting follows, which are documented^{[2]} on the TensorFlow website.

The most common use case, and the use case used in all the examples in this course, is broadcasting with scalars. Doing an addition with any scalar value will result in an element wise addition like so:

```
var a = tf.tensor([3, 8, 4, 6], [2, 2]);
var b = tf.scalar(2);
a.add(b).print();
```

This results in:

```
Tensor
[[5, 10],
[6, 8 ]]
```

And is equivalent to:

```
var a = tf.tensor([3, 8, 4, 6], [2, 2]);
var b = tf.tensor([2, 2, 2, 2], [2, 2]);
a.add(b).print();
```

## Subtraction, Division, and Multiplication

Similar to addition, the `sub`

function performs *element wise* subtraction between two Tensors. The `div`

function performs *element wise* division between two Tensors, and the `mul`

function performs *element wise* multiplication.

#### Note

## Mean Squared Error

Let’s follow on from our

Let’s imagine two Tensors represent black and white images, like so:

```
var a = tf.tensor([200, 176, 3, 34], [2,2]);
var b = tf.tensor([213, 132, 0, 98], [2,2]);
```

#### Note

*very*small images, but the algorithm will work for any size image.

First, we might try subtracting one Tensor from the other. The closer to 0 the resulting Tensor is the closer the images are, like so:

`a.sub(b).print()`

This results in:

```
Tensor
[[-13, 44 ],
[3 , -64]]
```

The `mean`

of all the values would give us a *single number* that defines how close the images are, like so:

`a.sub(b).mean().print()`

This results in:

```
Tensor
-7.5
```

Comparing the same image with itself returns 0, like so:

`a.sub(a).mean().print()`

This results in:

```
Tensor
0
```

So it might seem at first glance that this algorithm does a good job, but what if we compared `b`

with `a`

instead of `a`

with `b`

, like so:

`b.sub(a).mean().print()`

This results in:

```
Tensor
7.5
```

The result here is positive, whereas the result before was negative. That’s not ideal; the order of comparison shouldn’t matter. The main issue here is that the Tensor we are averaging has a mixture of positive and negative numbers like so:

```
Tensor
[[-13, 44 ],
[3 , -64]]
```

We want all the numbers to be positive, an operation that can help us here is `square`

, if we ran:

`a.sub(b).square().print()`

This results in:

```
Tensor
[[169, 1936],
[9 , 4096]]
```

And since all the numbers are now positive then the mean won’t change regardless of the order of comparison:

`a.sub(b).square().mean().print()`

and

`b.sub(a).square().mean().print()`

both return:

```
Tensor
1552.5
```

and comparing `a`

with itself returns 0 like so:

`a.sub(a).square().mean().print()`

returns:

```
Tensor
0
```

In machine learning, you will often have to decide on an algorithm to determine if two *things* are close to each other. For various reasons, *Mean Squared Error* is a good algorithm to use, so it’s used frequently throughout this course and in real-life.

## Summary

Operations are functions that run on Tensors and return other Tensors. There are many operations.^{[1]} that you can find on the TensorFlow.js website.

In this course, To complete all the example projects, you will only need to know, `add`

, `sub`

, `div`

, `mul`

, `mean`

and `square`

.

**Advanced** JavaScript

This unique course teaches you advanced JavaScript knowledge through a series of interview questions. Bring your JavaScript to the 2021's **today**.

[🌲,🌳,🌴].push(🌲)If you find my courses useful, please consider

**planting a tree on my behalf**to combat climate change. Just $4.50 will pay for 25 trees to be planted in my name. Plant a tree!