Machine Learning
Overfitting
Model Optimization
Data Science Strategies
Algorithm Improvement

How to select strategy to reduce overfitting?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Overfitting is one of the most common problems in machine learning. It occurs when a model learns the training data too well, capturing noise and irrelevant patterns that do not generalize to unseen data. The result is a model that performs excellently on training data but poorly on validation or test sets. Selecting the right strategy to reduce overfitting depends on the type of model, the amount of available data, and the specific symptoms you observe.

This article covers the most effective techniques for reducing overfitting, with practical code examples and guidance on when to apply each one.

Recognizing Overfitting

Before applying a fix, confirm that overfitting is actually the problem. The key indicators are:

  • Training loss decreases steadily while validation loss starts increasing after some point.
  • Training accuracy is significantly higher than validation accuracy (for example, 98% train vs. 72% validation).
  • The model performs poorly on new data despite strong training metrics.

A simple diagnostic is to plot training and validation loss curves over epochs.

python
1import matplotlib.pyplot as plt
2
3# Assume history is returned from model.fit()
4plt.plot(history.history['loss'], label='Training Loss')
5plt.plot(history.history['val_loss'], label='Validation Loss')
6plt.xlabel('Epoch')
7plt.ylabel('Loss')
8plt.legend()
9plt.title('Overfitting Diagnostic')
10plt.show()

If the training loss keeps dropping but validation loss diverges upward, the model is overfitting.

Strategy 1: Get More Training Data

The most reliable way to reduce overfitting is to increase the size and diversity of the training data. A model with many parameters and too few samples will memorize instead of generalize.

When collecting more real data is not possible, data augmentation can synthetically expand the dataset. For images, this includes random rotations, flips, crops, and color adjustments.

python
1from tensorflow.keras.preprocessing.image import ImageDataGenerator
2
3augmentor = ImageDataGenerator(
4    rotation_range=20,
5    width_shift_range=0.2,
6    height_shift_range=0.2,
7    horizontal_flip=True,
8    zoom_range=0.15
9)
10
11# Use augmentor.flow() with your training data

For text, augmentation techniques include synonym replacement, back-translation, and random insertion.

Strategy 2: Simplify the Model

A model that is too complex for the amount of data will overfit. Reducing complexity means fewer parameters to fit, which forces the model to learn only the most important patterns.

For neural networks, reduce the number of layers or units per layer.

python
1from tensorflow import keras
2
3# Overly complex model
4complex_model = keras.Sequential([
5    keras.layers.Dense(512, activation='relu', input_shape=(100,)),
6    keras.layers.Dense(512, activation='relu'),
7    keras.layers.Dense(256, activation='relu'),
8    keras.layers.Dense(10, activation='softmax')
9])
10
11# Simplified model
12simple_model = keras.Sequential([
13    keras.layers.Dense(64, activation='relu', input_shape=(100,)),
14    keras.layers.Dense(32, activation='relu'),
15    keras.layers.Dense(10, activation='softmax')
16])

For tree-based models, reduce max_depth, max_features, or min_samples_leaf.

python
1from sklearn.ensemble import RandomForestClassifier
2
3# Constrained to prevent overfitting
4model = RandomForestClassifier(
5    n_estimators=100,
6    max_depth=8,
7    min_samples_leaf=10,
8    max_features='sqrt'
9)

Strategy 3: Regularization

Regularization adds a penalty to the loss function that discourages large weight values. This constrains the model's capacity and reduces overfitting.

L2 Regularization (Ridge) adds the squared magnitude of weights to the loss. It keeps weights small but rarely drives them to exactly zero.

L1 Regularization (Lasso) adds the absolute magnitude of weights. It can drive some weights to zero, effectively performing feature selection.

python
1from tensorflow import keras
2from tensorflow.keras import regularizers
3
4model = keras.Sequential([
5    keras.layers.Dense(128, activation='relu', input_shape=(100,),
6                       kernel_regularizer=regularizers.l2(0.01)),
7    keras.layers.Dense(64, activation='relu',
8                       kernel_regularizer=regularizers.l2(0.01)),
9    keras.layers.Dense(10, activation='softmax')
10])

For scikit-learn models, regularization is often a constructor parameter.

