Skip to content

TensorFlow - Keras

Keras is a high-level API for building and training deep learning models. It’s user-friendly, modular, and extensible, making it easy to quickly prototype and experiment with deep learning ideas. Originally a standalone library, Keras is now fully integrated into TensorFlow as tf.keras. This makes it TensorFlow’s official high-level API, designed for ease of use and rapid development.

tf.keras supports two main ways to create models:

  • Sequential API: For simple, linear stacks of layers. This is the easiest way to get started.
  • Functional API: For more complex architectures, such as models with multiple inputs/outputs, shared layers, or non-linear topology.

A typical workflow for creating a deep learning model in tf.keras involves these steps:

  • Loading and preprocessing the data.
  • Defining the model architecture (stacking layers).
  • Compiling the model (specifying loss function, optimizer, and metrics).
  • Training the model (fitting it to the training data).
  • Evaluating the model’s performance on test data.
  • Making predictions on new data.
  • (Optional) Saving and loading the trained model.

Let’s illustrate with an example, building a simple CNN for MNIST digit classification (similar to the CNN chapter, but focusing on the Keras workflow). We’ll use a Jupyter Notebook style of presentation for clarity.

Step 1: Load and preprocess data.

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
# For reproducibility
np.random.seed(123)
tf.random.set_seed(123)
# Load pre-shuffled MNIST data
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Preprocess the data: reshape and normalize
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32') / 255
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype('float32') / 255
# Convert class vectors to binary class matrices (one-hot encoding)
num_classes = 10
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

This step imports necessary libraries and modules from TensorFlow and Keras, loads the MNIST dataset, and prepares it for training by reshaping, normalizing, and one-hot encoding the labels.

Step 2: Define the model architecture using the Sequential API.

model = keras.Sequential()
model.add(layers.Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(layers.MaxPooling2D(pool_size=(2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Flatten())
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(num_classes, activation='softmax'))
model.summary() # Display model architecture

Here, we create a Sequential model and add layers one by one. Conv2D for convolution, MaxPooling2D for down-sampling, Dropout for regularization, Flatten to convert 2D features to 1D, and Dense for fully connected layers. The final Dense layer has softmax activation for multi-class classification.

Step 3: Compile the model.

model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])

Compilation configures the training process. We specify the loss function (categorical_crossentropy), optimizer (adam), and metrics to monitor (accuracy).

Step 4: Train (fit) the model using the training data.

batch_size = 128
epochs = 10 # Reduced for brevity in tutorial output
history = model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
verbose=1,
validation_data=(x_test, y_test))

The fit method trains the model. verbose=1 shows a progress bar. validation_data allows monitoring performance on the test set during training.

The output during training will show loss and accuracy for each epoch:

Epoch 1/10
469/469 [==============================] - 4s 6ms/step - loss: 0.2389 - accuracy: 0.9269 - val_loss: 0.0517 - val_accuracy: 0.9827
Epoch 2/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0857 - accuracy: 0.9745 - val_loss: 0.0393 - val_accuracy: 0.9868
Epoch 3/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0644 - accuracy: 0.9804 - val_loss: 0.0344 - val_accuracy: 0.9882
Epoch 4/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0525 - accuracy: 0.9836 - val_loss: 0.0318 - val_accuracy: 0.9893
Epoch 5/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0448 - accuracy: 0.9860 - val_loss: 0.0313 - val_accuracy: 0.9895
Epoch 6/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0380 - accuracy: 0.9881 - val_loss: 0.0275 - val_accuracy: 0.9908
Epoch 7/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0338 - accuracy: 0.9893 - val_loss: 0.0279 - val_accuracy: 0.9912
Epoch 8/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0297 - accuracy: 0.9903 - val_loss: 0.0280 - val_accuracy: 0.9910
Epoch 9/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0264 - accuracy: 0.9915 - val_loss: 0.0291 - val_accuracy: 0.9911
Epoch 10/10
469/469 [==============================] - 3s 6ms/step - loss: 0.0240 - accuracy: 0.9921 - val_loss: 0.0270 - val_accuracy: 0.9918

Step 5: Evaluate the model (already done via validation_data in fit, but can be done explicitly).

score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

This provides a final measure of the model’s performance on unseen data. tf.keras simplifies the deep learning workflow significantly, making it more accessible.