AI & Machine Learning

Deep Learning with CNN: Convolutional Neural Network Guide

14 min readMarch 19, 2026
CNNConvolutional Neural NetworkDerin öğrenmeDeep learningCNN rehberiGörüntü sınıflandırmaImage classificationNeural networkCNN PythonCNN TensorFlowDerin öğrenme TürkçeYapay sinir ağları

Convolutional Neural Networks (CNNs) are among the most powerful architectures in deep learning. They have produced groundbreaking results in image classification, object detection, face recognition, and medical image analysis. In this article, we will explore the core components of CNNs, their layer structure, and how to build a practical model using TensorFlow/Keras.

What Is Deep Learning?

Deep learning is a subset of machine learning where artificial neural networks are built with multiple layers (deep layers). While traditional machine learning requires manual feature extraction, deep learning models automatically learn hierarchical features from raw data.

Why CNN?

Fully connected networks are inefficient for image data. A 224x224x3 RGB image has 150,528 input neurons. CNNs solve this problem through:

  • Parameter sharing: The same filter is slid across the entire image
  • Local connectivity: Each neuron looks at only a small region
  • Spatial hierarchy: Lower layers learn edges, higher layers learn complex structures

CNN Architecture

Convolution Layer

The heart of a CNN. Small filters (kernels) are slid across the image to produce feature maps.

  • Filter size: Typically 3x3 or 5x5
  • Stride: The step size of the filter movement
  • Padding: Zeros added to borders to control output dimensions
  • Activation: ReLU (Rectified Linear Unit) is the most common activation function

Pooling Layer

Reduces the dimensions of feature maps, lowering computational cost and preventing overfitting.

  • Max Pooling: Takes the maximum value within the window (most common)
  • Average Pooling: Computes the average within the window
  • Global Average Pooling: Reduces the entire map to a single value

Fully Connected Layer

Found in the final layers of the CNN. Converts the learned features into class predictions.

Building a CNN with TensorFlow/Keras

Basic CNN Architecture

Below is a CNN model example for the CIFAR-10 dataset:

python
import tensorflow as tf
from tensorflow.keras import layers, models

# Build the CNN model
model = models.Sequential([
    # First convolution block
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
    layers.BatchNormalization(),
    layers.MaxPooling2D((2, 2)),

    # Second convolution block
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.BatchNormalization(),
    layers.MaxPooling2D((2, 2)),

    # Third convolution block
    layers.Conv2D(128, (3, 3), activation='relu'),
    layers.BatchNormalization(),

    # Classification layers
    layers.GlobalAveragePooling2D(),
    layers.Dense(128, activation='relu'),
    layers.Dropout(0.5),
    layers.Dense(10, activation='softmax')
])

model.summary()

Data Loading and Preprocessing

python
# Load CIFAR-10 dataset
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()

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

# Data Augmentation
data_augmentation = tf.keras.Sequential([
    layers.RandomFlip("horizontal"),
    layers.RandomRotation(0.1),
    layers.RandomZoom(0.1),
    layers.RandomContrast(0.1),
])

# Create augmented training dataset
train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train))
train_ds = train_ds.shuffle(10000).batch(64).prefetch(tf.data.AUTOTUNE)

print(f"Training set: {X_train.shape}")
print(f"Test set: {X_test.shape}")

Model Compilation and Training

python
# Compile the model
model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

# Callbacks
callbacks = [
    tf.keras.callbacks.EarlyStopping(
        monitor='val_loss', patience=5, restore_best_weights=True
    ),
    tf.keras.callbacks.ReduceLROnPlateau(
        monitor='val_loss', factor=0.5, patience=3
    )
]

# Training
history = model.fit(
    X_train, y_train,
    epochs=50,
    batch_size=64,
    validation_split=0.2,
    callbacks=callbacks
)

# Evaluation
test_loss, test_accuracy = model.evaluate(X_test, y_test)
print(f"Test Accuracy: {test_accuracy:.2%}")

