Esta base de código acompanha o artigo da Nature Communications Previsão sazonal do gelo marinho do Ártico com aprendizado profundo probabilístico . Inclui código para reproduzir totalmente todos os resultados do estudo do zero. Também inclui código para baixar os dados gerados pelo estudo, publicados no Polar Data Center, e reproduzir todos os números do artigo.
A flexibilidade do código simplifica possíveis extensões do estudo. O pipeline de processamento de dados e a classe IceNetDataLoader
personalizada permitem ditar quais variáveis serão inseridas nas redes, quais simulações climáticas serão usadas para pré-treinamento e com que antecedência a previsão. A arquitetura do modelo IceNet pode ser adaptada em icenet/models.py
. A variável de saída para previsão pode até ser alterada refatorando a classe IceNetDataLoader
.
Um demonstrador desta base de código (baixando redes IceNet pré-treinadas e, em seguida, gerando e analisando previsões) produzido por @acocac pode ser encontrado no The Environmental Data Science Book.
As diretrizes abaixo pressupõem que você esteja trabalhando na linha de comando de uma máquina do tipo Unix com GPU. Se pretender reproduzir todos os resultados do estudo, 1 TB de espaço deverá cobrir com segurança os requisitos de armazenamento dos dados baixados e gerados.
Se você tiver problemas ou tiver sugestões de melhorias, levante um problema ou envie-me um e-mail ([email protected]).
Para reproduzir os números do papel diretamente dos resultados e previsões do artigo, execute o seguinte após configurar o ambiente conda (consulte a Etapa 1 abaixo):
./download_paper_generated_data.sh
. Baixa dados brutos do papel. A partir daqui, você poderá começar a explorar os resultados do artigo com mais detalhes.python3 icenet/download_sic_data.py
. Isso é necessário para traçar a borda do gelo real. Observe que este download pode levar de 1 a 12 horas para ser concluído.python3 icenet/gen_masks.py
python3 icenet/plot_paper_figures.py
. As figuras são salvas em figures/paper_figures/
. Eu uso conda para gerenciamento de pacotes. Se você ainda não possui o conda, pode baixá-lo aqui.
Para poder baixar dados ERA5, você deve primeiro configurar uma conta CDS e preencher seu arquivo .cdsapirc
. Siga as instruções de 'Instalar a chave API CDS' aqui.
Para baixar os dados de previsão do ECMWF SEAS5 para comparação com o IceNet, você deve primeiro registrar-se no ECMWF aqui. Se for de um Estado Membro do ECMWF, poderá obter acesso ao Catálogo MARS do ECMWF contactando o seu Representante de Informática. Uma vez registrado, obtenha sua chave API aqui e preencha as entradas da API ECMWF em icenet/config.py
.
Para rastrear execuções de treinamento e realizar ajuste de hiperparâmetros bayesianos com pesos e preconceitos, inscreva-se em https://wandb.ai/site. Obtenha sua chave de API aqui e preencha as entradas Pesos e Vieses em icenet/config.py
. Certifique-se de estar conectado executando wandb login
após configurar o ambiente conda.
Após clonar o repositório, execute os comandos abaixo na raiz do repositório para configurar o ambiente 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
A convenção de nomenclatura de variáveis CMIP6 é usada em todo este projeto - por exemplo, tas
para temperatura do ar na superfície, siconca
para concentração de gelo marinho, etc.
Aviso: alguns downloads são lentos e o tempo de download líquido pode levar de 1 a 2 dias. Pode ser aconselhável escrever um script bash para executar automaticamente todos esses comandos em sequência e executá-lo durante um fim de semana.
python3 icenet/gen_masks.py
. Isto obtém máscaras para a terra, os buracos polares, a extensão máxima mensal do gelo (a 'região da célula da grade ativa') e as regiões e litoral do Ártico.
python3 icenet/download_sic_data.py
. Baixa dados SIC OSI-SAF. Isso calcula a média mensal do SIC no lado do servidor, baixa os resultados e interpola bilinearmente as células ausentes da grade (por exemplo, buraco polar). Observe que este download pode levar de 1 a 12 horas para ser concluído.
./download_era5_data_in_parallel.sh
. Baixa dados de reanálise ERA5. Isso executa vários comandos python3 icenet/download_era5_data.py
paralelos em segundo plano para adquirir cada variável ERA5. Os dados brutos ERA5 são baixados no formato global de latitude-longitude e reestruturados na grade EASE onde se encontram os dados SIC do OSI-SAF. Os logs são gerados para logs/era5_download_logs/
.
./download_cmip6_data_in_parallel.sh
. Baixa dados de simulação climática CMIP6. Isso executa vários comandos python3 icenet/download_cmip6_data.py
paralelos em segundo plano para baixar cada simulação climática. Os dados CMIP6 brutos são reestruturados do formato global de latitude-longitude para a grade EASE onde se encontram os dados SIC do OSI-SAF. Os logs são enviados para logs/cmip6_download_logs/
./rotate_wind_data_in_parallel.sh
. Isso executa vários comandos python3 icenet/rotate_wind_data.py
paralelos em segundo plano para girar os dados do vetor de vento ERA5 e CMIP6 na grade EASE. Os logs são enviados para logs/wind_rotation_logs/
.
./download_seas5_forecasts_in_parallel.sh
. Baixa as previsões do ECMWF SEAS5 SIC. Isso executa vários comandos python3 icenet/download_seas5_forecasts.py
paralelos para adquirir previsões SEAS5 2002-2020 para cada prazo de entrega por meio da API ECMWF MARS e reestruturar as previsões para EASE. As previsões são salvas em data/forecasts/seas5/
nas pastas latlon/
e EASE/
. Os logs são enviados para logs/seas5_download_logs/
.
python3 icenet/biascorrect_seas5_forecasts.py
. Bias corrige as previsões SEAS5 2012+ usando previsões de 2002-2011. Também calcula campos de probabilidade de gelo marinho (SIP) SEAS5. As previsões com correção de viés são salvas como NetCDFs em data/forecasts/seas5/
com dimensões (target date, y, x, lead time)
.
python3 icenet/gen_data_loader_config.py
. Define a configuração do carregador de dados. Isso é salvo como um arquivo JSON ditando os dados de entrada e saída do IceNet, divisões de treinamento/val/teste, etc. O arquivo de configuração é usado para instanciar a classe IceNetDataLoader
personalizada. Dois exemplos de arquivos de configuração são fornecidos neste repositório em dataloader_configs/
. Cada arquivo de configuração é identificado por um ID do dataloader, determinado por um carimbo de data/hora e um nome fornecido pelo usuário (por exemplo, 2021_06_15_1854_icenet_nature_communications
). O ID do carregador de dados, juntamente com um ID de arquitetura definido no script de treinamento, fornece um 'ID IceNet' que identifica exclusivamente um modelo de conjunto IceNet por sua configuração e arquitetura de dados. python3 icenet/preproc_icenet_data.py
. Normaliza os dados brutos do NetCDF e os salva como arquivos NumPy mensais. Os parâmetros de normalização (média/padrão dev ou min/máx) são salvos como um arquivo JSON para que novos dados possam ser pré-processados sem a necessidade de recalcular a normalização. Uma classe IceNetDataPreProcessor personalizada
O conjunto de dados observacionais de treinamento e validação para IceNet tem apenas 23 GB, o que pode caber na RAM de alguns sistemas e acelerar significativamente a fase de treinamento de ajuste fino em comparação com o uso do carregador de dados. Para se beneficiar disso, execute python3 icenet/gen_numpy_obs_train_val_datasets.py
para gerar tensores NumPy para os dados de entrada/saída train/val. Para se beneficiar ainda mais das melhorias na velocidade de treinamento de tf.data
, gere um conjunto de dados TFRecords a partir dos tensores NumPy usando python3 icenet/gen_tfrecords_obs_train_val_datasets.py
. O uso do carregador de dados, matrizes NumPy ou conjuntos de dados TFRecords para treinamento é controlado por bools em icenet/train_icenet.py
.
icenet/train_icenet.py
para ajuste de hiperparâmetros: Defina bools de pré-treinamento e escala de temperatura como False
na seção de entrada do usuário.wandb sweep icenet/sweep.yaml
wandb agent
impresso.python3 icenet/train_icenet.py
. Isso usa as configurações do hiperâmetro e a semente aleatória para inicialização do peso da rede como entradas de linha de comando. Execute isso várias vezes com diferentes configurações de --seed
para treinar um conjunto. As redes treinadas são salvas em trained_networks/<dataloader_ID>/<architecture_ID>/networks/
. Se estiver trabalhando em uma máquina compartilhada e familiarizado com SLURM, você pode querer agrupar este comando em um script SLURM. python3 icenet/predict_heldout_data.py
. Usa xarray
para salvar previsões ao longo dos anos de validação e teste como (2012-2020) como NetCDFs para IceNet e o benchmark de tendência linear. As previsões do IceNet são salvas em data/forecasts/icenet/<dataloader_ID>/<architecture_ID>/
. Para IceNet, o conjunto de dados de previsão completo tem dimensões (target date, y, x, lead time, ice class, seed)
, onde seed
especifica um único membro do conjunto ou a previsão média do conjunto. Uma previsão SIP média do conjunto também é calculada e salva como um arquivo menor e separado (que possui apenas as primeiras quatro dimensões).
Calcule o parâmetro de escala de temperatura média do conjunto do IceNet para cada lead time: python3 icenet/compute_ensemble_mean_temp_scaling.py
. As novas previsões SIP com escala de temperatura média do conjunto são salvas em data/forecasts/icenet/<dataloader_ID>/<architecture_ID>/icenet_sip_forecasts_tempscaled.nc
. Essas previsões representam o modelo IceNet de média de conjunto final usado para o artigo.
python3 icenet/analyse_heldout_predictions.py
. Carrega os dados de previsão do NetCDF e calcula as métricas de previsão, armazenando os resultados em um DataFrame global pandas
com MultiIndex
(model, ensemble member, lead time, target date)
e colunas para cada métrica (precisão binária e erro de extensão do gelo marinho). Usa dask
para evitar carregar todos os conjuntos de dados de previsão na memória, processando pedaços em paralelo para acelerar significativamente a análise. Os resultados são salvos como arquivos CSV em results/forecast_results/
com um carimbo de data/hora para evitar substituição. Opcionalmente, pré-carregue o arquivo CSV mais recente para acrescentar novos modelos ou métricas aos resultados sem a necessidade de reanalisar os modelos existentes. Use esse recurso para anexar resultados de previsão de outros modelos IceNet (identificados por seu ID do carregador de dados e ID da arquitetura) para rastrear o efeito das alterações de design no desempenho da previsão.
python3 icenet/analyse_uncertainty.py
. Avalia a calibração das previsões SIP do IceNet e SEAS5. Também determina a região da borda do gelo do IceNet e avalia sua capacidade de delimitação da borda do gelo. Os resultados são salvos em results/uncertainty_results/
.
python3 icenet/permute_and_predict.py
. Os resultados são armazenados em results/permute_and_predict_results/
.python3 icenet/plot_paper_figures.py
. As figuras são salvas em figures/paper_figures/
. Observe que você precisará do arquivo CSV de erro do Sea Ice Outlook para plotar o Supp. Figura 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
define funções utilitárias IceNet como pré-processador de dados, carregador de dados, processamento ERA5 e CMIP6, redução da taxa de aprendizagem e funcionalidade de vídeo.icenet/models.py
define arquiteturas de rede.icenet/config.py
define globais.icenet/losses.py
define funções de perda.icenet/callbacks.py
define retornos de chamada de treinamento.icenet/metrics.py
define métricas de treinamento.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
:
Agradecimentos a James Byrne (BAS) e Tony Phillips (BAS) pelas contribuições diretas a esta base de código.