TL;DR Learn how to use Tensors, build a Linear Regression model and a simple Neural Network
TensorFlow 2.0 (final) was released at the end of September. Oh boy, it looks much cooler than the 1.x series. Why is it so much better for you, the developer?

One highlevel API for building models (that you know and love)  Keras. The good news is that most of your old Keras code should work automagically after changing a couple of imports.

Eager execution  all your code looks much more like normal Python programs. Oldtimers might remember the horrible
Session
experiences. You shouldn’t need any of that, in daytoday use.
There are tons of other improvements, but the new developer experience is something that will make using TensorFlow 2 sweeter. What about PyTorch? PyTorch is still great and easy to use. But it seems like TensorFlow is catching up, or is it?
You’ll learn:
 How to install TensorFlow 2
 What is a Tensor
 Doing Tensor math
 Using probability distributions and sampling
 Build a Simple Linear Regression model
 Build a Simple Neural Network model
 Save/restore a model
Run the complete code in your browser
Setup
Let’s install the GPUsupported version and set up the environment:
!pip install tensorflowgpu
Check the installed version:
import tensorflow as tf
tf.__version__
2.0.0
And specify a random seed, so our results are reproducible:
RANDOM_SEED = 42
tf.random.set_seed(RANDOM_SEED)
Tensors
TensorFlow allows you to define and run operations on Tensors. Tensors are datacontainers that can be of arbitrary dimension  scalars, vectors, matrices, etc. You can put numbers (floats and ints) and strings into Tensors.
Let’s create a simple Tensor:
x = tf.constant(1)
print(x)
tf.Tensor(1, shape=(), dtype=int32)
It seems like our first Tensor contains the number 1, it is of type int32 and is shapeless. To obtain the value we can do:
x.numpy()
1
Let’s create a simple matrix:
m = tf.constant([[1, 2, 1], [3, 4, 2]])
print(m)
tf.Tensor(
[[1 2 1]
[3 4 2]], shape=(2, 3), dtype=int32)
This shape thingy seems to specify rows x columns. In general, the shape array shows how many elements are in every dimension of the Tensor.
Helpers
TensorFlow offers a variety of helper functions for creating Tensors. Let’s create a matrix full of ones:
ones = tf.ones([3, 3])
print(ones)
tf.Tensor(
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]], shape=(3, 3), dtype=float32)
and zeros:
zeros = tf.zeros([2, 3])
print(zeros)
tf.Tensor(
[[0. 0. 0.]
[0. 0. 0.]], shape=(2, 3), dtype=float32)
We have two rows and three columns. What if we want to turn it into three rows and two columns:
tf.reshape(zeros, [3, 2])
tf.Tensor(
[[0. 0.]
[0. 0.]
[0. 0.]], shape=(3, 2), dtype=float32)
You can use another helper function to replace rows and columns (transpose):
tf.transpose(zeros)
tf.Tensor(
[[0. 0.]
[0. 0.]
[0. 0.]], shape=(3, 2), dtype=float32)
Tensor Math
Naturally, you would want to do something with your data. Let’s start with adding numbers:
a = tf.constant(1)
b = tf.constant(1)
tf.add(a, b).numpy()
42
That seems reasonable :) You can do the same thing using something more human friendly:
(a + b).numpy()
You can multiply Tensors like so:
c = a + b
c * c
And compute dot product of matrices:
d1 = tf.constant([[1, 2], [1, 2]]);
d2 = tf.constant([[3, 4], [3, 4]]);
tf.tensordot(d1, d2, axes=1).numpy()
array([[ 9, 12],
[ 9, 12]], dtype=int32)
Sampling
You can also generate random numbers according to some famous probability distributions. Let’s start with Normal:
norm = tf.random.normal(shape=(1000, 1), mean=0., stddev=1.)
We can do the same thing from the Uniform:
unif = tf.random.uniform(shape=(1000, 1), minval=0, maxval=100)
Let’s have a look at something a tad more exotic  the Poisson distribution. It is popular for modeling the number of times an event occurs in some time. It is the first one (in our exploration) that contains a hyperparameter  $\lambda$. It controls the number of expected occurrences.
pois = tf.random.poisson(shape=(1000, 1), lam=0.8)
The Gamma distribution is continuous. It has 2 hyperparameters that control the shape and scale. It is used to model always positive continuous variables with skewed distributions.
gam = tf.random.gamma(shape=(1000, 1), alpha=0.8)
Simple Linear Regression Model
Let’s build a Simple Linear Regression model to predict the stopping distance of cars based on their speed. The data comes from here: https://vincentarelbundock.github.io/Rdatasets/datasets.html. It is given by this Tensor:
data = tf.constant([
[4,2],
[4,10],
[7,4],
[7,22],
[8,16],
[9,10],
[10,18],
[10,26],
[10,34],
[11,17],
[11,28],
[12,14],
[12,20],
[12,24],
[12,28],
[13,26],
[13,34],
[13,34],
[13,46],
[14,26],
[14,36],
[14,60],
[14,80],
[15,20],
[15,26],
[15,54],
[16,32],
[16,40],
[17,32],
[17,40],
[17,50],
[18,42],
[18,56],
[18,76],
[18,84],
[19,36],
[19,46],
[19,68],
[20,32],
[20,48],
[20,52],
[20,56],
[20,64],
[22,66],
[23,54],
[24,70],
[24,92],
[24,93],
[24,120],
[25,85]
])
We can extract the two columns using slicing:
speed = data[:, 0]
stopping_distance = data[:, 1]
Let’s have a look at the data:
It seems like a linear model can do a decent job of predicting the stopping distance. Simple Linear Regression finds a straight line that predicts the variable of interest based on a single predictor/feature.
Time to build the model using the Keras API:
lin_reg = keras.Sequential([
layers.Dense(1, activation='linear', input_shape=[1]),
])
optimizer = tf.keras.optimizers.RMSprop(0.001)
lin_reg.compile(
loss='mse',
optimizer=optimizer,
metrics=['mse']
)
We’re using the Sequential API with a single layer  1 parameter with linear activation. We’ll try to minimize the Mean squared error during training.
And for the training itself:
history = lin_reg.fit(
x=speed,
y=stopping_distance,
shuffle=True,
epochs=1000,
validation_split=0.2,
verbose=0
)
We’re breaking any ordering issues by shuffling the data and reserving 20% for validation. Let’s have a look at the training process:
The model is steadily improving during training. That’s a good sign. What can we do with a more complex model?
Simple Neural Network Model
Keras (and TensorFlow) was designed as a tool to build Neural Networks. Turns out, Neural Networks are good when a linear model isn’t enough. Let’s create one:
def build_neural_net():
net = keras.Sequential([
layers.Dense(32, activation='relu', input_shape=[1]),
layers.Dense(16, activation='relu'),
layers.Dense(1),
])
optimizer = tf.keras.optimizers.RMSprop(0.001)
net.compile(loss='mse',
optimizer=optimizer,
metrics=['mse', 'accuracy'])
return net
Things look similar, except for the fact that we stack multiple layers on top of each other. We’re also using a different activation function  ReLU.
Training this model looks exactly the same:
net = build_neural_net()
history = net.fit(
x=speed,
y=stopping_distance,
shuffle=True,
epochs=1000,
validation_split=0.2,
verbose=0
)
Seems like we ain’t making much progress after epoch 200 or so. Can we not waste our time waiting for the whole training to complete?
Early Stopping
Sure, you can stop the training process manually at say epoch 200. But what if you train another model? What if you obtain more data?
You can use the builtin callback EarlyStopping to halt the training when some metric (e.g. the validation loss) stops improving. Let’s see how we can use it:
early_stop = keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=10
)
We want to monitor the validation loss. We’ll observe for improvement for 10 epochs before stopping. Let’s see how we can use it:
net = build_neural_net()
history = net.fit(
x=speed,
y=stopping_distance,
shuffle=True,
epochs=1000,
validation_split=0.2,
verbose=0,
callbacks=[early_stop]
)
Effectively, we’ve cut down the number of training epochs to ~120. Is this going to work every time that well? Not really. Using early stopping introduces yet another hyperparameter that you need to consider when training your model. Use it cautiously.
Now your model is ready for the real world. How can you store it for later use?
Save/Restore Model
You can save the complete model (including weights) like this:
net.save('simple_net.h5')
And load it like that:
simple_net = keras.models.load_model('simple_net.h5')
You can use this mechanism to deploy your model and use it in production (for example).
Conclusion
You did it! You now know (a tiny bit) TensorFlow 2! Let’s recap what you’ve learned:
 How to install TensorFlow 2
 What is a Tensor
 Doing Tensor math
 Using probability distributions and sampling
 Build a Simple Linear Regression model
 Build a Simple Neural Network model
 Save/restore a model
Run the complete code in your browser
Stay tuned for more :)