# CropIntel ML Pipeline Machine learning pipeline for crop disease classification using TensorFlow Lite. ## Working without Kaggle (collaborators) Training datasets are on Kaggle, but **you do not need Kaggle** to run the web app if someone shares trained weights. 1. Install inference deps from repo root: `pip install -r ml/requirements-inference.txt` 2. Download a zip of `ml/models/` (same layout as after training: `corn//…`, etc.): ```bash export CROPINTEL_MODELS_URL='https://…/cropintel-models.zip' python3 -m ml.scripts.fetch_models ``` 3. Run Next.js; `/api/predict` will call `scripts/predict.py`. **Docker:** see repo root `docker-compose.yml` and set `CROPINTEL_MODELS_URL` before `docker compose up`. **Maintainers:** package your local `ml/models/` for release: ```bash python3 -m ml.scripts.package_models -o cropintel-models.zip ``` --- ## Overview This ML pipeline trains deep learning models to classify crop diseases from leaf images. Models are trained using transfer learning with EfficientNetB0 and exported to TensorFlow Lite format for efficient production inference. ## Structure ``` ml/ ├── config.py # Configuration and hyperparameters ├── training/ # Training scripts │ ├── train_crop.py # Train model for single crop │ └── train_all_crops.py # Train models for all crops ├── inference/ # Inference modules │ └── tflite_predictor.py # TFLite predictor for production ├── utils/ # Utilities │ ├── data_loader.py # Dataset loading and preprocessing │ ├── model_builder.py # Model architecture │ ├── evaluation.py # Model evaluation metrics │ └── tflite_converter.py # TFLite conversion ├── scripts/ # Utility scripts │ ├── download_datasets.py # Download datasets from Kaggle │ └── create_synthetic_dataset.py # Random images for pipeline smoke tests (no Kaggle) ├── data/ # Dataset storage (gitignored) └── models/ # Trained models (gitignored) └── {crop}/ └── {version}/ ├── model.tflite ├── metadata.json ├── label_map.json ├── metrics.json └── training_info.json ``` ## Setup **Why a fresh `git clone` does not show “paper” accuracy:** `ml/data/` and `ml/models/` are not in git. You need either Kaggle downloads + training, or the synthetic smoke-test path below. ### Option A — Real data (Kaggle) 1. Install dependencies (from repository root): ```bash pip install -r ml/requirements.txt ``` 2. Set up Kaggle API credentials: - Install Kaggle CLI: `pip install kaggle` - Download `kaggle.json` from your Kaggle account settings - Place it at `~/.kaggle/kaggle.json` - Accept dataset terms on Kaggle website 3. Download datasets: ```bash python -m ml.scripts.download_datasets ``` ### Option B — No Kaggle (pipeline smoke test only) Random noise images are **not** diagnostically meaningful; they only prove training, evaluation, and TFLite export run on your machine. ```bash pip install -r ml/requirements.txt python -m ml.scripts.create_synthetic_dataset --crop corn --force python -m ml.training.train_crop --crop corn --epochs 2 --no-fine-tune ``` Use `--crop all` on the synthetic script to populate every crop before `train_all_crops`. ### Option C — Docker (same commands inside a container) From the repository root: ```bash docker compose -f docker-compose.ml.yml build docker compose -f docker-compose.ml.yml run --rm ml \ python -m ml.scripts.create_synthetic_dataset --crop corn --force docker compose -f docker-compose.ml.yml run --rm ml \ python -m ml.training.train_crop --crop corn --epochs 2 --no-fine-tune ``` Download with Kaggle inside Docker (host must have `~/.kaggle/kaggle.json`): ```bash docker compose -f docker-compose.ml.yml run --rm -v "$HOME/.kaggle:/root/.kaggle:ro" ml \ python -m ml.scripts.download_datasets ``` ### Optional: improve soybean healthy-class coverage If soybean healthy predictions are weak, add extra healthy soybean images from: - [Soybean Healthy and Diseased Images Dataset (Mendeley)](https://data.mendeley.com/datasets/w8vm4mm8t4/1) Place extracted data in one of: - `ml/data/soybean_mendeley/Healthy/` - `ml/data/soybean_healthy/Healthy/` - `ml/data/soybean_extra/Healthy/` The loader auto-includes these healthy images during soybean training. By default it also uses **`~/Soybean Healthy and Diseased Images Dataset/Soybean Healthy`** when that folder exists (same class label: **Healthy**). To point elsewhere: ```bash export CROPINTEL_SOYBEAN_HEALTHY_DIRS="/path/to/Soybean Healthy:/path/to/more/healthy" python -m ml.training.train_crop --crop soybean ``` (On macOS/Linux, separate multiple folders with `:` in that variable.) ## Training ### Train a single crop model: ```bash python -m ml.training.train_crop --crop corn --epochs 50 ``` ### Train all crops: ```bash python -m ml.training.train_all_crops --epochs 50 ``` ### Options: - `--crop`: Crop name (corn, soybean, wheat, rice) - `--epochs`: Number of training epochs - `--no-fine-tune`: Skip fine-tuning phase ## Model Architecture - **Base Model**: EfficientNetB0 (pre-trained on ImageNet) - **Transfer Learning**: Two-phase training 1. Train classifier head with frozen base model 2. Fine-tune top layers of base model - **Output**: Multi-class classification (diseases + healthy) - **Export Format**: TensorFlow Lite (optimized for mobile/edge) ## Inference ```python from ml.inference.tflite_predictor import TFLitePredictor from PIL import Image # Initialize predictor predictor = TFLitePredictor(crop="corn") # Predict from image image = Image.open("path/to/image.jpg") result = predictor.predict(image) print(f"Disease: {result['disease']}") print(f"Confidence: {result['confidence']:.2%}") print(f"Is Healthy: {result['is_healthy']}") ``` ## Model Versioning Models are versioned by timestamp: `v1_YYYYMMDD_HHMMSS` Each version includes: - `model.tflite`: TensorFlow Lite model - `metadata.json`: Model metadata and class names - `label_map.json`: Label to class name mapping - `metrics.json`: Evaluation metrics - `training_info.json`: Training configuration and results - `confusion_matrix.png`: Confusion matrix visualization ## Evaluation Metrics Models are evaluated on held-out test sets with: - Accuracy - Precision, Recall, F1-score (weighted and per-class) - Confusion matrix - Classification report ## Production Considerations - **Confidence Threshold**: 0.7 (configurable in `config.py`) - **Input Size**: 224x224x3 RGB images - **Preprocessing**: Normalize to [0, 1] range - **Quantization**: Float16 by default (can use int8 for smaller models) - **Model Size**: ~5-15 MB per crop (depending on quantization) ## Supported Crops - **Corn**: Common Rust, Gray Leaf Spot, Blight, Healthy - **Soybean**: Multiple diseases including mosaic virus, blight, rust, etc. - **Wheat**: Rusts, smut, blight, powdery mildew, pests, Healthy - **Rice**: Blast, bacterial blight, brown spot, Healthy