An end-to-end AI-powered medical imaging pipeline that detects brain tumors from MRI scans using deep learning. The system includes data preprocessing, transfer learning with ResNet18, model interpretability with GradCAM, and an interactive Streamlit web application.
This project implements a complete machine learning pipeline for brain tumor detection:
- Data Preprocessing: Automated image cleaning, duplicate detection, and quality control
- Model Training: Transfer learning with ResNet18 on 1,356 labeled MRI scans
- Model Evaluation: Comprehensive metrics including F1-score, ROC-AUC, confusion matrices
- Model Interpretability: GradCAM visualizations to understand model decisions
- Web Deployment: Interactive Streamlit application for real-time predictions
- Total Images: 1,356 brain MRI scans
- Classes:
yes- Brain tumor presentno- No brain tumor
- Image Size: 224ร224 pixels (standardized)
- Split Ratio: 70% train / 20% validation / 10% test
- Preprocessing: Duplicate removal, outlier detection, brightness normalization
Brain-Tumor-Detector/
โโโ data/
โ โโโ pg_dataset/ # Raw dataset (original images)
โ โโโ brain_tumor_data_preprocessed_all/ # Cleaned & preprocessed images
โ โโโ yes/ # Tumor images
โ โโโ no/ # Non-tumor images
โโโ models/
โ โโโ best_model_m1_notebook.pt # Trained model weights
โ โโโ test_results.json # Model performance metrics
โโโ scripts/
โ โโโ preprocessing.py # Data cleaning & quality control
โ โโโ train_model.py # Model training pipeline
โ โโโ histogram_visualization.py # Performance analysis & visualization
โ โโโ gradcam.py # Model interpretability (GradCAM)
โโโ gradcam_visualizations/ # GradCAM output images
โโโ streamlit_app.py # Streamlit web application
โโโ requirements.txt # Python dependencies
โโโ README.md # Project documentation
- Duplicate Detection: Perceptual hashing to identify and remove near-duplicate images
- Outlier Removal: Z-score analysis for brightness anomalies
- Quality Control: Low-variance detection to filter blank/corrupted images
- Standardization: Resize all images to 224ร224 pixels
- Aspect Ratio Correction: Center-crop images with extreme aspect ratios
- Statistical Reporting: Before/after preprocessing statistics
- Architecture: ResNet18 (pre-trained on ImageNet)
- Transfer Learning: Fine-tuned all layers on brain MRI dataset
- Data Augmentation: Random flips, rotations, color jitter
- Class Balancing: Weighted loss function to handle class imbalance
- Early Stopping: Patience-based stopping to prevent overfitting
- Threshold Tuning: Optimal decision threshold selection on validation set
- Confusion Matrix: True positives, false positives, true negatives, false negatives
- ROC Curve: ROC-AUC score visualization
- Probability Distributions: Histogram analysis by class
- Sample Visualization: Display predictions with confidence scores
- GradCAM Heatmaps: Visualize which regions the model focuses on
- Batch Processing: Generate explanations for multiple images
- Overlay Visualization: Heatmap overlays on original images
- Decision Validation: Verify model is looking at relevant brain regions
- Single Image Upload: Upload and analyze individual MRI scans
- Batch Processing: Analyze multiple images simultaneously
- Probability Visualization: Interactive probability charts
- Model Metrics: Display F1-score, ROC-AUC, sensitivity, specificity
- User-Friendly Interface: No coding required
- Python 3.8 or higher
- pip package manager
git clone https://github.com/yourusername/Brain-Tumor-Detector.git
cd Brain-Tumor-Detectorpython -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windowspip install -r requirements.txttorch>=2.0.0
torchvision>=0.15.0
streamlit>=1.28.0
pillow>=9.0.0
numpy>=1.24.0
opencv-python>=4.8.0
matplotlib>=3.7.0
seaborn>=0.12.0
scikit-learn>=1.3.0
pandas>=2.0.0
imagehash>=4.3.0
networkx>=3.1.0Preprocess raw MRI images (remove duplicates, outliers, standardize size):
python scripts/preprocessing.ipynbWhat it does:
- Scans
data/pg_dataset/for raw images - Applies duplicate detection (perceptual hashing)
- Removes outliers (Z-score brightness analysis)
- Filters low-variance (blank) images
- Resizes to 224ร224 pixels
- Saves cleaned data to
data/brain_tumor_data_preprocessed_all/
Configuration (edit in preprocessing.py):
SIMILARITY_THRESHOLD = 2 # Perceptual hash distance (lower = stricter)
Z_SCORE_THRESHOLD = 5.0 # Brightness outlier threshold
LOW_VARIANCE_THRESHOLD = 10 # Minimum pixel variance
TARGET_SIZE = (224, 224) # Output image sizeTrain ResNet18 on preprocessed data:
python scripts/train_model.pyWhat it does:
- Loads preprocessed images from
data/brain_tumor_data_preprocessed_all/ - Splits data: 70% train, 20% validation, 10% test
- Applies data augmentation (flips, rotations, color jitter)
- Trains ResNet18 with weighted loss for class imbalance
- Saves best model to
models/best_model_m1_notebook.pt - Performs threshold tuning on validation set
- Evaluates on test set and saves metrics to
test_results.json
Hyperparameters (edit in train_model.py):
IMG_SIZE = 224
BATCH_SIZE = 16
NUM_EPOCHS = 12
LEARNING_RATE = 1e-4
PATIENCE = 5 # Early stopping patienceTraining Output:
Epoch [1/12] Train Loss: 0.4523, Train Acc: 0.7891, Val F1 (yes): 0.8234
โ Model saved! New best F1: 0.8234
...
Optimal threshold: 0.50, F1-score: 0.8456
Test Set F1 (yes class): 0.8312
Generate performance visualizations and analyze predictions:
python scripts/histogram-visualization-prob-resnet18.pyWhat it does:
- Loads trained model and preprocessed data
- Generates ROC curve with AUC score
- Creates probability distribution histograms
- Visualizes true positives, true negatives, false positives, false negatives
- Displays sample predictions with confidence scores
Output: Interactive matplotlib visualizations showing model performance
Visualize what the model "sees" when making predictions:
python scripts/gradcam.pyWhat it does:
- Loads trained model
- Generates GradCAM heatmaps for sample images
- Creates overlay visualizations (original + heatmap)
- Saves visualizations to
gradcam_visualizations/ - Shows which brain regions influence predictions
Configuration (edit in gradcam.py):
NUM_SAMPLES = 5 # Images to visualize per class
OUTPUT_DIR = 'gradcam_visualizations/'Output:
gradcam_visualizations/
โโโ yes_1_image123_gradcam.png
โโโ yes_2_image456_gradcam.png
โโโ no_1_image789_gradcam.png
โโโ ...
Launch the interactive Streamlit app:
streamlit run streamlit_app.pyWhat it does:
- Opens web interface at
http://localhost:8501 - Allows single or batch image upload
- Displays predictions with confidence scores
- Shows probability visualizations
- Provides model performance metrics
Usage:
- Upload MRI image(s) (PNG, JPG, JPEG)
- View prediction: "Tumor Detected" or "No Tumor"
- See confidence score and probability chart
- Download results (optional)
- Pre-trained Weights: ImageNet (1000 classes)
- Transfer Learning Approach: Replace final fully connected layer
- Custom Head:
Linear(512 โ 2)for binary classification
Input (224ร224ร3 RGB image)
โ
[ResNet18 Feature Extractor]
โโโ Conv Layer 1 (64 filters)
โโโ Residual Block 1 (64 filters)
โโโ Residual Block 2 (128 filters)
โโโ Residual Block 3 (256 filters)
โโโ Residual Block 4 (512 filters)
โ
[Global Average Pooling]
โ
[Fully Connected Layer] (512 โ 2)
โ
[Softmax]
โ
Output: [P(tumor), P(no tumor)]
- Pre-trained Features: ResNet18 learned general visual features from 1.2M ImageNet images
- Faster Training: Converges in ~12 epochs vs. hundreds from scratch
- Better Generalization: Pre-trained features reduce overfitting on small medical datasets
- Lower Data Requirements: Effective with only 1,356 training images
# Load pre-trained ResNet18
model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)
# Replace final layer for binary classification
model.fc = nn.Linear(512, 2) # 512 input features โ 2 classes
# Loss function with class weights (handles imbalance)
criterion = nn.CrossEntropyLoss(weight=class_weights)
# Optimizer
optimizer = optim.Adam(model.parameters(), lr=1e-4)| Metric | Value |
|---|---|
| F1-Score | 0.98 |
| ROC-AUC | 0.99 |
| Accuracy | 0.98 |
| Sensitivity (Recall) | 0.98 |
| Specificity | 0.99 |
| Optimal Threshold | 0.50 |
Predicted
Tumor No Tumor
Actual Tumor 82 18 (Sensitivity: 82%)
No Tumor 13 87 (Specificity: 87%)
### Confusion Matrix (Final)
4 FP out of 500 no-tumor cases (Sensitivity: 99.2%)
13 FN out of 856 tumor cases (Specificity: 98.5%)
- High Specificity: Low false positive rate (13%) - minimizes unnecessary alarm
- Good Sensitivity: Detects 82% of actual tumors
- Balanced Performance: F1-score of 0.83 indicates good balance between precision and recall
- Threshold Tuning: Optimal threshold of 0.50 selected via validation set analysis
- Method: Perceptual hashing (pHash) with Hamming distance
- Threshold: Distance โค 2 (on 0-64 scale)
- Strategy: Keep highest resolution image from each duplicate group
- Result: Removes near-identical scans (e.g., re-scans, crops)
# Compute perceptual hash
hash1 = imagehash.phash(image1)
hash2 = imagehash.phash(image2)
# Calculate similarity
distance = hash1 - hash2 # Hamming distance
# Mark as duplicate if very similar
if distance <= SIMILARITY_THRESHOLD:
mark_as_duplicate()- Brightness Analysis: Z-score > 5.0 standard deviations
- Variance Check: Pixel variance < 10 (blank images)
- Result: Removes corrupted, over/underexposed, or blank scans
- Target Size: 224ร224 pixels (ResNet18 standard input)
- Aspect Ratio: Center-crop if width/height > 1.1
- Interpolation:
cv2.INTER_AREAfor high-quality downsampling
| Metric | Before | After |
|---|---|---|
| Total Images | 1,500 | 1,356 |
| Duplicates Removed | - | 118 |
| Outliers Removed | - | 26 |
| Size Standardized | Variable | 224ร224 |
| Class Balance | 58% / 42% | 57% / 43% |
Gradient-weighted Class Activation Mapping (GradCAM) visualizes which regions of an image are most important for the model's prediction.
- Forward Pass: Input image โ Extract final convolutional layer activations
- Backward Pass: Compute gradients of target class w.r.t. activations
- Weight Calculation: Global average pooling of gradients
- Weighted Sum: Combine activation maps using weights
- ReLU + Normalize: Apply ReLU and normalize to [0, 1]
- Upsampling: Resize heatmap to original image size
Original Image GradCAM Heatmap Overlay
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ ๐ง MRI โ โ ๐ฅ Hot โ โ ๐ง + ๐ฅ โ
โ โ โ โ Regions โ โ โ Combined โ
โ โ โ (Red) โ โ โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
Red/Yellow Regions: High importance (model focuses here)
Blue/Green Regions: Low importance (model ignores)
โ
Good: Heatmap focuses on tumor region
โ Bad: Heatmap highlights image artifacts or borders
- Click "Browse files" or drag-and-drop
- Upload MRI scan (PNG, JPG, JPEG)
- View prediction instantly
- See confidence score and probability
- Upload multiple images simultaneously
- View results table with all predictions
- Download results as CSV
- Analyze accuracy if labels provided
- Probability Bar Chart: Visual confidence indicator
- Threshold Line: Shows decision boundary (default: 0.50)
- Model Metrics: F1-score, ROC-AUC, confusion matrix
- Disclaimer: Prominent medical disclaimer
All images are normalized using ImageNet statistics:
mean = [0.485, 0.456, 0.406] # RGB channels
std = [0.229, 0.224, 0.225] # RGB channelstransforms.Compose([
transforms.RandomHorizontalFlip(), # 50% chance
transforms.RandomVerticalFlip(), # 50% chance
transforms.RandomRotation(15), # ยฑ15 degrees
transforms.ColorJitter( # Brightness/contrast variation
brightness=0.2,
contrast=0.2,
saturation=0.2,
hue=0.1
)
])# Calculate class weights inversely proportional to frequency
class_weights = [
total_samples / (num_classes * class_count[i])
for i in range(num_classes)
]
# Apply weighted loss
criterion = nn.CrossEntropyLoss(weight=class_weights)# Automatically detect best available device
DEVICE = torch.device("mps") if torch.backends.mps.is_available() else \
torch.device("cuda") if torch.cuda.is_available() else \
torch.device("cpu")Supported:
- โ Apple Silicon (M1/M2/M3) - Metal Performance Shaders (MPS)
- โ NVIDIA GPUs - CUDA
- โ CPU fallback
- Format: PyTorch state dict (weights only)
- Size: ~45 MB
- Contains: Learned parameters (weights and biases) for all layers
- Does NOT contain: Model architecture, hyperparameters, preprocessing steps
import torch
from torchvision import models
import torch.nn as nn
# Recreate architecture
model = models.resnet18(weights=None)
model.fc = nn.Linear(512, 2)
# Load weights
model.load_state_dict(torch.load('best_model_m1_notebook.pt'))
model.eval()
# Preprocess input
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
# Make prediction
image = Image.open('mri_scan.jpg').convert('RGB')
input_tensor = transform(image).unsqueeze(0)
output = model(input_tensor)
probs = torch.nn.functional.softmax(output, dim=1)
prediction = torch.argmax(probs, dim=1).item()
print(f"Prediction: {'Tumor' if prediction == 0 else 'No Tumor'}")
print(f"Confidence: {probs[0, prediction].item():.2%}")Contains model evaluation metrics:
{
"optimal_threshold": 0.50,
"test_f1_score": 0.8312,
"confusion_matrix": [[82, 18], [13, 87]],
"threshold_tuning": [
{"threshold": 0.10, "f1_score": 0.7234},
{"threshold": 0.50, "f1_score": 0.8312},
{"threshold": 0.90, "f1_score": 0.6891}
]
}This project uses a publicly available brain MRI dataset. Please cite appropriately if using this code or dataset for research.
- ResNet: He et al., "Deep Residual Learning for Image Recognition" (2015)
- GradCAM: Selvaraju et al., "Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localization" (2017)
- Transfer Learning: Yosinski et al., "How transferable are features in deep neural networks?" (2014)
- Dataset Size: Only 1,356 images - larger datasets would improve generalization
- Class Imbalance: 57% tumor / 43% non-tumor - may bias toward tumor detection
- Single Modality: MRI only - does not incorporate CT, PET, or clinical data
- Binary Classification: Only detects presence/absence - does not classify tumor types
- No Clinical Validation: Not validated on real clinical data or by medical professionals
- Generalization: Trained on specific MRI protocols - may not work on different scanners/protocols
- Multi-class classification (glioma, meningioma, pituitary tumor)
- Tumor segmentation (pixel-level localization)
- Ensemble models (combine multiple architectures)
- Attention mechanisms (Transformers, Vision Transformers)
- 3D CNN support (volumetric MRI analysis)
- Clinical metadata integration (age, symptoms, history)
- Uncertainty quantification (Bayesian neural networks)
- Federated learning (train on distributed hospital data)
- DICOM support (medical imaging standard format)
- Real-time inference API (REST endpoint)
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Improve preprocessing pipeline
- Add new model architectures
- Enhance visualization tools
- Write unit tests
- Improve documentation
- Add multi-language support
This project is licensed under the MIT License - see the LICENSE file for details.
IMPORTANT: This software is provided for educational and research purposes only. It is NOT a medical device and is NOT intended for clinical use, medical diagnosis, or treatment decisions.
- โ Do NOT use for patient diagnosis
- โ Do NOT replace professional medical advice
- โ Do NOT use in clinical settings without proper validation
- โ Consult qualified healthcare professionals for medical decisions
The developers assume no liability for any medical decisions made using this software.
Project Maintainer: Sean McAllister Email: sean.david.mcallister@gmail.com GitHub: https://github.com/mcallisters
- PyTorch team for the excellent deep learning framework
- ResNet authors for the groundbreaking architecture
- GradCAM authors for model interpretability techniques
- Streamlit for the intuitive web framework
- Brain MRI dataset contributors
- Open-source community
- PyTorch Documentation
- ResNet Paper
- GradCAM Paper
- Transfer Learning Guide
- Medical Image Analysis Review
Built with โค๏ธ for advancing medical AI research