Swiftorial Logo
Home
Swift Lessons
AI Tools
Learn More
Career
Resources

Building Your First AI Model with Python

A practical, beginner-friendly tutorial on building and training a simple image classification model using TensorFlow and Keras. Includes detailed steps, code examples, and explanations to help you create your first AI model.

1. Introduction to Image Classification

Image classification is a fundamental machine learning task where an AI model identifies objects or categories in images (e.g., distinguishing cats from dogs). This tutorial guides you through building a convolutional neural network (CNN) to classify handwritten digits from the MNIST dataset, a classic dataset containing 70,000 grayscale images of digits (0–9).

Using Python, TensorFlow, and Keras, you’ll learn to preprocess data, build a model, train it, and evaluate its performance. No prior AI experience is required, but basic Python knowledge is helpful.

2. Setting Up Your Environment

Before building the model, set up your development environment with the necessary tools and libraries.

Step 1: Install Python

Ensure Python 3.7 or later is installed. Download it from python.org or use a package manager like Anaconda.

Step 2: Install Required Libraries

Install TensorFlow, NumPy, and Matplotlib using pip. Open a terminal and run:

pip install tensorflow numpy matplotlib

Step 3: Use a Development Environment

Use an IDE like VS Code or Jupyter Notebook. For beginners, Google Colab is a free, cloud-based option with TensorFlow pre-installed.

  • VS Code: Install the Python extension and create a .py file.
  • Jupyter Notebook: Run pip install jupyter and launch with jupyter notebook.
  • Google Colab: Access at colab.research.google.com.

Step 4: Verify Installation

Check TensorFlow installation by running this code:

import tensorflow as tf
print(tf.__version__)

This should display the TensorFlow version (e.g., 2.17.0). If it fails, reinstall TensorFlow or check your Python environment.

3. Loading and Preprocessing the MNIST Dataset

The MNIST dataset is included in TensorFlow’s Keras library. It contains 60,000 training images and 10,000 test images, each 28x28 pixels, labeled with digits 0–9.

Step 1: Load the Dataset

Load MNIST using Keras:

import tensorflow as tf

# Load MNIST dataset
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

# Check dataset shape
print("Training data shape:", x_train.shape)  # (60000, 28, 28)
print("Test data shape:", x_test.shape)      # (10000, 28, 28)

Explanation: x_train and x_test are image arrays (28x28 pixels). y_train and y_test are labels (0–9).

Step 2: Preprocess the Data

Prepare the data for training by normalizing pixel values and reshaping for the CNN.

# Normalize pixel values to [0, 1]
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0

# Reshape images for CNN (add channel dimension)
x_train = x_train.reshape((x_train.shape[0], 28, 28, 1))
x_test = x_test.reshape((x_test.shape[0], 28, 28, 1))

# Convert labels to one-hot encoding
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)

# Verify shapes
print("Reshaped training data:", x_train.shape)  # (60000, 28, 28, 1)
print("One-hot labels:", y_train.shape)          # (60000, 10)

Explanation:

  • Normalization: Pixel values (0–255) are scaled to [0,1] to improve training stability.
  • Reshaping: Add a channel dimension (1 for grayscale) to match CNN input requirements.
  • One-Hot Encoding: Convert labels to a binary matrix (e.g., 3 becomes [0,0,0,1,0,0,0,0,0,0]).

Step 3: Visualize the Data

Display sample images to understand the dataset:

import matplotlib.pyplot as plt

# Plot first 9 images
plt.figure(figsize=(10, 10))
for i in range(9):
    plt.subplot(3, 3, i+1)
    plt.imshow(x_train[i].reshape(28, 28), cmap='gray')
    plt.title(f"Label: {y_train[i].argmax()}")
    plt.axis('off')
plt.show()

Explanation: This code displays a 3x3 grid of MNIST images with their corresponding labels.

4. Building the CNN Model

A convolutional neural network (CNN) is ideal for image classification, as it detects spatial patterns like edges and shapes. We’ll build a simple CNN using Keras.

Model Architecture

Create a sequential model with convolutional, pooling, and dense layers:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout

# Build the CNN model
model = Sequential([
    # Convolutional layer: 32 filters, 3x3 kernel, ReLU activation
    Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    # Pooling layer: 2x2 pool size
    MaxPooling2D((2, 2)),
    # Second convolutional layer: 64 filters
    Conv2D(64, (3, 3), activation='relu'),
    MaxPooling2D((2, 2)),
    # Flatten layer to transition to dense layers
    Flatten(),
    # Dense layer with 128 neurons
    Dense(128, activation='relu'),
    # Dropout to prevent overfitting
    Dropout(0.5),
    # Output layer: 10 neurons for 10 classes, softmax activation
    Dense(10, activation='softmax')
])

# Print model summary
model.summary()

Explanation:

  • Conv2D: Applies convolution to detect features (e.g., edges). 32 and 64 filters increase feature complexity.
  • MaxPooling2D: Reduces spatial dimensions (e.g., 28x28 to 14x14), improving efficiency.
  • Flatten: Converts 2D feature maps to a 1D vector for dense layers.
  • Dense: Fully connected layers for classification.
  • Dropout: Randomly disables 50% of neurons during training to prevent overfitting.
  • Softmax: Outputs probabilities for each class (0–9).

5. Compiling the Model

Configure the model for training by specifying the optimizer, loss function, and metrics.

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

Explanation:

  • Optimizer: Adam, an adaptive learning rate optimizer, balances speed and stability.
  • Loss: Categorical crossentropy, suitable for multi-class classification with one-hot labels.
  • Metrics: Accuracy tracks the percentage of correct predictions.