Dropout and Regularization

Overfitting is one of the most common issues in deep neural networks. The model memorizes training data and fails to generalize to new examples. Several regularization techniques help address this problem.

Dropout randomly disables neurons during training, preventing the model from becoming overly dependent on specific neurons. Each training step effectively trains a different sub-network, creating an ensemble-like effect. Dropout rates of 30-50% are typical for fully connected layers, while 10-25% is common after convolutional layers.

L2 Regularization (Weight Decay) penalizes large weight values, encouraging the model to stay simpler. It can be added to any layer via the kernel regularizer parameter:

python
from tensorflow.keras import regularizers

# Enhanced CNN model with regularization
model_reg = models.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3),
                  kernel_regularizer=regularizers.l2(1e-4)),
    layers.BatchNormalization(),
    layers.MaxPooling2D((2, 2)),
    layers.Dropout(0.15),

    layers.Conv2D(64, (3, 3), activation='relu',
                  kernel_regularizer=regularizers.l2(1e-4)),
    layers.BatchNormalization(),
    layers.MaxPooling2D((2, 2)),
    layers.Dropout(0.2),

    layers.Conv2D(128, (3, 3), activation='relu',
                  kernel_regularizer=regularizers.l2(1e-4)),
    layers.BatchNormalization(),

    layers.GlobalAveragePooling2D(),
    layers.Dense(256, activation='relu',
                 kernel_regularizer=regularizers.l2(1e-4)),
    layers.Dropout(0.5),
    layers.Dense(10, activation='softmax')
])

Using regularization techniques together typically yields the best results. Batch normalization also provides an implicit regularization effect, as mini-batch statistics introduce noise during training.

Learning Rate Scheduling

Using a fixed learning rate is often suboptimal. At the beginning of training, a higher learning rate explores the broad parameter space, then the rate is gradually decreased for finer adjustments. This strategy helps the model both converge quickly and reach a better optimum.

python
# Cosine decay learning rate schedule
initial_learning_rate = 0.001
decay_steps = 1000

lr_schedule = tf.keras.optimizers.schedules.CosineDecay(
    initial_learning_rate=initial_learning_rate,
    decay_steps=decay_steps,
    alpha=1e-6  # Minimum learning rate
)

# Warm-up with cosine decay (recommended approach)
class WarmupCosineDecay(tf.keras.optimizers.schedules.LearningRateSchedule):
    def __init__(self, warmup_steps, total_steps, peak_lr):
        super().__init__()
        self.warmup_steps = warmup_steps
        self.total_steps = total_steps
        self.peak_lr = peak_lr

    def __call__(self, step):
        warmup = self.peak_lr * (step / self.warmup_steps)
        cosine = 0.5 * self.peak_lr * (1 + tf.cos(
            np.pi * (step - self.warmup_steps) / (self.total_steps - self.warmup_steps)
        ))
        return tf.where(step < self.warmup_steps, warmup, cosine)

optimizer = tf.keras.optimizers.Adam(learning_rate=lr_schedule)

Model Evaluation with Confusion Matrix

To deeply understand a model's performance, confusion matrices and per-class metrics are essential. A confusion matrix shows the distribution of correct and incorrect predictions for each class, revealing which classes the model struggles with.

python
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# Predict on test set
y_pred = model.predict(X_test)
y_pred_classes = np.argmax(y_pred, axis=1)
y_true = y_test.flatten()

# CIFAR-10 class names
class_names = ['Airplane', 'Automobile', 'Bird', 'Cat', 'Deer',
               'Dog', 'Frog', 'Horse', 'Ship', 'Truck']

# Confusion Matrix
cm = confusion_matrix(y_true, y_pred_classes)

plt.figure(figsize=(10, 8))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
            xticklabels=class_names, yticklabels=class_names)
plt.title('Confusion Matrix')
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.tight_layout()
plt.savefig('confusion_matrix.png', dpi=150)
plt.show()

