Inspiration
I picked the illegal deforestation problem (GP-04) at Neural Storm 2026 because the numbers are hard to ignore. Global Forest Watch reports that the tropics lost primary forest at roughly 10 football fields per minute in 2021 to 2023, and 18 per minute in 2024. Satellites already photograph all of this. The real problem is that nobody can go through that much imagery by hand, so clearing often gets noticed months late.
I also don't like AI that only gives an answer. If a forest team is going to travel for hours because a model said "forest was cleared here", they should be able to see what the model actually looked at. So explainability was a requirement from day one, not an extra.
What it does
ForestWatch AI is a web app that reads satellite images and answers three questions: what is on the ground, did forest disappear between two dates, and where should someone go first.
- Classify a patch: upload a small satellite patch and get one of 10 land-cover classes, a confidence score, and a Grad-CAM heatmap that shows which parts of the image drove the decision. It takes about 14 ms on a Colab T4 GPU.
- Scan a large image: the app cuts a bigger scene into tiles, classifies every tile, and draws a colour-coded map (forest, farmland, water, built-up) with forest cover in % and hectares.
- Change detection: give it a before image and an after image of the same place. Forest loss shows up in red, regrowth in green, and the app checks what the lost tiles turned into: crops, industry or housing.
- Field response plan: for the lost area it estimates the CO2 released, the saplings needed to replant, and a ranked list of grid sectors for ground teams. You can download the alert map, a JSON report and a short text brief.
- Model performance: training curves, a confusion matrix and per-class scores, so anyone can check my accuracy claim.
How I built it
The model is a ResNet18 pretrained on ImageNet and fine-tuned on EuroSAT. EuroSAT has 27,000 Sentinel-2 RGB patches (64x64 pixels, 10 classes) from 34 European countries. I started with a small CNN trained from scratch, then switched to transfer learning with ResNet18.
I trained for 8 epochs with AdamW, a cosine learning-rate schedule and random flips on the training images. The split is 21,600 train and 5,400 validation with a fixed seed. Result: 98.19% validation accuracy and a macro F1 of 0.982.
For explainability I used Grad-CAM with PyTorch hooks. I hook into layer3 and not layer4, because for a 64x64 input layer4 only gives a 2x2 grid, which is too coarse to show anything useful. Layer3 gives 4x4.
For big images, the app cuts the scene into tiles (the size is adjustable), resizes each tile to 64x64 and runs them through the GPU in batches. The 10 classes are merged into 4 groups so the map is easy to read. For change detection, the before and after images are tiled on the exact same grid. A tile counts as lost if it was forest before and is not forest now.
Area per tile is (tile pixels x metres per pixel)^2 / 10,000, so at Sentinel-2's 10 m per pixel a 64 px tile is about 41 hectares. The carbon estimate is lost hectares x 140 tC/ha x 44/12, where 140 tC/ha is a default assumption the user can change.
The app is built with Streamlit and Plotly. I ran it on Colab and shared it through a Cloudflare tunnel.
Challenges I ran into
My accuracy number was not trustworthy at first. I used random_split without a seed, so the validation set changed every time I ran the code. That means a later evaluation could include images the model had already trained on. I fixed it with a fixed seed and two separate data pipelines, so only the training images are augmented.
A classifier is not a change detector. The model only says what one patch is. It took me a while to see that deforestation is a comparison problem. The fix was tiling both images on the same grid and comparing the results tile by tile.
Getting the app online from Colab. The localhost links Streamlit prints don't work from Colab, and my first tunnel attempt gave a 502 Bad Gateway for minutes. I ended up starting Streamlit with explicit flags, checking that it was healthy, and only then opening a Cloudflare tunnel.
What I learned
- Transfer learning gets you very far with a small compute budget.
- Grad-CAM isn't magic. It's gradients flowing back to one layer, and the layer you pick matters a lot.
- An accuracy score only means something if the split is clean. EuroSAT is also a fairly easy dataset (published results are around 98.5%), so my 98.19% mostly shows the training was done properly. It doesn't prove the model works anywhere in the world.
- Turning a model into something people can use took about as much time as training it.
Limits (being honest)
- The before/after demo scene is synthetic. I built it from real EuroSAT validation patches to show the pipeline, so the forest loss it shows is not a real event.
- The model was trained on European images and RGB only. For tropical forests it needs retraining on local data.
- The CO2, sapling and carbon-credit numbers are estimates that depend on adjustable assumptions.
- Change detection works best when both images come from the same season. Harvested fields can look like forest loss.
What's next
- Retrain on regional, multi-season imagery and test on areas the model has never seen
- Use the 13-band multispectral data and NDVI for better forest detection
- Pull Sentinel-2 images for a chosen area automatically
- Time-series monitoring with automatic alerts
- Export results as GeoJSON for GIS tools