6. Training the Model

Train the model on the MNIST dataset using the training data and validate on a subset.

# Train the model
history = model.fit(
    x_train, y_train,
    epochs=10,
    batch_size=32,
    validation_split=0.2
)

Explanation:

  • Epochs: The model processes the entire dataset 10 times.
  • Batch Size: 32 images are processed before updating weights, balancing speed and stability.
  • Validation Split: 20% of training data is reserved for validation to monitor performance.

Training may take a few minutes, depending on your hardware. On Google Colab with a GPU, it’s faster.

7. Evaluating the Model

Assess the model’s performance on the test dataset.

# Evaluate the model
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f"Test accuracy: {test_accuracy:.4f}")

Explanation: This code returns the loss and accuracy on the test set. A well-trained model typically achieves ~98% accuracy on MNIST.

Visualize Training Progress

Plot accuracy and loss over epochs to understand training dynamics:

plt.figure(figsize=(12, 4))

# Plot accuracy
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()

# Plot loss
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

Explanation: These plots show how accuracy improves and loss decreases. If validation loss increases while training loss decreases, the model may be overfitting.

8. Making Predictions

Use the trained model to predict digits in the test set.

import numpy as np

# Predict on a single image
sample_image = x_test[0:1]  # First test image
prediction = model.predict(sample_image)
predicted_label = np.argmax(prediction, axis=1)

# Display the image and prediction
plt.imshow(sample_image.reshape(28, 28), cmap='gray')
plt.title(f"Predicted: {predicted_label[0]}, True: {y_test[0].argmax()}")
plt.axis('off')
plt.show()

Explanation: This code predicts the digit for a test image and displays it with the predicted and true labels. argmax extracts the class with the highest probability.

9. Improving the Model

Enhance model performance with these techniques:

Add Data Augmentation

Augment the dataset to improve generalization:

from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Define data augmentation
datagen = ImageDataGenerator(
    rotation_range=10,
    zoom_range=0.1,
    width_shift_range=0.1,
    height_shift_range=0.1
)

# Train with augmented data
model.fit(datagen.flow(x_train, y_train, batch_size=32),
          epochs=10,
          validation_data=(x_test, y_test))

Explanation: Augmentation applies random rotations, zooms, and shifts to images, making the model robust to variations.

Tune Hyperparameters

  • Layers: Add more Conv2D or Dense layers for complex patterns.
  • Learning Rate: Adjust Adam’s learning rate (e.g., optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001)).
  • Epochs/Batch Size: Experiment with more epochs or different batch sizes.

Prevent Overfitting

Add regularization (e.g., L2 regularization) or increase dropout rate:

from tensorflow.keras.regularizers import l2

# Add L2 regularization
model = Sequential([
    Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1), kernel_regularizer=l2(0.01)),
    MaxPooling2D((2, 2)),
    Conv2D(64, (3, 3), activation='relu', kernel_regularizer=l2(0.01)),
    MaxPooling2D((2, 2)),
    Flatten(),
    Dense(128, activation='relu', kernel_regularizer=l2(0.01)),
    Dropout(0.5),
    Dense(10, activation='softmax')
])

Explanation: The `kernel_regularizer` parameter penalizes large weights, preventing the model from becoming too complex and overfitting the training data.

10. Saving and Loading the Model

Save the trained model for future use and load it for predictions.

# Save the model
model.save('mnist_cnn_model.h5')

# Load the model
from tensorflow.keras.models import load_model
loaded_model = load_model('mnist_cnn_model.h5')

# Make predictions with loaded model
prediction = loaded_model.predict(x_test[0:1])
print(f"Predicted label: {np.argmax(prediction, axis=1)[0]}")

Explanation: The model is saved in HDF5 format and can be loaded later, preserving weights and architecture.

11. Challenges and Next Steps

Common challenges and how to address them:

  • Overfitting: Use dropout, regularization, or augmentation to improve generalization.
  • Low Accuracy: Increase model complexity, train for more epochs, or tune hyperparameters.
  • Resource Constraints: Use Google Colab’s free GPU/TPU for faster training.

Next Steps

  • Explore Other Datasets: Try CIFAR-10 (color images) or Fashion MNIST.
  • Learn Advanced Architectures: Study ResNet, VGG, or transfer learning with pre-trained models.
  • Build Projects: Create a web app to classify uploaded images using Flask or Streamlit.
  • Join Communities: Share your work on Kaggle, GitHub, or X to get feedback.

12. Full Code Example

Here’s the complete code to build, train, and evaluate the MNIST classifier:

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# Load and preprocess data
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
x_train = x_train.reshape((x_train.shape[0], 28, 28, 1))
x_test = x_test.reshape((x_test.shape[0], 28, 28, 1))
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)

# Build the model
model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D((2, 2)),
    tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
    tf.keras.layers.MaxPooling2D((2, 2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(10, activation='softmax')
])

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

# Train the model
history = model.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.2)

# Evaluate the model
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f"Test accuracy: {test_accuracy:.4f}")

# Plot training history
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

# Make a prediction
sample_image = x_test[0:1]
prediction = model.predict(sample_image)
predicted_label = np.argmax(prediction, axis=1)
plt.imshow(sample_image.reshape(28, 28), cmap='gray')
plt.title(f"Predicted: {predicted_label[0]}, True: {y_test[0].argmax()}")
plt.axis('off')
plt.show()

Explanation: This code combines all steps into a single script. Run it in a Jupyter Notebook or Python file to train and test the model.

← Back to Articles