Cette base de code accompagne le document Nature Communications sur la prévision saisonnière des glaces de mer dans l'Arctique avec un apprentissage profond probabiliste . Il comprend du code pour reproduire intégralement tous les résultats de l’étude à partir de zéro. Il comprend également du code pour télécharger les données générées par l'étude, publiées sur le Polar Data Centre, et reproduire tous les chiffres de l'article.
La flexibilité du code simplifie les extensions possibles de l'étude. Le pipeline de traitement des données et la classe IceNetDataLoader
personnalisée vous permettent de dicter quelles variables sont entrées dans les réseaux, quelles simulations climatiques sont utilisées pour la pré-formation et jusqu'où prévoir. L'architecture du modèle IceNet peut être adaptée dans icenet/models.py
. La variable de sortie à prévoir pourrait même être modifiée en refactorisant la classe IceNetDataLoader
.
Un démonstrateur de cette base de code (téléchargement de réseaux IceNet pré-entraînés, puis génération et analyse de prévisions) produit par @acocac peut être trouvé dans The Environmental Data Science Book.
Les instructions ci-dessous supposent que vous travaillez dans la ligne de commande d'une machine de type Unix avec un GPU. Si vous souhaitez reproduire tous les résultats de l’étude, 1 To d’espace doit couvrir en toute sécurité les besoins de stockage à partir des données téléchargées et générées.
Si vous rencontrez des problèmes ou avez des suggestions d'amélioration, veuillez soulever un problème ou m'envoyer un e-mail ([email protected]).
Pour reproduire les chiffres du papier directement à partir des résultats et des prévisions du papier, exécutez ce qui suit après avoir configuré l'environnement conda (voir l'étape 1 ci-dessous) :
./download_paper_generated_data.sh
. Télécharge les données brutes du document. À partir de là, vous pourrez commencer à explorer les résultats de l’article plus en détail.python3 icenet/download_sic_data.py
. Ceci est nécessaire pour tracer la lisière des glaces de la vérité terrain. Notez que ce téléchargement peut prendre de 1 à 12 heures.python3 icenet/gen_masks.py
python3 icenet/plot_paper_figures.py
. Les chiffres sont enregistrés dans figures/paper_figures/
. J'utilise conda pour la gestion des packages. Si vous n'avez pas encore conda, vous pouvez le télécharger ici.
Pour pouvoir télécharger les données ERA5, vous devez d'abord créer un compte CDS et remplir votre fichier .cdsapirc
. Suivez les instructions « Installer la clé API CDS » ici.
Pour télécharger les données de prévision du CEPMMT SEAS5 afin de les comparer avec IceNet, vous devez d'abord vous inscrire auprès du CEPMMT ici. Si vous résidez dans un État membre du CEPMMT, vous pouvez alors accéder au catalogue MARS du CEPMMT en contactant votre représentant informatique. Une fois inscrit, obtenez votre clé API ici et remplissez les entrées API ECMWF dans icenet/config.py
.
Pour suivre les entraînements et effectuer le réglage des hyperparamètres bayésiens avec des poids et des biais, inscrivez-vous sur https://wandb.ai/site. Obtenez votre clé API à partir d'ici et remplissez les entrées Weights et Biais dans icenet/config.py
. Assurez-vous que vous êtes connecté en exécutant wandb login
après avoir configuré l'environnement conda.
Après avoir cloné le référentiel, exécutez les commandes ci-dessous à la racine du référentiel pour configurer l'environnement conda :
conda install -n base mamba -c conda-forge
.mamba env create --file environment.yml
mamba env create --file environment.locked.yml
conda activate icenet
La convention de dénomination des variables CMIP6 est utilisée tout au long de ce projet - par exemple tas
pour la température de l'air en surface, siconca
pour la concentration de glace de mer, etc.
Attention : certains téléchargements sont lents et le temps de téléchargement net peut prendre 1 à 2 jours. Il peut être conseillé d'écrire un script bash pour exécuter automatiquement toutes ces commandes dans l'ordre et de l'exécuter pendant un week-end.
python3 icenet/gen_masks.py
. Cela permet d'obtenir des masques pour la terre, les trous polaires, l'étendue maximale mensuelle des glaces (la « région de cellule de grille active »), ainsi que les régions et le littoral de l'Arctique.
python3 icenet/download_sic_data.py
. Télécharge les données OSI-SAF SIC. Celui-ci calcule la moyenne mensuelle côté serveur SIC, télécharge les résultats et interpole de manière bilinéaire les cellules de grille manquantes (par exemple, un trou polaire). Notez que ce téléchargement peut prendre de 1 à 12 heures.
./download_era5_data_in_parallel.sh
. Télécharge les données de réanalyse ERA5. Cela exécute plusieurs commandes python3 icenet/download_era5_data.py
parallèles en arrière-plan pour acquérir chaque variable ERA5. Les données brutes ERA5 sont téléchargées au format latitude-longitude globale et regroupées dans la grille EASE sur laquelle se trouvent les données OSI-SAF SIC. Les journaux sont affichés dans logs/era5_download_logs/
.
./download_cmip6_data_in_parallel.sh
. Télécharge les données de simulation climatique CMIP6. Cela exécute plusieurs commandes python3 icenet/download_cmip6_data.py
parallèles en arrière-plan pour télécharger chaque simulation climatique. Les données brutes CMIP6 sont regroupées du format latitude-longitude globale vers la grille EASE sur laquelle se trouvent les données OSI-SAF SIC. Les journaux sont affichés dans logs/cmip6_download_logs/
./rotate_wind_data_in_parallel.sh
. Cela exécute plusieurs commandes python3 icenet/rotate_wind_data.py
parallèles en arrière-plan pour faire pivoter les données vectorielles de vent ERA5 et CMIP6 sur la grille EASE. Les journaux sont affichés dans logs/wind_rotation_logs/
.
./download_seas5_forecasts_in_parallel.sh
. Téléchargez les prévisions SIC SEAS5 du CEPMMT. Cela exécute plusieurs commandes python3 icenet/download_seas5_forecasts.py
parallèles pour acquérir les prévisions SEAS5 2002-2020 pour chaque délai via l'API MARS de l'ECMWF et recréer les prévisions pour EASE. Les prévisions sont enregistrées dans data/forecasts/seas5/
dans les dossiers latlon/
et EASE/
. Les journaux sont affichés dans logs/seas5_download_logs/
.
python3 icenet/biascorrect_seas5_forecasts.py
. Bias corrige les prévisions SEAS5 2012+ en utilisant les prévisions 2002-2011. Calcule également les champs de probabilité de glace de mer (SIP) SEAS5. Les prévisions corrigées des biais sont enregistrées sous forme de NetCDF dans data/forecasts/seas5/
avec des dimensions (target date, y, x, lead time)
.
python3 icenet/gen_data_loader_config.py
. Définit la configuration du chargeur de données. Ceci est enregistré sous forme de fichier JSON dictant les données d'entrée et de sortie d'IceNet, les répartitions train/val/test, etc. Le fichier de configuration est utilisé pour instancier la classe IceNetDataLoader
personnalisée. Deux exemples de fichiers de configuration sont fournis dans ce référentiel dans dataloader_configs/
. Chaque fichier de configuration est identifié par un ID de chargeur de données, déterminé par un horodatage et un nom fourni par l'utilisateur (par exemple 2021_06_15_1854_icenet_nature_communications
). L'ID du chargeur de données, associé à un ID d'architecture défini dans le script de formation, fournit un « ID IceNet » qui identifie de manière unique un modèle d'ensemble IceNet par sa configuration de données et son architecture. python3 icenet/preproc_icenet_data.py
. Normalise les données brutes NetCDF et les enregistre sous forme de fichiers NumPy mensuels. Les paramètres de normalisation (mean/std dev ou min/max) sont enregistrés sous forme de fichier JSON afin que les nouvelles données puissent être prétraitées sans avoir à recalculer la normalisation. Une classe IceNetDataPreProcessor personnalisée
L'ensemble de données de formation et de validation d'observation pour IceNet ne fait que 23 Go, ce qui peut tenir dans la RAM de certains systèmes et accélérer considérablement la phase de formation de réglage fin par rapport à l'utilisation du chargeur de données. Pour en bénéficier, exécutez python3 icenet/gen_numpy_obs_train_val_datasets.py
pour générer des tenseurs NumPy pour les données d'entrée/sortie train/val. Pour bénéficier davantage des améliorations de la vitesse de formation de tf.data
, générez un ensemble de données TFRecords à partir des tenseurs NumPy à l'aide de python3 icenet/gen_tfrecords_obs_train_val_datasets.py
. L'utilisation du chargeur de données, des tableaux NumPy ou des ensembles de données TFRecords pour la formation est contrôlée par les booléens dans icenet/train_icenet.py
.
icenet/train_icenet.py
pour le réglage des hyperparamètres : définissez les booléens de pré-entraînement et de mise à l'échelle de la température sur False
dans la section de saisie utilisateur.wandb sweep icenet/sweep.yaml
wandb agent
qui est imprimée.python3 icenet/train_icenet.py
. Cela prend les paramètres de l'hyperamètre et la graine aléatoire pour l'initialisation du poids du réseau comme entrées de ligne de commande. Exécutez-le plusieurs fois avec différents paramètres de --seed
pour entraîner un ensemble. Les réseaux formés sont enregistrés dans trained_networks/<dataloader_ID>/<architecture_ID>/networks/
. Si vous travaillez sur une machine partagée et êtes familier avec SLURM, vous souhaiterez peut-être envelopper cette commande dans un script SLURM. python3 icenet/predict_heldout_data.py
. Utilise xarray
pour enregistrer les prédictions sur les années de validation et de test (2012-2020) en tant que NetCDF pour IceNet et le benchmark de tendance linéaire. Les prévisions d'IceNet sont enregistrées dans data/forecasts/icenet/<dataloader_ID>/<architecture_ID>/
. Pour IceNet, l'ensemble de données de prévision complet a des dimensions (target date, y, x, lead time, ice class, seed)
, où seed
spécifie un seul membre de l'ensemble ou la prévision moyenne de l'ensemble. Une prévision SIP moyenne d'ensemble est également calculée et enregistrée dans un fichier distinct plus petit (qui ne comporte que les quatre premières dimensions).
Calculez le paramètre de mise à l'échelle de la température moyenne d'ensemble d'IceNet pour chaque délai : python3 icenet/compute_ensemble_mean_temp_scaling.py
. Les nouvelles prévisions SIP à l'échelle de la température moyenne d'ensemble sont enregistrées dans data/forecasts/icenet/<dataloader_ID>/<architecture_ID>/icenet_sip_forecasts_tempscaled.nc
. Ces prévisions représentent le modèle IceNet à moyenne d'ensemble final utilisé pour l'article.
python3 icenet/analyse_heldout_predictions.py
. Charge les données de prévision NetCDF et calcule les métriques de prévision, en stockant les résultats dans un DataFrame pandas
global avec MultiIndex
(model, ensemble member, lead time, target date)
et des colonnes pour chaque métrique (précision binaire et erreur d'étendue de la glace de mer). Utilise dask
pour éviter de charger l'intégralité des ensembles de données de prévision en mémoire, en traitant des morceaux en parallèle pour accélérer considérablement l'analyse. Les résultats sont enregistrés sous forme de fichiers CSV dans results/forecast_results/
avec un horodatage pour éviter leur écrasement. Préchargez éventuellement le dernier fichier CSV pour ajouter de nouveaux modèles ou métriques aux résultats sans avoir à réanalyser les modèles existants. Utilisez cette fonctionnalité pour ajouter les résultats de prévision d'autres modèles IceNet (identifiés par leur ID de chargeur de données et leur ID d'architecture) afin de suivre l'effet des modifications de conception sur les performances des prévisions.
python3 icenet/analyse_uncertainty.py
. Évalue l'étalonnage des prévisions SIP d'IceNet et de SEAS5. Détermine également la région de la lisière des glaces d'IceNet et évalue sa capacité à délimiter la lisière des glaces. Les résultats sont enregistrés dans results/uncertainty_results/
.
python3 icenet/permute_and_predict.py
. Les résultats sont stockés dans results/permute_and_predict_results/
.python3 icenet/plot_paper_figures.py
. Les chiffres sont enregistrés dans figures/paper_figures/
. Notez que vous aurez besoin du fichier CSV d’erreur Sea Ice Outlook pour tracer Supp. Figure 5 : wget -O data/sea_ice_outlook_errors.csv 'https://ramadda.data.bas.ac.uk/repository/entry/get/sea_ice_outlook_errors.csv?entryid=synth%3A71820e7d-c628-4e32-969f-464b7efb187c%3AL3Jlc3VsdHMvb3V0bG9va19lcnJvcnMvc2VhX2ljZV9vdXRsb29rX2Vycm9ycy5jc3Y%3D'
icenet/utils.py
définit les fonctions utilitaires IceNet telles que le préprocesseur de données, le chargeur de données, le traitement ERA5 et CMIP6, la décroissance du taux d'apprentissage et la fonctionnalité vidéo.icenet/models.py
définit les architectures réseau.icenet/config.py
définit les variables globales.icenet/losses.py
définit les fonctions de perte.icenet/callbacks.py
définit les rappels de formation.icenet/metrics.py
définit les métriques de formation.tree
.
├── data
│ ├── obs
│ ├── cmip6
│ │ ├── EC-Earth3
│ │ │ ├── r10i1p1f1
│ │ │ ├── r12i1p1f1
│ │ │ ├── r14i1p1f1
│ │ │ ├── r2i1p1f1
│ │ │ └── r7i1p1f1
│ │ └── MRI-ESM2-0
│ │ ├── r1i1p1f1
│ │ ├── r2i1p1f1
│ │ ├── r3i1p1f1
│ │ ├── r4i1p1f1
│ │ └── r5i1p1f1
│ ├── forecasts
│ │ ├── icenet
│ │ │ ├── 2021_06_15_1854_icenet_nature_communications
│ │ │ │ └── unet_tempscale
│ │ │ └── 2021_06_30_0954_icenet_pretrain_ablation
│ │ │ └── unet_tempscale
│ │ ├── linear_trend
│ │ └── seas5
│ │ ├── EASE
│ │ └── latlon
│ ├── masks
│ └── network_datasets
│ └── dataset1
│ ├── meta
│ ├── obs
│ ├── transfer
│ └── norm_params.json
├── dataloader_configs
│ ├── 2021_06_15_1854_icenet_nature_communications.json
│ └── 2021_06_30_0954_icenet_pretrain_ablation.json
├── figures
├── icenet
├── logs
│ ├── cmip6_download_logs
│ ├── era5_download_logs
│ ├── seas5_download_logs
│ └── wind_rotation_logs
├── results
│ ├── forecast_results
│ │ └── 2021_07_01_183913_forecast_results.csv
│ ├── permute_and_predict_results
│ │ └── permute_and_predict_results.csv
│ └── uncertainty_results
│ ├── ice_edge_region_results.csv
│ ├── sip_bounding_results.csv
│ └── uncertainty_results.csv
└── trained_networks
└── 2021_06_15_1854_icenet_nature_communications
├── obs_train_val_data
│ ├── numpy
│ └── tfrecords
│ ├── train
│ └── val
└── unet_tempscale
└── networks
├── network_tempscaled_36.h5
├── network_tempscaled_37.h5
:
Merci à James Byrne (BAS) et Tony Phillips (BAS) pour leurs contributions directes à cette base de code.