Skip to content

Convolutional Neural Networks

TensorFlow - Convolutional Neural Networks

Section titled “TensorFlow - Convolutional Neural Networks”

After understanding machine learning concepts, we can now shift our focus to deep learning. Deep learning, a subfield of machine learning, represents a significant advancement in AI, powering applications like image and speech recognition.

Two important types of deep neural networks are:

  • Convolutional Neural Networks (CNNs)
  • Recurrent Neural Networks (RNNs)

This chapter focuses on CNNs, which are particularly effective for processing grid-like data, such as images.

Convolutional Neural Networks (CNNs) are specialized neural networks for processing data with a grid-like topology, such as an image (a 2D grid of pixels). They are central to many computer vision applications like image classification, object detection, and facial recognition. Unlike traditional neural networks that might require manual feature extraction from images, CNNs automatically learn hierarchical features directly from the input data, typically 2D or 3D tensors.

Leading tech companies extensively use CNNs for various recognition tasks, leveraging their ability to learn spatial hierarchies of features.

A CNN typically involves three core ideas or types of layers:

  • Convolutional layers (exploiting local receptive fields)
  • Pooling layers
  • Fully Connected layers

Let’s understand these concepts:

CNNs leverage the spatial correlations in input data. Neurons in early layers connect only to a small region of the input layer, known as the local receptive field. This allows the network to learn elementary features (like edges or corners) first. As data passes through deeper layers, these local features are combined to form more complex patterns.

A key operation in CNNs is convolution. Imagine a small filter (or kernel) sliding across the input image. At each position, the filter performs an element-wise multiplication with the part of the image it covers, and the results are summed up to produce a single value in an output feature map. This process is repeated with multiple filters to learn different features. The weights of these filters are learned during training.

The set of weights defining a filter is shared across all positions of the input, significantly reducing the number of parameters and allowing the network to detect features regardless of their position in the image. Each filter also typically has an associated bias term, which is also shared.

Pooling layers are often inserted after convolutional layers. Their purpose is to reduce the spatial dimensions (width and height) of the feature maps, thereby reducing computational complexity and controlling overfitting. Common pooling operations include Max Pooling (taking the maximum value in a local region) and Average Pooling. This also helps make the learned features more robust to small translations in the input.

TensorFlow Implementation of CNN using Keras

Section titled “TensorFlow Implementation of CNN using Keras”

We’ll now implement a CNN for image classification using TensorFlow’s Keras API, which provides a user-friendly way to build neural networks. We’ll use the MNIST dataset of handwritten digits.

Step 1: Import necessary modules and load data. We’ll use tf.keras.datasets.mnist to load the data and tf.keras for building the model.

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
# Load the MNIST dataset
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Preprocess the data
# Normalize pixel values to be between 0 and 1
x_train = x_train.astype("float32") / 255.0
x_test = x_test.astype("float32") / 255.0
# Reshape images to (28, 28, 1) for CNN input (add channel dimension)
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
# Convert labels to one-hot encoded vectors
num_classes = 10
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

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

input_shape = (28, 28, 1) # Height, Width, Channels
model = keras.Sequential(
[
keras.Input(shape=input_shape),
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"), # 32 filters, 3x3 kernel
layers.MaxPooling2D(pool_size=(2, 2)), # 2x2 max pooling
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"), # 64 filters, 3x3 kernel
layers.MaxPooling2D(pool_size=(2, 2)),
layers.Flatten(), # Flatten the 2D feature maps to a 1D vector
layers.Dropout(0.5), # Dropout for regularization
layers.Dense(num_classes, activation="softmax") # Output layer with softmax
]
)
model.summary() # Print model architecture

Explanation of the layers:

  • keras.Input: Defines the expected input shape.
  • layers.Conv2D: 2D convolutional layer. The first argument is the number of filters, kernel_size specifies the dimensions of the convolutional window, and activation is the activation function (ReLU is common).
  • layers.MaxPooling2D: Reduces dimensionality by taking the maximum value over a window defined by pool_size.
  • layers.Flatten: Converts the 2D multi-channel feature maps into a 1D vector to be fed into dense layers.
  • layers.Dropout: A regularization technique where randomly selected neurons are ignored during training to prevent overfitting.
  • layers.Dense: A standard fully connected neural network layer. The final layer uses softmax activation for multi-class classification.

Step 3: Compile the model. This configures the learning process.

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

Here, we use:

  • optimizer="adam": Adam is an efficient and commonly used optimization algorithm.
  • loss="categorical_crossentropy": Suitable for multi-class classification with one-hot encoded labels.
  • metrics=["accuracy"]: We want to monitor classification accuracy during training.

Step 4: Train the model using the fit method.

batch_size = 128
epochs = 15
print("\nTraining the model...")
history = model.fit(x_train, y_train,
batch_size=batch_size,
epochs=epochs,
validation_split=0.1) # Use 10% of training data for validation

batch_size determines the number of samples processed before the model’s internal parameters are updated. epochs is the number of times the entire training dataset is passed through the model. validation_split reserves a portion of training data for validation during training.

Step 5: Evaluate the trained model on the test set.

print("\nEvaluating the model on test data...")
score = model.evaluate(x_test, y_test, verbose=0)
print("Test loss:", score[0])
print("Test accuracy:", score[1])
# Example: Make a prediction on a single test image
print("\nMaking a prediction on the first test image...")
prediction = model.predict(np.expand_dims(x_test[0], axis=0))
predicted_class = np.argmax(prediction[0])
actual_class = np.argmax(y_test[0])
print(f"Predicted class: {predicted_class}, Actual class: {actual_class}")

This example demonstrates a modern approach to building, training, and evaluating a CNN using TensorFlow 2.x and its Keras API. The code is more concise and aligns with current best practices, eliminating the need for manual session management, placeholders, and explicit variable initialization seen in older TensorFlow versions.

Expected output (will vary slightly due to random initializations and training dynamics):

Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 26, 26, 32) 320
max_pooling2d (MaxPooling2D (None, 13, 13, 32) 0
)
conv2d_1 (Conv2D) (None, 11, 11, 64) 18496
max_pooling2d_1 (MaxPoolin (None, 5, 5, 64) 0
g2D)
flatten (Flatten) (None, 1600) 0
dropout (Dropout) (None, 1600) 0
dense (Dense) (None, 10) 16010
=================================================================
Total params: 34,826
Trainable params: 34,826
Non-trainable params: 0
_________________________________________________________________
Training the model...
Epoch 1/15
422/422 [==============================] - 5s 5ms/step - loss: 0.3651 - accuracy: 0.8900 - val_loss: 0.0836 - val_accuracy: 0.9773
Epoch 2/15
422/422 [==============================] - 2s 4ms/step - loss: 0.1109 - accuracy: 0.9663 - val_loss: 0.0578 - val_accuracy: 0.9840
...
Epoch 15/15
422/422 [==============================] - 2s 4ms/step - loss: 0.0265 - accuracy: 0.9913 - val_loss: 0.0337 - val_accuracy: 0.9903
Evaluating the model on test data...
Test loss: 0.0279...
Test accuracy: 0.9901...
Making a prediction on the first test image...
1/1 [==============================] - 0s 18ms/step
Predicted class: 7, Actual class: 7