# Detailed classification report
print(classification_report(y_true, y_pred_classes, target_names=class_names))

This analysis reveals which classes the model confuses. For instance, confusion between cat and dog classes is expected since these classes are visually similar.

Transfer Learning

Instead of training from scratch, leverage pre-trained models to achieve high performance with less data. Transfer learning allows you to take the general visual features learned by a model trained on large datasets (like ImageNet) and apply them to your own problem.

This approach is particularly effective when working with limited data. The lower layers of an ImageNet-trained model have already learned universal features like edges, textures, and simple shapes. You can freeze these layers and train only the top classification layers on your own dataset.

python
# Build model with transfer learning
base_model = tf.keras.applications.ResNet50V2(
    include_top=False,
    weights='imagenet',
    input_shape=(224, 224, 3)
)
base_model.trainable = False  # Freeze all layers

# Add your own classification layers
model_tl = models.Sequential([
    base_model,
    layers.GlobalAveragePooling2D(),
    layers.BatchNormalization(),
    layers.Dense(256, activation='relu'),
    layers.Dropout(0.4),
    layers.Dense(10, activation='softmax')
])

model_tl.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

# Fine-tuning: Unfreeze top layers for fine adjustment
base_model.trainable = True
for layer in base_model.layers[:-20]:
    layer.trainable = False

model_tl.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5),
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

Visualizing Feature Maps

To understand what a CNN has learned, you can visualize the outputs of intermediate layers. This technique is valuable for both debugging and explaining the model's decision process. Lower layers learn low-level features like edges and colors, while upper layers learn high-level features like object parts and complex structures.

python
# Visualize intermediate layer outputs
from tensorflow.keras.models import Model

# Get the output of the first convolution layer
intermediate_model = Model(
    inputs=model.input,
    outputs=model.layers[0].output  # First Conv2D layer
)

# Predict with a single image
sample_image = X_test[0:1]
feature_maps = intermediate_model.predict(sample_image)

# Visualize feature maps
fig, axes = plt.subplots(4, 8, figsize=(16, 8))
for i, ax in enumerate(axes.flat):
    if i < feature_maps.shape[-1]:
        ax.imshow(feature_maps[0, :, :, i], cmap='viridis')
    ax.axis('off')
plt.suptitle('First Convolution Layer Feature Maps')
plt.tight_layout()
plt.savefig('feature_maps.png', dpi=150)
plt.show()

Popular CNN Architectures

Notable CNN architectures developed over the years:

  • LeNet-5 (1998): Designed for handwritten digit recognition
  • AlexNet (2012): Won ImageNet and kickstarted the deep learning revolution
  • VGGNet (2014): Demonstrated the power of deep networks with 3x3 filters
  • ResNet (2015): Enabled training up to 152 layers with skip connections
  • EfficientNet (2019): Efficient architecture through compound model scaling

Optimization Tips

  1. Batch Normalization: Use after each layer to stabilize training
  2. Dropout: Apply 30-50% in fully connected layers
  3. Data Augmentation: Artificially expand your dataset
  4. Learning Rate Scheduling: Decrease the learning rate as training progresses
  5. Mixed Precision Training: Speed up training with FP16

Summary

CNNs are the foundational building blocks of image classification and computer vision. Through the combination of convolution, pooling, and fully connected layers, they extract meaningful features from raw pixel data. Dropout and L2 regularization keep overfitting in check, while learning rate scheduling strategies like cosine decay optimize the training process. Confusion matrix analysis reveals which classes the model struggles with, and transfer learning enables high accuracy even with limited data. Visualizing feature maps provides a powerful tool for understanding the model's decision-making process. With TensorFlow/Keras, you can build these architectures in just a few lines of code and apply them successfully in modern deep learning projects.

Related Articles

Have a Flutter Project?

I build high-performance Flutter applications for iOS, Android, and web.

Get in Touch