|
| 1 | +# ClimateVision — Training Handoff (run this now) |
| 2 | + |
| 3 | +**Goal:** produce real trained models for ClimateVision so the live site |
| 4 | +(climatevision.green) stops serving demo/untrained output. Do **flooding first** |
| 5 | +(best dataset fit), then deforestation, then ice. |
| 6 | + |
| 7 | +**You need:** Google Colab (Pro recommended — GPU + longer runtime) and a Google |
| 8 | +account with Earth Engine access. You do **not** need any private key file — use |
| 9 | +interactive auth (step 2). Est. time: ~30 min setup + 1–3 h GPU training per model. |
| 10 | + |
| 11 | +When done, you hand back **one file per model** (`best_model.pth` and/or |
| 12 | +`model.onnx`) — see step 7. |
| 13 | + |
| 14 | +--- |
| 15 | + |
| 16 | +## 1. Set up the environment (Colab cell) |
| 17 | + |
| 18 | +```python |
| 19 | +!git clone https://github.com/Climate-Vision/ClimateVision.git |
| 20 | +%cd ClimateVision |
| 21 | +!pip install -q -r requirements.txt |
| 22 | +!pip install -q -e . |
| 23 | +import torch; print("CUDA available:", torch.cuda.is_available()) # must be True |
| 24 | + |
| 25 | +from google.colab import drive # so checkpoints survive a runtime reset |
| 26 | +drive.mount('/content/drive') |
| 27 | +!mkdir -p /content/drive/MyDrive/climatevision/models |
| 28 | +``` |
| 29 | + |
| 30 | +## 2. Earth Engine auth — interactive, NO key file |
| 31 | + |
| 32 | +```python |
| 33 | +import ee |
| 34 | +ee.Authenticate() # opens an OAuth link, paste the token |
| 35 | +ee.Initialize(project='YOUR_GEE_PROJECT_ID') |
| 36 | +``` |
| 37 | + |
| 38 | +> GEE is only needed if you pull fresh tiles for spot-checking. Training itself |
| 39 | +> uses the downloaded dataset, so you can skip this if you just want to train. |
| 40 | +
|
| 41 | +## 3. Download a dataset |
| 42 | + |
| 43 | +```bash |
| 44 | +# flooding (Sen1Floods11) needs gsutil: |
| 45 | +!pip install -q gsutil |
| 46 | +!python scripts/download_datasets.py --dataset flooding --out data/datasets |
| 47 | +``` |
| 48 | + |
| 49 | +| Type | Dataset | Tool | License | |
| 50 | +|------|---------|------|---------| |
| 51 | +| flooding | Sen1Floods11 | `gsutil` | CC-BY 4.0 | |
| 52 | +| deforestation | MultiEarth Amazon | `huggingface_hub` | research use | |
| 53 | +| ice_melting | AI4Arctic v2 | `eotdl` | CC-BY 4.0 | |
| 54 | + |
| 55 | +## 4. Convert to the training layout ⚠️ the one manual step |
| 56 | + |
| 57 | +The trainer reads stem-matched GeoTIFF pairs in this structure: |
| 58 | + |
| 59 | +``` |
| 60 | +data/datasets/<type>/ |
| 61 | + train/ images/ *.tif masks/ *.tif |
| 62 | + val/ images/ *.tif masks/ *.tif |
| 63 | + test/ images/ *.tif masks/ *.tif |
| 64 | +``` |
| 65 | + |
| 66 | +Each dataset ships in its own format, so write a short conversion that: |
| 67 | +1. reads each scene + its label, |
| 68 | +2. writes the image bands ClimateVision expects for that type |
| 69 | + (flooding = B03,B08,B11 → 3 bands; deforestation = B04,B03,B02,B08 → 4 bands), |
| 70 | +3. writes the mask as a single-band `uint8` with class indices matching |
| 71 | + `config.yaml` (flooding: 0=dry_land, 1=permanent_water, 2=flooded), |
| 72 | +4. uses the **same filename stem** for image and mask, |
| 73 | +5. splits ~80/10/10 into train/val/test. |
| 74 | + |
| 75 | +Notes per dataset: |
| 76 | +- **Sen1Floods11**: GeoTIFF chips already; map its water/flood labels to the |
| 77 | + 3-class scheme above. SAR bands — run them through |
| 78 | + `src/climatevision/data/sar_preprocessing.py` (speckle filter + dB scaling). |
| 79 | +- **MultiEarth**: Sentinel-2 chips with binary deforestation masks (0/1) — fits |
| 80 | + the 4-band / 2-class deforestation config directly. |
| 81 | +- **AI4Arctic**: netCDF — extract the SAR layer + ice chart, tile to 256×256. |
| 82 | + |
| 83 | +## 5. Train |
| 84 | + |
| 85 | +```bash |
| 86 | +!python scripts/train_real.py \ |
| 87 | + --analysis-type flooding \ |
| 88 | + --data-dir data/datasets/flooding \ |
| 89 | + --epochs 50 --batch-size 8 \ |
| 90 | + --out /content/drive/MyDrive/climatevision/models |
| 91 | +``` |
| 92 | + |
| 93 | +`train_real.py` reads channels/classes from `config.yaml` automatically, uses the |
| 94 | +existing `Trainer` (AdamW, warmup→cosine LR, EMA, mixed precision, early stopping) |
| 95 | +and saves `best_model.pth` (with `model_state_dict` + `val_iou`) to the run dir. |
| 96 | + |
| 97 | +## 6. Evaluate and gate |
| 98 | + |
| 99 | +```bash |
| 100 | +!python scripts/evaluate.py --checkpoint <run>/best_model.pth --data-dir data/datasets/flooding |
| 101 | +!python scripts/generate_model_card.py --checkpoint <run>/best_model.pth |
| 102 | +!python scripts/governance_ci_gate.py # must pass before promoting a model |
| 103 | +``` |
| 104 | + |
| 105 | +Only promote a model that clears the governance gate (metrics + fairness). That |
| 106 | +is the line between "preview" and something an agency can act on. |
| 107 | + |
| 108 | +## 7. Export ONNX + hand back |
| 109 | + |
| 110 | +```bash |
| 111 | +!python scripts/export_model.py --checkpoint <run>/best_model.pth |
| 112 | +# produces <run>/model.onnx (+ model_quantized.onnx, export_info.json) |
| 113 | +``` |
| 114 | + |
| 115 | +Hand back to the project owner, per analysis type, either: |
| 116 | +- `best_model.pth` (PyTorch), or |
| 117 | +- `model.onnx` (the API serves this automatically via onnxruntime). |
| 118 | + |
| 119 | +Deployment (owner does this): drop the file into `models/<type>_<date>/` and |
| 120 | +rebuild the Docker image (the Dockerfile already `COPY models/`), **or** place it |
| 121 | +on the Fly volume at `/app/outputs` and point `config.yaml` `weights:` at it. |
| 122 | +The serving code (`inference/pipeline.py`) finds `.pth` first, else `model.onnx`. |
| 123 | + |
| 124 | +--- |
| 125 | + |
| 126 | +## Quick reference — how serving picks up your model |
| 127 | + |
| 128 | +`inference/pipeline.py` resolution order per type: |
| 129 | +1. `config.yaml` `weights:` path (PyTorch `.pth`) |
| 130 | +2. `models/best_model.pth` |
| 131 | +3. newest `models/*/best_model.pth` |
| 132 | +4. `config.yaml` `onnx_weights:` or newest `models/<type>_*/model.onnx` (ONNX) |
| 133 | +5. otherwise → untrained demo weights (what's live now) |
| 134 | + |
| 135 | +So just getting a trained file into `models/<type>_*/` is enough to go live with |
| 136 | +a real model. |
0 commit comments