Downloads · 30 days
0
rorinfo/chennai-lst-unet
chennai-lst-unet is a machine learning model from rorinfo. Use it for the machine learning task on the model card, and read the license before you ship it in a product. The card lists the license as cc-by-4.0.
A small FiLM-conditioned U-Net that predicts the spatial pattern of land surface temperature over the Greater Chennai Corporation from urban form and that morning's weather, at 30 m.
Downloads · 30 days
0
Access
Public
Updated Sep 18, 2026
Repo size
35.1 MB
Likes
0
Public
Click a slice to open those files.
.npz27 MB · 77%
From the Hugging Face model README
A small FiLM-conditioned U-Net that predicts the spatial pattern of land surface temperature over the Greater Chennai Corporation from urban form and that morning's weather, at 30 m.
2.02 M parameters. Test MAE 1.309 °C, r 0.932, skill +0.248 over pixel climatology, on 27.9 M held-out pixels.
The model predicts a within-scene anomaly — how much hotter or cooler each pixel is than the average of that same scene — not an absolute temperature. That choice is the point of the model: predicting absolute LST is easy and nearly meaningless, because most of the variance is "how hot was that day", which is readable straight off the weather vector. Removing the scene mean forces the network to explain spatial structure, which is the urban heat island signal.
Given a city's fixed form and a day's weather, produce the heat pattern: which streets, plots and wards run hotter than their surroundings. It is used to rank neighbourhoods, compare land-cover types at matched distance from the coast, and generate hypotheses about interventions by perturbing the inputs.
It is not a nowcast and not a thermometer. See Limitations.
| Spatial input | 21 channels, 128×128 px at 30 m |
| — 17 static | GHSL built height / surface / volume; elevation, slope, aspect (sin, cos); distance to coast; 9 ESA WorldCover one-hot classes |
| — 4 dynamic | NDVI, NDBI, NDWI, FVC from the same Landsat acquisition |
| Meteo vector | 11 values: t2m, RH, u10, v10, shortwave radiation, VPD, wind speed (all percentile-scaled), plus sin/cos day-of-year, a year term, and an onshore-flow component |
| Output | 1 channel, within-scene LST anomaly in °C |
The onshore component is the sea-breeze signal as a single number:
onshore = −0.966·u10 + 0.259·v10, derived from a shore-normal bearing of 285° for
Chennai's N15°E coastline. Positive means marine air is being pushed inland.
A four-level U-Net. The meteo vector goes through an MLP (11 → 128 → 128 → 512) producing
per-channel scale and shift parameters applied at the bottleneck as
x = x · (1 + γ) + β — FiLM conditioning. Because the conditioning acts per channel
rather than per position, parameter count is independent of patch size.
This matters. The reference implementation (Delgado-Enales et al., Urban Climate 2025, for Bilbao) flattens the bottleneck and concatenates the meteo vector into a dense layer. That single layer is 79% of its parameters and grows with patch area: 4.2 M at 32 px, 67.2 M at 64 px, roughly 1.07 billion at 128 px.
Spatially blocked splits, stratified by distance to coast — train, validation and test occupy disjoint 8 km blocks, so no test pixel neighbours a training pixel.
Best model (FiLM, 128 px patches, 66 scenes):
| metric | value |
|---|---|
| MAE | 1.3088 °C |
| RMSE | 1.7744 |
| Pearson r | 0.932 |
| pixel climatology MAE | 1.7409 |
| ridge MAE | 2.1826 |
| scene-mean MAE | 3.6642 |
| skill vs climatology | +0.248 |
| test set | 2,112 patch-scenes / 27,938,332 pixels |
Controlled architecture comparison — both runs share a byte-identical split
(3343/795/735 patches; both report pixel_climatology MAE 1.6000292301177979 and
ridge 2.0171847343444824 to every printed digit), so raw MAEs are directly comparable:
| this model (FiLM) | reference architecture | |
|---|---|---|
| parameters | 2.02 M | 5.33 M |
| test MAE | 1.3456 | 1.4388 |
| skill vs climatology | +0.159 | +0.101 |
| best epoch | 16 | 3 |
| train/val gap at best epoch | 0.047 | 0.130 |
FiLM is 6.5% more accurate with 2.6× fewer parameters. Both architectures reach essentially the same training loss (~1.05); the difference is entirely generalisation. The reference architecture's validation loss stops improving at epoch 3 while its training loss keeps falling, which is what the 79%-in-one-dense-layer structure predicts.
Reproducibility. Retrained from scratch, the 33-scene configuration reproduced bit-identically: best validation loss 1.3186 both times, test MAE 1.3767924308776855 both times, matching epoch by epoch from epoch 1.
66 Landsat 8/9 Collection 2 Level-2 scenes, 2016-03-06 to 2026-06-06, March–June only (Chennai's pre-monsoon peak), cloud cover < 40%, over 80.048–80.350 E, 12.830–13.240 N. Surface temperature is the USGS single-channel retrieval (TIRS band 10 + ASTER GED emissivity + NCEP profiles) — not a split-window product; say so in any methods section.
Cloud, cloud shadow, cirrus, dilated cloud, snow and fill are masked from QA_PIXEL
bits 0–5. Masking only the cloud bit leaves thin cirrus in the scene, which depresses
retrieved surface temperature by several degrees and would be absorbed into the anomaly
field as a fabricated cool spot.
Training used masked L1 loss, AdamW, ReduceLROnPlateau, early stopping with patience 12, batch size 16, on one RTX 5060 Laptop GPU.
Read these before using any number from this model.
import torch, numpy as np
from model import build_model
ck = torch.load("best.pt", map_location="cpu", weights_only=False)
model = build_model(ck["arch"], ck["in_channels"], ck["meteo_dim"],
{"base_filters": 32}, ck["patch_px"])
model.load_state_dict(ck["model"]); model.eval()
x = torch.randn(1, 21, 128, 128) # 17 static + 4 dynamic, pre-normalised
met = torch.randn(1, 11) # see meteo_scaling.json for the scaling
with torch.no_grad():
anomaly_c = model(x, met) # (1, 1, 128, 128), degrees C
inputs.npz in this repo carries the pre-normalised static and mean dynamic channels for
the whole Chennai frame, and meteo_scaling.json the 2nd/98th percentiles used to scale
raw weather values. The Space in this repo is a worked example.
Required by the source licences. Reproduce these wherever the model or its outputs are used.
OpenStreetMap is not used in this model. It is used only for the place, street and ward geometry in the companion web map; those derived tables are ODbL and are published separately, not here.
Method adapted from Delgado-Enales, I. et al., Urban Climate (2025);
reference implementation at github.com/InigoD/UHI-UNET.
@software{chennai_lst_unet,
title = {Chennai LST U-Net: FiLM-conditioned prediction of urban surface
temperature anomaly},
year = {2026},
note = {2.02M parameters; 66 Landsat scenes, 2016--2026;
test MAE 1.309 C, skill +0.248 over pixel climatology}
}