A Guide to Debug your ML Model
Introduction
When a model fails to meet expectations, the instinct is often to tweak hyperparameters or switch architectures. However, experience from building production systems at KishnaKushwaha shows that the majority of issues stem from data quality or pipeline bugs. Recognizing where to look first saves hours of fruitless experimentation.
We will cover a structured checklist: verify data integrity, detect leakage, assess class imbalance, inspect missing values, and then move on to modelâcentric diagnostics such as loss curves, overfitting signs, and underfitting signals. Each step includes practical code snippets you can drop into a notebook. If you're exploring this area, check out AI interview prep tool â Try Intervu free.
The techniques described here have been applied to improve the predictive maintenance models in GrowthAI, the resumeâmatching engine in Intervu, and the intent classification module of the Voice Agent.
Why It Matters
A model that appears to perform well in validation but collapses in production often suffers from subtle data leakage or preprocessing mismatches. These issues erode trust and can lead to costly business decisions based on faulty predictions.
By systematically checking for NaNs, outliers, and leakage before tuning hyperparameters, you ensure that any performance gains are genuine. This approach has reduced debugging cycles by roughly 40âŻ% in the projects led by Kishna.
Furthermore, understanding whether a model is overfitting or underfitting guides you toward the right remedyâregularization versus increased capacityâsaving compute resources and avoiding wasted experiments.
Core Concepts
Before diving into code, it helps to define the key phenomena we will hunt for.
- Data leakage: Information from the future or the target inadvertently becomes a feature, inflating validation metrics.
- Missing values: NaNs that propagate through calculations can produce NaN predictions or break gradient flow.
- Class imbalance: One label dominates the dataset, allowing a model to achieve high accuracy by always predicting the majority class.
- Outliers: Extreme values can skew loss surfaces, especially for distanceâbased or linear models.
- Overfitting: Training accuracy far exceeds test accuracy, indicating memorization.
- Underfitting: Both training and test accuracies remain low, suggesting insufficient model capacity or inadequate training.
Each concept has a corresponding diagnostic tool, which we will explore next.
Architecture and How It Works
The debugging workflow follows a linear pipeline that can be iterated as new issues surface.
This structure mirrors the validation strategy used in the Voice Agent project, where a strict temporal split prevented leakage of future utterance features.
StepâbyâStep Implementation
Below is a concrete implementation using Python, pandas, and scikitâlearn. Feel free to adapt the snippet to PyTorch or TensorFlow workflows.
# 1. Load data
import pandas as pd
df = pd.read_csv('/assets/datasets/telemetry.csv')
# 2. Separate features and target
X = df.drop(columns=['failure'])
y = df['failure']
# 3. Split BEFORE any preprocessing
from sklearn.model_selection import train_test_split
X_temp, X_test, y_temp, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y)
X_train, X_val, y_train, y_val = train_test_split(
X_temp, y_temp, test_size=0.25, random_state=42, stratify=y_temp) # 0.25 Ă 0.8 = 0.2 validation
# 4. Check for NaNs in the training set
def report_nans(dataframe):
nan_counts = dataframe.isnull().sum()
total = len(dataframe)
nan_pct = (nan_counts / total) * 100
return nan_counts[nan_counts > 0], nan_pct[nan_pct > 0]
nan_cols, nan_pct = report_nans(X_train)
print('Columns with NaNs:', nan_cols.to_dict())
print('Percentage missing:', nan_pct.to_dict())
# 5. Simple imputation (median) fitted on train only
from sklearn.impute import SimpleImputer
imp = SimpleImputer(strategy='median')
X_train_imp = imp.fit_transform(X_train)
X_val_imp = imp.transform(X_val)
X_test_imp = imp.transform(X_test)
# 6. Scale features (standardization) fitted on train
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train_imp)
X_val_scaled = scaler.transform(X_val_imp)
X_test_scaled = scaler.transform(X_test_imp)
# 7. Baseline model
from sklearn.linear_model import LogisticRegression
baseline = LogisticRegression(max_iter=1000, n_jobs=-1)
baseline.fit(X_train_scaled, y_train)
print('Baseline val accuracy:', baseline.score(X_val_scaled, y_val))
# 8. Placeholder for your complex model (e.g., a neural net)
# Train it, then compare validation/test scores to the baseline.
This script guarantees that no information from the validation or test sets leaks into the preprocessing steps, a mistake that once caused a 15âŻ% overestimation of accuracy in the GrowthAI forecasting module.
After confirming that the baseline outperforms a constant predictor, you can proceed to train your main architecture while watching for the warning signs discussed earlier.
Practical Examples
Example 1: Detecting and Handling Missing Values
Suppose you notice that the column âsensor_3â has 12âŻ% missing entries. Instead of dropping the column, you can impute using the median value computed solely from the training split, as shown in the snippet above. This preserves the featureâs distribution while avoiding leakage.
Visual inspection of a histogram before and after imputation can reveal whether the imputed values create an artificial spike; if they do, consider using a more sophisticated method like iterative imputation.
Example 2: Spotting Data Leakage Through Temporal Features
In a predictive maintenance scenario, you might inadvertently include a feature like âdays_since_last_serviceâ that is calculated using the failure timestamp itself. To audit, compute the correlation between each feature and the target in the training set; an unusually high absolute correlation (>0.9) warrants investigation.
One effective test is to train a model on a single batch (see ExampleâŻ3) and verify that loss drops to near zero. If it does not, the problem may be a broken pipeline rather than the model architecture.
Example 3: SingleâBatch Overfit Test
The following PyTorch snippet grabs one batch of data and trains the model for many epochs. If the architecture and learning rate are suitable, the loss should approach zero.
import torch
import torch.nn as nn
import torch.optim as optim
# Assume `train_loader` yields batches of tensors
model = MyModel() # replace with your architecture
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
# Grab a single batch
batch_x, batch_y = next(iter(train_loader))
model.train()
for epoch in range(200):
optimizer.zero_grad()
outputs = model(batch_x)
loss = criterion(outputs, batch_y)
loss.backward()
optimizer.step()
if epoch % 20 == 0:
print(f'Epoch {epoch}, loss: {loss.item():.6f}')
# After the loop, loss should be close to 0 if the model can learn
If the loss remains flat, check the learning rate (too high or too low), verify that gradients are not vanishing, and ensure the loss function matches the task (e.g., use BCEWithLogitsLoss for binary classification). This test saved the Intervu team from weeks of tuning a transformer whose embedding layer was accidentally set to nonâtrainable.
Frequently Asked Questions (FAQs)
Q: What is the first thing I should check when my modelâs validation accuracy is unexpectedly high?
A: Begin by looking for data leakage. Verify that you split the data before any preprocessing and that no feature contains information from the target or future timestamps. A quick sanity check is to train a model on a single batch; if loss drops to near zero, the architecture can learn, suggesting the high validation score may be due to leakage.
Q: How can I detect missing values efficiently in a large pandas DataFrame?
A: Use df.isnull().sum() to get missing counts per column, then divide by len(df) to obtain percentages. Columns with a high percentage (e.g., >20âŻ%) may warrant dropping or specialized imputation, while low percentages can be handled with median or mean imputation fitted on the training set only.
Q: What is a reliable way to identify outliers without assuming a Gaussian distribution?
A: Apply the Interquartile Range (IQR) method: compute Q1 and Q3, then flag values below Q1 â 1.5ĂIQR or above Q3 + 1.5ĂIQR. This technique works well for skewed distributions and is resistant to extreme values.
Q: My model shows 99âŻ% training accuracy but only 60âŻ% test accuracy. What does this indicate?
A: This large gap is a classic sign of overfitting. The model has memorized training nuances rather than learning generalizable patterns. Mitigate it by adding regularization (L2 weight decay, dropout), increasing the size of the training set via data augmentation, or using early stopping based on validation loss.
Q: Both training and test accuracies are low. How should I proceed?
A: The model is underfitting. Increase model capacity (more layers, neurons, or trees), train for additional epochs, or enrich the feature set (e.g., extract day_of_week, hour_of_day from timestamps, or create interaction features). Reâevaluate after each change.
Q: How does severe class imbalance affect model evaluation?
A: When one class exceeds roughly 90âŻ% of the samples, a model can achieve high accuracy by always predicting the majority class while providing no useful signal for the minority class. Use metrics such as F1âscore, precisionârecall AUC, or consider resampling techniques (SMOTE, undersampling) and classâweighted loss functions.
Q: What preprocessing steps must happen after the train/validation/test split to avoid leakage?
A: All fitting operationsâimputation, scaling, encoding, dimensionality reductionâmust be performed exclusively on the training data. The learned parameters are then applied to validation and test splits. This prevents information from leaking into the preprocessing stage.
Q: Is it necessary to inspect prediction residuals?
A: Yes. Plotting residuals (prediction â true value) can reveal systematic biases that aggregate metrics hide. Patterns such as increasing error with predicted magnitude suggest heteroscedasticity, prompting a transformation of the target or a different loss function.
Q: How do I know if my learning rate is appropriate?
A: Run the singleâbatch overfit test. If loss fails to decrease, try lowering the learning rate. If loss oscillates or diverges, reduce it further. Conversely, if loss drops quickly but then plateaus at a high value, consider a slightly higher rate or a learningârate schedule.
Conclusion
Debugging machine learning models is less about random tweaks and more about a disciplined, evidenceâbased process. By first eliminating dataâcentric pitfallsâleakage, missing values, outliers, and class imbalanceâyou create a trustworthy foundation for model training. Subsequent checks on loss curves, singleâbatch learnability, and biasâvariance tradeâoffs guide you toward the right architectural or regularization adjustments.
Applying this workflow has consistently improved the reliability of systems such as GrowthAIâs anomaly detector, Intervuâs skillâmatching classifier, and the Voice Agentâs intent parser. Remember: the model is only as good as the data it learns from and the rigor with which you validate each step. Keep a notebook of your debugging experiments; over time, youâll develop an intuition that turns frustrating failures into rapid insights.
Explore more technical guides and tutorials on our articles page.