Multi-label deep learning system that predicts probable side effects of any drug molecule from its SMILES string or common name — served through a Flask web interface.
🎬 Demo Video: Watch / Download demo_recording.webm
Input: "Aspirin" or CC(=O)OC1=CC=CC=C1C(=O)O
Output: Rash (66%) · Dermatitis (63%) · Nausea (63%) · Vomiting (59%) ...
Early-stage drug development lacks scalable tools for side effect screening. Lab trials are expensive, slow, and restricted to known compounds. This project addresses that gap by training a neural network on molecular fingerprints to predict multi-label side effects for any small molecule — including novel drugs not yet in clinical databases.
- Dual input mode — accepts drug names (resolved via PubChem → ChEMBL fallback) or raw SMILES strings
- Multi-label prediction — simultaneously predicts across 300 side effect classes with per-class probability thresholds
- Per-class threshold tuning — thresholds optimized per label on the validation set to maximize F1, not simply fixed at 0.5
- Combined molecular features — ECFP4 Morgan fingerprints (2048-bit) concatenated with 200-dimensional RDKit physicochemical descriptors (2248-dim total)
- Focal Loss training — handles severe class imbalance across rare side effects (α=0.25, γ=2.0) with clipped positive-weight reweighting
- REST API —
/predict,/stats, and/examplesendpoints for programmatic access - Molecular property display — returns MolWt, LogP, and atom count alongside predictions
| Layer | Technology |
|---|---|
| Deep Learning | PyTorch 2.0+, Mixed-precision AMP |
| Cheminformatics | RDKit (Morgan FP, 200 descriptors) |
| Drug Lookup | PubChem REST API, ChEMBL API |
| Web Server | Flask |
| Training Utilities | scikit-learn, NumPy, tqdm |
| Visualization | Matplotlib, Seaborn |
User Input (Drug Name or SMILES)
│
▼
┌─────────────────────┐
│ drug_lookup.py │ PubChem → ChEMBL fallback (name → SMILES)
└────────┬────────────┘
│ SMILES
▼
┌─────────────────────┐
│ Feature Pipeline │ ECFP4 (2048-bit) + RDKit Descriptors (200-dim)
│ smiles_to_combined │ → 2248-dimensional float32 vector
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ MLP_MultiLabel │ Linear(2248→1024) → BN → ReLU → Dropout(0.3)
│ (predict.py) │ Linear(1024→512) → BN → ReLU → Dropout(0.3)
│ │ Linear(512→300) → Sigmoid
└────────┬────────────┘
│ Per-class probabilities
▼
┌─────────────────────┐
│ Per-class │ Thresholds tuned on validation set (grid search
│ Threshold Filter │ over [0.1, 0.9] in 50 steps per label)
└────────┬────────────┘
│
▼
Ranked Side Effect Predictions + Confidence Labels
# 1. Clone
git clone https://github.com/Prashikdev2315/Drug-Side-effect-Predictor.git
cd Drug-Side-effect-Predictor
# 2. Create virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Run the web app (pre-trained model ships in /checkpoints)
python app.pyOpen http://localhost:5000 in your browser.
- Enter a drug name (e.g.,
ibuprofen) or SMILES string - Select how many top predictions to display (default: 10)
- Click Predict — results show side effect name, probability %, threshold, and confidence label (Low / Medium / High)
python predict.py --smiles "CC(C)CC1=CC=C(C=C1)C(C)C(=O)O" --top_k 10python predict.py --interactive# Predict
curl -X POST http://localhost:5000/predict \
-H "Content-Type: application/json" \
-d '{"input": "aspirin", "top_k": 5}'
# Model stats
curl http://localhost:5000/stats
# Example molecules
curl http://localhost:5000/examples| Metric | Score |
|---|---|
| Micro F1 | 0.4021 |
| Macro F1 | 0.3316 |
| Micro Precision | 0.2689 |
| Micro Recall | 0.7968 |
| Per-label Accuracy | 44.9% |
Note: High recall (0.797) is intentional — the model is tuned to surface plausible side effects rather than suppress uncertain ones, reflecting safer clinical utility. Macro F1 is depressed by rare labels with few training examples.
| Challenge | Solution |
|---|---|
| Severe class imbalance — most side effects appear in <5% of drugs | Multi-label Focal Loss (α=0.25, γ=2.0) with clipped positive-weight reweighting (max 10×) |
| Fixed threshold underperforms on rare classes | Per-class threshold tuning via grid search on validation set; only classes with ≥5 positive examples are tuned |
| Users don't know SMILES syntax | drug_lookup.py resolves plain names using PubChem API with ChEMBL as fallback |
| Feature dimension mismatch on rerun | Auto-detects input dimension from first layer weight tensor; regenerates fingerprints if mismatch found |
| Windows multiprocessing deadlock in DataLoader | Set num_workers=0; used pin_memory=True to preserve throughput |
DrugSideEffectPrediction/
├── app.py # Flask server — routes /predict, /stats, /examples
├── model.py # MLP architecture, Focal Loss, training loop, metrics
├── predict.py # Inference pipeline (CLI + importable API)
├── drug_lookup.py # Drug name → SMILES via PubChem / ChEMBL
├── generate_metrics.py # Post-training metric generation
├── demo_metrics.py # Demo/reporting utilities
├── run.py # Training entry point
├── validate_setup.py # Environment validation
├── checkpoints/
│ ├── best_model.pt # Best epoch checkpoint (~34 MB)
│ ├── final_model.pt # Final model weights (~11 MB)
│ ├── inference_bundle.joblib # Config + thresholds + label names
│ ├── label_names.json # 300 side effect class names
│ ├── thresholds.npy # Per-class tuned thresholds
│ └── test_metrics.json # Saved evaluation results
├── templates/ # Jinja2 HTML templates
├── static/ # CSS / JS assets
├── X_ecfp.npy # Precomputed feature matrix
├── y_labels.npy # Multi-label target matrix
└── requirements.txt
- Replace MLP with a Graph Neural Network (GCN/GAT) operating directly on molecular graphs for richer structural induction bias
- Add attention / saliency maps to highlight which molecular substructures drive each prediction
- Drug-drug interaction module — predict adverse interactions between two SMILES inputs
- Integrate patient gene expression profiles for personalized side effect risk scoring
- Deploy on Hugging Face Spaces or Railway for public access
- Hyperparameter sweep via Optuna to improve Macro F1 on tail classes
MIT License — see LICENSE for details.
⚠️ Disclaimer: This tool is for academic and research use only. It is not a certified medical diagnostic system and must not substitute professional clinical judgment.