AI-powered waste classification for environmental awareness and sustainable waste management.
EcoVision is a web-based application that leverages deep learning and computer vision to classify waste items as biodegradable or non-biodegradable in real-time. Users upload images of waste items and receive instant predictions along with environmental impact scores, decomposition time estimates, and actionable recycling recommendations. The system achieves 89% validation accuracy using transfer learning with MobileNetV2, providing sub-second predictions through an intuitive web interface.
Backend
- Flask - RESTful API server
- TensorFlow/Keras - Deep learning inference
- OpenCV - Image preprocessing
- NumPy - Numerical operations
- Gunicorn - Production WSGI server
Frontend
- Vanilla JavaScript - Client-side interactions
- HTML5/CSS3 - Responsive UI
- AJAX - Asynchronous API calls
ML Model
- MobileNetV2 - Transfer learning base
- ImageNet weights - Pre-trained feature extraction
- Binary classification - Sigmoid activation layer
Infrastructure
- Python 3.11 runtime
- Render.com deployment (configured)
Improper waste disposal contributes significantly to environmental degradation, with millions of tons of recyclable materials ending up in landfills annually. Many individuals struggle to correctly identify whether items are biodegradable or recyclable, leading to contamination of recycling streams and reduced efficiency of waste management systems.
EcoVision addresses this knowledge gap by democratizing access to waste classification technology. By providing instant, accurate feedback on waste categorization along with educational content about environmental impact, the application empowers users to make informed disposal decisions. This project demonstrates how accessible AI can drive behavioral change toward more sustainable waste management practices at the individual level.
┌─────────────┐
│ Browser │
│ (Client) │
└──────┬──────┘
│ HTTP (image upload)
▼
┌─────────────────────────────┐
│ Flask Web Server │
│ ┌───────────────────────┐ │
│ │ /predict endpoint │ │
│ │ /health endpoint │ │
│ │ Static file serving │ │
│ └───────────────────────┘ │
└──────────┬──────────────────┘
│
▼
┌──────────────────────────────┐
│ Image Processing Layer │
│ - File validation │
│ - OpenCV preprocessing │
│ - Resize to 96×96 │
│ - Normalization (0-1) │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ ML Inference Engine │
│ - MobileNetV2 model │
│ - Binary classification │
│ - Confidence scoring │
└──────────┬───────────────────┘
│
▼
┌──────────────────────────────┐
│ Response Generation │
│ - Class mapping │
│ - Eco-impact lookup │
│ - JSON serialization │
└──────────────────────────────┘
Request Flow
-
File Upload Handler (
/predictendpoint)- Validates file extension against whitelist
- Secures filename to prevent path traversal
- Saves to temporary
uploads/directory - Returns 400 for invalid files
-
Image Preprocessing Pipeline
imread() → cvtColor(BGR→RGB) → resize(96×96) → float32 cast → normalize(/255) → expand_dims()
-
Model Inference
- Single forward pass through frozen MobileNetV2
- Sigmoid output: [0.0-1.0]
- Threshold at 0.5 for binary decision
- Returns raw probability score
-
Post-Processing
- Map prediction to class label
- Calculate confidence percentage
- Lookup eco-impact metadata from dictionary
- Cleanup: delete uploaded file
-
Response Structure
{ "classification": "Biodegradable (Organic)", "confidence": "94.32%", "eco_score": "2/10", "decompose_time": "2-6 months", "tip": "Compost organic waste..." }
Model Architecture
Input: (96, 96, 3) RGB image
↓
MobileNetV2 Base (frozen)
- Depth-wise separable convolutions
- 53 layers, 2.2M parameters
- Pre-trained ImageNet weights
↓
GlobalAveragePooling2D
- Reduces spatial dimensions
- Output: (1280,)
↓
Dropout(0.3)
- Regularization during training
↓
Dense(1, activation='sigmoid')
- Binary classification
- Output: [0.0, 1.0]
Training Pipeline (train_model.py)
- Data augmentation: rotation (15°), horizontal flip
- Batch size: 128 for GPU efficiency
- Epochs: 5 (prevents overfitting on binary task)
- Optimizer: Adam (lr=0.001)
- Loss: Binary cross-entropy
1. Transfer Learning with MobileNetV2
- Decision: Use pre-trained MobileNetV2 instead of training from scratch
- Rationale:
- Achieves 89% accuracy with only 5 epochs (~2-3 minutes training)
- MobileNetV2 is optimized for edge devices (low latency)
- Pre-trained ImageNet weights provide robust feature extraction
- Small model size (9MB) enables fast deployment
2. Binary Classification Over Multi-Class
- Decision: Collapse waste categories into biodegradable vs. non-biodegradable
- Rationale:
- Simpler decision boundary improves accuracy
- More interpretable for end-users
- Sufficient granularity for primary use case (disposal guidance)
- Reduces data requirements and training complexity
3. 96×96 Input Resolution
- Decision: Use 96×96 instead of standard 224×224
- Rationale:
- 5.4× fewer pixels reduces inference time
- Waste classification doesn't require fine-grained texture analysis
- Lower memory footprint for deployment
- Faster image preprocessing on client uploads
4. Stateless Flask API
- Decision: RESTful design with no session state
- Rationale:
- Simplifies horizontal scaling
- No database dependency for MVP
- Ephemeral file storage (immediate cleanup)
- Clear separation of concerns
5. Frontend-Backend Separation
- Decision: Vanilla JS with AJAX instead of server-side rendering
- Rationale:
- Async uploads provide better UX (no page reload)
- Enables future migration to SPA framework
- API-first design supports mobile app development
- Cleaner separation for collaborative development
6. In-Memory Model Loading
- Decision: Load model once at server startup
- Rationale:
- Eliminates per-request loading overhead (~2s)
- Acceptable memory footprint (~50MB)
- Trade-off favors latency over memory for this use case
Failure: Server starts without waste_classifier_model.h5
- Symptom: All predictions return 503 Service Unavailable
- Detection: Health check endpoint returns
model_loaded: false - Mitigation:
- Startup validation logs warning if model missing
- Health endpoint exposes model status for monitoring
- README provides clear training instructions
- CI/CD should verify model artifact exists before deployment
Failure: Server crashes under concurrent requests
- Symptom: Gunicorn workers killed by OS
- Root Cause: Multiple 96×96 images + model weights exceed RAM
- Mitigation:
- Set
MAX_CONTENT_LENGTH = 16MBto limit upload size - Use Gunicorn with
--workers=1 --threads=2for memory-constrained environments - Implement request queuing with Redis for high traffic
- Configure swap space as emergency buffer
- Monitor memory usage; scale vertically if sustained >80%
- Set
Failure: Attacker uploads executable disguised as image
- Symptom: Arbitrary code execution on server
- Mitigation:
- Whitelist file extensions (png, jpg, jpeg only)
- Use
secure_filename()to sanitize paths - Validate file headers with
imghdror magic numbers - Isolate
uploads/directory with restrictive permissions - Delete files immediately after processing (no persistence)
Failure: cv2.imread() returns None for corrupted images
- Symptom:
NoneTypeerror crashes prediction endpoint - Mitigation:
- Wrap preprocessing in try-except block
- Validate
img is not Nonebefore resize - Return 400 with descriptive error message
- Log failed uploads for debugging
Failure: First request takes 5-10s due to TensorFlow initialization
- Symptom: User perceives app as unresponsive
- Mitigation:
- Warm up model with dummy prediction at startup
- Use serverless keep-warm ping (cron job hitting
/health) - Display loading states prominently in UI
- Set realistic timeout expectations in frontend (30s)
Failure: Model confidently misclassifies unusual waste (e.g., e-waste)
- Symptom: Incorrect disposal guidance
- Mitigation:
- Display confidence scores to indicate uncertainty
- Add fallback message for low-confidence predictions (<60%)
- Implement user feedback mechanism (thumbs up/down)
- Periodic retraining with crowdsourced corrections
- Expand dataset to include edge cases
Failure: Frontend hosted separately cannot call API
- Symptom: Browser blocks requests with CORS error
- Mitigation:
flask-corsalready installed and configured- Verify
CORS(app)applies to all routes - Whitelist specific origins in production (not
*) - Test cross-origin requests before deployment
Failure: TensorFlow 2.20 incompatible with NumPy 2.x
- Symptom: Import errors crash server startup
- Mitigation:
- Pin
numpy>=1.23.0,<2.0.0in requirements.txt - Use virtual environment to isolate dependencies
- Lock dependency versions after successful deployment
- Test
pip install -r requirements.txtin CI pipeline
- Pin
Failure: uploads/ directory fills disk on high-traffic days
- Symptom: New uploads fail with disk I/O errors
- Mitigation:
- Immediate file deletion after processing (already implemented)
- Scheduled cron job to purge orphaned files older than 1 hour
- Monitor disk usage; alert if >90% full
- Use object storage (S3) if scaling beyond single server
Failure: Slow inference (>30s) causes worker to be killed
- Symptom: 502 Bad Gateway errors under load
- Mitigation:
- Set
--timeout=60in Gunicorn config - Profile model inference; optimize bottlenecks
- Add request timeout handling in Flask (return 408)
- Use async workers (
--worker-class=gevent) if needed
- Set
# Clone repository
git clone https://github.com/Developer-Sahil/Week-2.git
cd Week-2
# Install dependencies
pip install -r requirements.txt
# Train model (if not present)
python train_model.py
# Run application
python app.pyVisit https://ecovision-zpke.onrender.com/ to use the application.
Author: Sahil Sharma
License: MIT
Dataset: Waste Classification Data - Kaggle