python
1from sklearn.linear_model import LogisticRegression
2
3# C is the inverse of regularization strength (smaller C = stronger regularization)
4model = LogisticRegression(C=0.1, penalty='l2')

Strategy 4: Dropout

Dropout randomly deactivates a fraction of neurons during each training step, which forces the network to learn redundant representations and prevents co-adaptation of neurons.

python
1from tensorflow import keras
2
3model = keras.Sequential([
4    keras.layers.Dense(256, activation='relu', input_shape=(100,)),
5    keras.layers.Dropout(0.5),
6    keras.layers.Dense(128, activation='relu'),
7    keras.layers.Dropout(0.3),
8    keras.layers.Dense(10, activation='softmax')
9])

Typical dropout rates range from 0.2 to 0.5. Higher rates provide stronger regularization but can slow convergence or underfit if set too aggressively.

Strategy 5: Early Stopping

Early stopping monitors validation loss during training and halts training when the loss stops improving. This prevents the model from continuing to learn noise in the training data.

python
1from tensorflow.keras.callbacks import EarlyStopping
2
3early_stop = EarlyStopping(
4    monitor='val_loss',
5    patience=10,        # Wait 10 epochs for improvement
6    restore_best_weights=True  # Revert to the best model
7)
8
9model.fit(x_train, y_train,
10          validation_data=(x_val, y_val),
11          epochs=200,
12          callbacks=[early_stop])

Early stopping is simple, effective, and works with any model that trains iteratively. The patience parameter controls how many epochs of no improvement to tolerate before stopping.

Strategy 6: Cross-Validation

Cross-validation gives you a more robust estimate of model performance and helps you detect overfitting that might be hidden by a single train/validation split.

python
1from sklearn.model_selection import cross_val_score
2from sklearn.ensemble import GradientBoostingClassifier
3
4model = GradientBoostingClassifier(n_estimators=100, max_depth=5)
5scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
6
7print(f"Mean accuracy: {scores.mean():.3f} +/- {scores.std():.3f}")

A large gap between train scores and cross-validation scores signals overfitting. Adjust model complexity or regularization until the gap narrows.

Strategy 7: Batch Normalization

Batch normalization normalizes activations within each mini-batch, which has a mild regularizing effect and can reduce the need for dropout.

python
1from tensorflow import keras
2
3model = keras.Sequential([
4    keras.layers.Dense(128, input_shape=(100,)),
5    keras.layers.BatchNormalization(),
6    keras.layers.Activation('relu'),
7    keras.layers.Dense(64),
8    keras.layers.BatchNormalization(),
9    keras.layers.Activation('relu'),
10    keras.layers.Dense(10, activation='softmax')
11])

Choosing the Right Strategy

The best strategy depends on your situation.

  • Small dataset: Start with data augmentation and regularization.
  • Deep neural network: Combine dropout, early stopping, and batch normalization.
  • Tree-based model: Limit depth, increase min_samples_leaf, and use cross-validation.
  • High-dimensional input: Apply L1 regularization or feature selection to remove irrelevant features.
  • Training loss still high: The model may be underfitting, not overfitting. Increase capacity before applying regularization.

In practice, you will often combine multiple strategies. For example, a typical deep learning setup uses data augmentation, dropout, L2 regularization, and early stopping together.

Common Pitfalls

Applying regularization when the model is underfitting. If training loss is already high, adding regularization or dropout makes things worse. First ensure the model can fit the training data, then address overfitting.

Setting dropout too high. Dropout rates above 0.5 can prevent the network from learning effectively. Start with 0.2 and increase gradually while monitoring validation performance.

Not using a held-out test set. If you tune hyperparameters against the validation set repeatedly, you can overfit to the validation data itself. Keep a separate test set that you only evaluate at the very end.

Ignoring data quality. Label noise, duplicate samples, and data leakage can all cause apparent overfitting. Before tuning the model, verify that the data is clean and the train/validation split does not leak information.

Summary

Overfitting happens when a model learns noise in the training data instead of general patterns. The main strategies to combat it are increasing training data, simplifying the model, applying regularization (L1/L2), using dropout, implementing early stopping, and validating with cross-validation. Diagnose overfitting by comparing training and validation metrics, then choose strategies based on your model type, data size, and observed symptoms. Combining multiple techniques typically produces the best results.


Course illustration
Course illustration

All Rights Reserved.