## Simple computations

First, we're going to take a look at the tensor object type. Then we'll have a graphical understanding of TensorFlow to define computations. Finally, we'll run the graphs with sessions, showing how to substitute intermediate values.

### Defining scalars and tensors

The first thing you need to do is download the source code pack for this book and open the `simple.py`

file. You can either use this file to copy and paste lines into TensorFlow or CoCalc, or type them directly yourselves. First, let's import `tensorflow`

as `tf`

. This is a convenient way to refer to it in Python. You'll want to hold your constant numbers in `tf.constant`

calls. For example, let's do `a = tf.constant(1)`

and `b = tf.constant(2)`

:

import tensorflow as tf # You can create constants in TF to hold specific values a = tf.constant(1) b = tf.constant(2)

Of course, you can add and multiply these to get other values, namely `c`

and `d`

:

# Of course you can add, multiply, and compute on these as you like c = a + b d = a * b

TensorFlow numbers are stored in **tensors**, a fancy term for multidimensional arrays. If you pass a Python list to TensorFlow, it does the right thing and converts it into an appropriately dimensioned tensor. You can see this illustrated in the following code:

# TF numbers are stored in "tensors", a fancy term for multidimensional arrays. If you pass TF a Python list, it can convert it V1 = tf.constant([1., 2.]) # Vector, 1-dimensional V2 = tf.constant([3., 4.]) # Vector, 1-dimensional M = tf.constant([[1., 2.]]) # Matrix, 2d N = tf.constant([[1., 2.],[3.,4.]]) # Matrix, 2d K = tf.constant([[[1., 2.],[3.,4.]]]) # Tensor, 3d+

The `V1`

vector, a one-dimensional tensor, is passed as a Python list of `[1. , 2.]`

. The dots here just force Python to store the number as decimal values rather than integers. The `V2`

vector is another Python list of `[3. , 4. ]`

. The `M`

variable is a two-dimensional matrix made from a list of lists in Python, creating a two-dimensional tensor in TensorFlow. The `N`

variable is also a two-dimensional matrix. Note that this one actually has multiple rows in it. Finally, `K`

is a true tensor, containing three dimensions. Note that the final dimension contains just one entry, a single two-by-two box.

Don't worry if this terminology is a bit confusing. Whenever you see a strange new variable, you can jump back to this point to understand what it might be.

### Computations on tensors

You can also do simple things, such as add tensors together:

V3 = V1 + V2

Alternatively, you can multiply them element-wise, so each common position is multiplied together:

# Operations are element-wise by default M2 = M * M

For true matrix multiplication, however, you need to use `tf.matmul`

, passing in your two tensors as arguments:

NN = tf.matmul(N,N)

### Doing computation

Everything so far has just specified the TensorFlow graph; we haven't yet computed anything. To do this, we need to start a session in which the computations will take place. The following code creates a new session:

sess = tf.Session()

Once you have a session open, doing: `sess.run(NN)`

will evaluate the given expression and return an array. We can easily send this to a variable by doing the following:

output = sess.run(NN) print("NN is:") print(output)

If you run this cell now, you should see the correct tensor array for the `NN`

output on the screen:

When you're done using your session, it's good to close it, just like you would close a file handle:

# Remember to close your session when you're done using it sess.close()

For interactive work, we can use `tf.InteractiveSession()`

like so:

sess = tf.InteractiveSession()

You can then easily compute the value of any node. For example, entering the following code and running the cell will output the value of `M2`

:

# Now we can compute any node print("M2 is:") print(M2.eval())

### Variable tensors

Of course, not all our numbers are constant. To update weights in a neural network, for example, we need to use `tf.Variable`

to create the appropriate object:

W = tf.Variable(0, name="weight")

Note that variables in TensorFlow are not initialized automatically. To do so, we need to use a special call, namely `tf.global_variables_initializer()`

, and then run that call with `sess.run()`

:

init_op = tf.global_variables_initializer() sess.run(init_op)

This is to put a value in that variable. In this case, it will stuff a `0`

value into the `W`

variable. Let's just verify that `W`

has that value:

print("W is:") print(W.eval())

You should see an output value for `W`

of `0`

in your cell:

Let's see what happens when you add `a`

to it:

W += a print("W after adding a:") print(W.eval())

Recall that `a`

is `1`

, so you get the expected value of `1`

here:

Let's add `a`

again, just to make sure we can increment and that it's truly a variable:

W += a print("W after adding a:") print(W.eval())

Now you should see that `W`

is holding `2`

, as we have incremented it twice with `a`

:

### Viewing and substituting intermediate values

You can return or supply arbitrary nodes when doing a TensorFlow computation. Let's define a new node but also return another node at the same time in a fetch call. First, let's define our new node `E`

, as shown here:

E = d + b # 1*2 + 2 = 4

Let's take a look at what `E`

starts as:

print("E as defined:") print(E.eval())

You should see that, as expected, `E`

equals `4`

. Now let's see how we can pass in multiple nodes, `E`

and `d`

, to return multiple values from a `sess.run`

call:

# Let's see what d was at the same time print("E and d:") print(sess.run([E,d]))

You should see multiple values, namely `4`

and `2`

, returned in your output:

Now suppose we want to use a different intermediate value, say for debugging purposes. We can use `feed_dict`

to supply a custom value to a node anywhere in our computation when returning a value. Let's do that now with `d`

equals `4`

instead of `2`

:

# Use a custom d by specifying a dictionary print("E with custom d=4:") print(sess.run(E, feed_dict = {d:4.}))

Remember that `E `

equals` d + b`

and the values of `d`

and `b`

are both `2`

. Although we've inserted a new value of `4`

for `d`

, you should see that the value of `E`

will now be output as `6`

:

You have now learned how to do core computations with TensorFlow tensors. It's time to take the next step forward by building a logistic regression model.