Vilaine Amont — Flood Forecast (Station-Attention)

Modèle de prévision de crues pour les 11 stations hydrométriques du bassin Vilaine Amont (Bretagne, France), avec intervalles de confiance natifs via quantile regression.

Architecture

Per-station LSTM → Cross-station Multi-Head Attention → Quantile Regression

  • Encodeur : LSTM partagé (2 couches, hidden 128) traite chaque station indépendamment (7 variables × 72 pas de temps)
  • Attention : 3 couches Multi-Head Attention (8 têtes) avec résidus et LayerNorm permettent l'échange d'information entre stations
  • Précipitations futures : encodeur MLP intégrant les prévisions de précipitations à 24h (11 stations × 24h = 264 valeurs)
  • Décodeurs : têtes séparées pour hauteur (H) et débit (Q), chacune produisant 24 horizons × 3 quantiles
  • Quantiles : q10, q50, q90 — entraînés avec pinball loss asymétrique en crue

Entrées / Sorties

Entrées

Nom Shape Description
past_input (batch, 72, 77) 72h de données passées — 11 stations × 7 variables/station (paddé à 77)
future_precip (batch, 264) Précipitations prévues — 11 stations × 24h

Les 7 variables par station sont : h (hauteur), q (débit), precip (précipitations), dh (variation H), dq (variation Q), soil_moisture_0_to_7cm, soil_moisture_7_to_28cm. Certaines stations remplacent q/dq par release (lâchers de barrage).

Toutes les valeurs sont normalisées min-max avec les paramètres de norm_params.json.

Sorties

Nom Shape Description
predictions (batch, 1296) 432 sorties × 3 quantiles (interleaved)

Les 1296 sorties sont organisées : pour chaque station, pour chaque variable (H puis Q), pour chaque horizon (1-24h), les 3 quantiles [q10, q50, q90] sont interleaved. Le mapping exact est dans station_attn_meta.json.

Les prédictions sont des deltas normalisés — il faut les dénormaliser puis les ajouter à la dernière valeur observée pour obtenir les valeurs absolues.

Stations

Code Nom Variables prédites
J700061001 Janzé (Seiche) H, Q
J701064001 Lac de la Valière H
J702401001 Louvigné-de-Bais (Quincampoix) H, Q
J702403001 Étang de Marcillé H
J702402001 Rannée (Ardenne) H, Q
J701061001 Vitré (Vilaine) H, Q
J704301001 Pocé-les-Bois (Cantache) H
J705302001 Lac de la Haute Vilaine H
J706062001 Châteaubourg (Vilaine) H, Q
J708311001 La Bouëxière (Illet) H, Q
J709063002 Cesson-Sévigné (Vilaine) H, Q

Métriques

Résultats sur le jeu de test — hiver 2025-2026 (Châteaubourg, q50) :

Horizon NSE RMSE
t+1h 0.9999 6 mm
t+6h 0.9968 36 mm
t+12h 0.9884 69 mm
t+24h 0.9699 112 mm

Calibration des quantiles : P(y < q10) ≈ 10%, P(y < q90) ≈ 85% (cibles 10%/90%).

Utilisation

import numpy as np
import onnxruntime as ort
import json

# Charger le modèle et les métadonnées
session = ort.InferenceSession("station_attn.onnx")
meta = json.load(open("station_attn_meta.json"))
norm = json.load(open("norm_params.json"))

# Préparer les entrées (normalisées min-max)
past_input = np.zeros((1, 72, 77), dtype=np.float32)   # 72h passées
future_precip = np.zeros((1, 264), dtype=np.float32)    # précip prévues 24h

# Inférence
outputs = session.run(None, {
    "past_input": past_input,
    "future_precip": future_precip,
})
predictions = outputs[0]  # shape (1, 1296)

# Extraire les prédictions pour Châteaubourg (H, q50, t+6h)
station = "J706062001"
h_start = meta["output_map"][station]["h_start"]
n_quantiles = meta["n_quantiles"]
horizon_idx = 5  # t+6h (0-indexed)
q50_idx = 1      # [q10, q50, q90]

delta_norm = predictions[0, (h_start + horizon_idx) * n_quantiles + q50_idx]

# Dénormaliser
h_min = norm[f"{station}_h"]["min"]
h_max = norm[f"{station}_h"]["max"]
delta = delta_norm * (h_max - h_min)

# Valeur absolue = dernière observation + delta
# prediction_h = last_observed_h + delta

Données d'entraînement

  • Hydrométrie : hauteurs d'eau (H) et débits (Q) horaires depuis 2000 — Hydro EauFrance
  • Météo : précipitations et humidité du sol horaires — Open-Meteo
  • Split : train 2000–2025/06, val 2025/07–2025/12, test 2026/01+

Entraînement

  • GPU : NVIDIA DGX Spark (Grace Blackwell GB10)
  • Optimiseur : Adam, lr=5e-4
  • Batch size : 256
  • Loss : Pinball loss avec pénalité asymétrique en crue (H ≥ 800mm à Châteaubourg)
  • Suréchantillonnage : crues ×2/×4/×8 selon le seuil
  • Framework : PyTorch → export ONNX

Liens

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support