Casting manufacturing dataset of submersible pump impellers to automate defect detection. Contains 7,348 grayscale images (300×300px) with two classes OK and Defective addressing the industry's manual inspection bottleneck that causes financial losses and accuracy gaps. We split the dataset as (5,307), validation (1,326), and test (715) with augmentation. Classes: OK and Defective.
| Metric | Value |
|---|---|
| Test Accuracy | 94% |
| Defect Recall | 100% |
| Defect Precision | 92% |
| F1-Score | 0.96 |
| ROC-AUC | 0.998 |
| Model Size | 495 KB |
# Clone/download repository
cd casting-defect-detection
# Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txtDataset: Kaggle Industrial Casting Product Dataset
- Train: 5,307 images (80% of train folder)
- Val: 1,326 images (20% of train folder)
- Test: 715 images (completely unseen)
- Classes: OK (262), Defective (453)
- Resolution: 300×300 grayscale
Augmentation Applied:
- Rotation (±20°), Horizontal/Vertical Flip
- Zoom (0.15), Brightness (0.85-1.15)
- Applied only to training set
Training: Open CastingCNN.ipynb and run cells sequentially.
3-Block Convolutional Neural Network
Input (300×300×1)
↓
Block 1: Conv2D(32) → BatchNorm → MaxPool
↓
Block 2: Conv2D(64) → BatchNorm → MaxPool
↓
Block 3: Conv2D(128) → BatchNorm → MaxPool [GradCAM source]
↓
GlobalAveragePooling → Dense(256) → Dropout(0.5)
↓
Output: Sigmoid (binary classification)
- Total Parameters: 126,849 (495 KB)
- Optimizer: Adam (learning_rate=1.25e-05)
- Loss: Binary CrossEntropy
- Batch Size: 32
precision recall f1-score support
OK 1.00 0.85 0.92 262
Defective 0.92 1.00 0.96 453
accuracy 0.94 715
weighted avg 0.95 0.94 0.94 715
- True Positives: 452/453 (99.8% catch rate)
- True Negatives: 222/262 (85% acceptance)
- False Negatives: 1 (defect escaped)
- False Positives: 40 (good parts rejected)
Key Observations:
- Training and validation curves move together (no overfitting)
- Convergence at epoch 24
- Loss decreases smoothly from 0.6 → 0.1
- Validation accuracy reaches 98%
from tensorflow.keras.models import load_model
import cv2
import numpy as np
# Load model
model = load_model('best_model.h5')
# Load and prepare image
img = cv2.imread('casting_image.png', cv2.IMREAD_GRAYSCALE)
img_array = cv2.resize(img, (300, 300)).astype(np.float32) / 255.0
img_input = np.expand_dims(img_array, axis=(0, -1))
# Predict
defect_prob = model.predict(img_input)[0][0]
is_defective = "Defective" if defect_prob > 0.5 else "OK"
print(f"Prediction: {is_defective}")
print(f"Confidence: {defect_prob*100:.2f}%")from pathlib import Path
import pandas as pd
casting_dir = Path('castings/')
results = []
for img_path in casting_dir.glob('*.png'):
img = cv2.imread(str(img_path), cv2.IMREAD_GRAYSCALE)
img_array = cv2.resize(img, (300, 300)).astype(np.float32) / 255.0
img_input = np.expand_dims(img_array, axis=(0, -1))
defect_prob = model.predict(img_input)[0][0]
results.append({
'image': img_path.name,
'defect_confidence': f"{defect_prob*100:.2f}%",
'prediction': 'Defective' if defect_prob > 0.5 else 'OK'
})
df = pd.DataFrame(results)
df.to_csv('inspection_results.csv', index=False)
print(df)import tensorflow as tf
def generate_gradcam(model, img_array, layer_name="block3_conv"):
"""Generate Grad-CAM heatmap"""
last_conv_layer = model.get_layer(layer_name)
grad_model = tf.keras.models.Model(
[model.inputs],
[last_conv_layer.output, model.output]
)
with tf.GradientTape() as tape:
conv_outputs, predictions = grad_model(img_array)
class_channel = predictions[:, 0]
grads = tape.gradient(class_channel, conv_outputs)
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))
conv_outputs = conv_outputs[0]
heatmap = conv_outputs @ pooled_grads[..., tf.newaxis]
heatmap = tf.squeeze(heatmap)
heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap)
return heatmap.numpy()
# Use it
heatmap = generate_gradcam(model, img_input)
# Visualize heatmap overlay on original imageGradCAM highlights which image regions influence the model's decision:
How to interpret:
- Red regions: High activation (important for decision)
- Blue regions: Low activation (ignored by model)
- Green/Yellow: Medium importance
This proves the model learns genuine defect patterns, not spurious features.
Interpretation:
- Two clear peaks: one at 0 (OK) and one at 1 (Defective)
- Clean separation indicates strong model confidence
- Decision threshold at 0.5 effectively separates classes
Why ROC-AUC = 0.998 is important:
- Model separates defective from OK across all thresholds
- Works perfectly even if you adjust decision threshold
- Robust to different operating points
- Better than threshold-dependent metrics alone
Model outputs mapped to 4 tier severity levels that are also changeable based on tolelrance during manufacturing
| Tier | Confidence | Action |
|---|---|---|
| PASS | < 50% | Accept part |
| LOW | 50-69% | Monitor |
| MODERATE | 70-89% | Manual review |
| CRITICAL | ≥ 90% | Reject immediately |
def assess_severity(defect_prob):
if defect_prob < 0.5:
return {'tier': 'PASS', 'action': 'Accept'}
elif defect_prob < 0.7:
return {'tier': 'LOW', 'action': 'Monitor'}
elif defect_prob < 0.9:
return {'tier': 'MODERATE', 'action': 'Manual Review'}
else:
return {'tier': 'CRITICAL', 'action': 'Reject'}
severity = assess_severity(0.95)
print(f"Severity: {severity['tier']} → {severity['action']}")
CNN-based-casting-defect-detection/
├── CastingCNN.ipynb
├── best_model.h5
├── requirements.txt
├── README.md
└── results
✓ 100% Defect Recall: Catches essentially all defects (only 1 missed out of 453)
✓ 92% Precision: When model rejects, 92% are truly defective
✓ 0.998 ROC-AUC: Near perfect class separation
✓ Explainable: GradCAM shows exactly where model focuses
Out of 715 test castings:
✓ Correct: 674 (94%)
├─ 222 good parts accepted
└─ 452 defects caught
✗ Errors: 41 (6%)
├─ 40 good parts rejected (15% false rejection)
└─ 1 defect escaped (0.2% miss rate - acceptable)
See requirements.txt:
tensorflow>=2.10
numpy>=1.21
opencv-python>=4.5
matplotlib>=3.5
pandas>=1.3
scikit-learn>=1.0
Install with:
pip install -r requirements.txtCourse Project Manufacturing Engineering ME 222 IIT Guwahati





