Nedbør Nowcasting med maskinlæring

ML
DL
CNN
Værprediksjon
UNet
Nedbør Nowcasting med maskinlæring cover image

I dag anslår meteorologer at 90 % av værmeldingene er riktige i løpet av 5 dager. Spådommene som gjøres er vanligvis basert på to separate metoder:

  1. Fysikkbaserte tilnærminger: Disse tilnærmingene bruker modeller som integrerer målbare størrelser som trykk, skyenes bevegelser, himmelforhold... Slike modeller er gode til å forutsi været for de kommende dagene eller ukene.

  2. Fysikkfrie (databaserte) tilnærminger: Disse tilnærmingene bruker historiske data for å lage modeller som kan lage spådommer. Slike modeller viser gode resultater i å forutsi været i opptil 6 timer eller det som kalles vær-nåkasting.

I denne artikkelen vil vi diskutere den andre kategorien tilnærminger. Vi vil diskutere de forskjellige formatene for værdata, hvordan maskinlæring kan utnyttes for å gjøre værmeldinger, og hvordan de utviklede arkitekturene kan være fordelaktige for å løse lignende problemer.

Data for klimaprediksjon

Siden de fysikkfrie tilnærmingene bruker historiske data, la oss starte med å se nærmere på tilgjengelige data.

Vi vil bruke to hovedkilder til data:

  1. Bildedata: Disse dataene har form av radar- eller satellittbilder av et spesifisert geografisk område. Den brukes til å forutsi nedbør, vindbevegelse eller fuktighet.

Satellite Image

  1. Tabelldata : Disse dataene har form av registreringer av målbare mengder som temperatur, fuktighet eller vindhastighet.

Tabular Data

Mens begge datakildene er viktige for å bygge kraftige modeller, vil vi fokusere på førstnevnte (bildedata samlet inn fra radarer eller satellitter) for enkelhets skyld. De mest brukte modellene med bildedata er Convolutional Neural Networks (CNNs ).

Etter dette arbeidet, skal vi bruke en U-Net-arkitektur for å bygge vår egen nowcasting-modell.

Arkitektur

Å ta utgangspunkt i en eksisterende arkitektur er nyttig av mange grunner, blant annet:

Arkitekturer fungerer som retningslinjer for å lage nye modeller. Folk som lager nye arkitekturer bruker en prøving og feiling tilnærming for å komme til de endelige resultatene. Ved å gjenbruke deres endelige resultater kan vi spare mye tid.

Forhåndsutdannede modeller er vanligvis tilgjengelige for umiddelbar bruk. Når forskere publiserer sine nye arkitekturer, publiserer de vanligvis de trente parameterne også, slik at brukerne slipper å gå gjennom bryet med å trene/optimalisere fra bunnen av. Dette er spesielt nyttig for veldig store, ressurstørste modeller.

Eksempler på kjente visjonsarkitekturer inkluderer:

  • LeNet (60k parametere)

LeNet

  • AlexNet (60m parametere)

AlexNet

  • VGG-16 (138 m parametere)

VGG-16

U-Net

U-Net er en arkitektur basert på et fullstendig konvolusjonelt nettverk, noe som betyr at det ikke har noen fullstendig tilkoblede lag. Den ble først introdusert for en medisinsk bildesegmenteringsoppgave. Disse resultatene inspirerte forskere til å utvide det til andre oppgaver innen datasyn.

I 2019 brukte Google en U-Net-basert arkitektur for å lage en nedbørsprognosemodell.

Navnet "U-Net" kommer fra "U"-formen på arkitekturen.

U-net Architecture

Vi identifiserer tre hovedkomponenter:

  1. Contracting / Encoder: Rekkefølge av convolution/pooling-lag som komprimerer inngangsbildet til en representasjon i mindre størrelse.

  2. Bro / Flaskehals: Den nederste delen av "U" kobler koderen til dekoderen. Den er dannet av en serie konvolusjonsoperasjoner.

  3. Dekontraktering / Dekoder: Rekkefølge av oppkonvolusjoner og konvolusjonslag, som "dekomprimerer" utgangen fra flaskehalsen.

Arkitekturen til et U-Net ser så langt ut som en auto-koder. Forskjellen ligger imidlertid i informasjonen som sendes mellom koderen og dekoderen. Denne informasjonen overføres ved å sammenkoble resultatene av konvolusjoner fra koderen med resultatene av oppkonvolusjonen til dekoderen. Denne modifikasjonen forbedrer oppløsningen og lar modellen gi en mer romlig presis utgang (plasseringen av pikslene i utgangen vil være mer presis, og løser et problem som oppstod i modeller som ikke inkluderte sammenkobling). Sammenkoblingen gjøres symmetrisk.

Bygge en U-Net-modell for nedbør nåkasting

I denne delen skal vi bygge en U-Net-modell for å forutsi været fra satellittbilder. Vi vil bruke en forhåndstrent modell kalt Rain-Net.

Koden nedenfor er tilgjengelig i denne colab.

Vi installerer først wradlib, et åpen kildekodebibliotek for værradardatabehandling

!pip install wradlib
import wradlib as wrl

Vi skriver deretter to hjelpefunksjoner for å laste ned satellittdata fra DWDs åpne dataserver


import urllib.request
import io
import numpy as np
import datetime

def download_and_read_RY(RY_timestamp):
   url = f"https://opendata.dwd.de/weather/radar/radolan/ry/raa01-ry_10000-{RY_timestamp}-dwd---bin"
   data_binary = urllib.request.urlopen(url).read()
   data, attr = wrl.io.read_radolan_composite(io.BytesIO(data_binary), missing = 0)
   data = data.astype("float32")
   return data,attr

def download_data():
   latest_scan, latest_attr = download_and_read_RY("latest")
   latest_datetime = latest_attr["datetime"]
   list_for_downloading = [ts.strftime("%y%m%d%H%M") for ts in
       [latest_datetime - datetime.timedelta(minutes=t) for t in [15, 10, 5]]]
   previous_scans = np.array([download_and_read_RY(ts)[0] for ts in list_for_downloading])
   print(list_for_downloading)
   scans = np.concatenate([previous_scans, latest_scan[np.newaxis, ::, ::]], axis = 0)

   return scans, latest_datetime

Disse verktøyene lar oss laste ned de siste 4 satellittbildene, som er antallet satellittbilder vi trenger for å gjøre spådommer med vår forhåndstrente modell.

Vi kan da bruke funksjonene som er opprettet for å få de siste 4 bildene


RY_latest, RY_latest_timestep = download_data()

Etter å ha fått bildene bruker vi wradlibs vis.plot_ppi metode for å plotte dataene

for i in range(RY_latest.shape[0]):
   wrl.vis.plot_ppi(RY_latest[i])

VIS Radar

Vi har nå lastet inn dataene våre. La oss laste inn modellen neste.

Vi starter med å importere de aktuelle klassene. Vi vil bruke TensorFlow i denne artikkelen.

fra tensorflow.keras.layers importer Input, Conv2D, Activation, Concatenate, Conv2DTranspose, MaxPool2D

fra tensorflow.keras.models import Modell

La oss konstruere 3 primitive byggeklosser. Disse "byggeklossene" vil bli brukt til å lage hele arkitekturen, i henhold til denne implementeringen.

Den første blokken tilsvarer rekkefølgen av konvolusjonslag, vi kaller den "conv_block"

def conv_block(input, num_filters):
   x = Conv2D(num_filters, 3, padding ="same", kernel_initializer="he_normal"(input))
   x = Activation("relu")(x)
   x = Conv2D(num_filters, 3, padding ="same", kernel_initializer="he_normal"(x))
   x = Activation("relu")(x)
   return x

Den andre blokken brukes til å bygge fra koderdelen (konvolusjonsblokk + maks pooling). Vi kaller det en "encoder_block"

def encoder_block(input, num_filters):
   x = conv_block(input, num_filters)
   p = MaxPool2D((2,2))(x)
   return x,p

Den tredje og siste blokken er en "dekoder_blokk" (oppkonvolusjon + sammenkobling + konvolusjon).

def decoder_block(input, skip_features, num_filters):
   x = Conv2DTranspose(num_filters, (2,2), strides=2, padding="same", kernel_initializer="he_normal")
   x = Concatenate()([x, skip_features])
   x = conv_block(x, num_filters)
   return x

Vi kombinerer disse byggeklossene for å konstruere U-Net-modellen

def build_unet(input_shape = (928, 928, 4)):

   inputs = Input(input_shape)
   e1, p1 = encoder_bock(inputs, 64)
   e2, p2 = encoder_bock(p1, 128)
   e3, p3 = encoder_bock(p2, 256)
   e4, p4 = encoder_bock(p3, 512)

   b1 = conv_block(p4, 1024)

   d1 = decoder_block(b1, e4, 512)
   d2 = decoder_block(d1, e3, 256)
   d3 = decoder_block(d2, e2, 128)
   d4 = decoder_block(d3, e1, 64)

   outputs = Conv2D(1, 1, padding="same", activation="linear")(d4)

   unet = Model(inputs, outputs, name="U-Net")

   return unet

Lek gjerne litt med implementeringen, forbedre den eller tilpass den til dine behov hvis du vil bruke den til noe annet.

Å trene denne modellen kan ta mye tid. Heldigvis finnes det en modell som heter Rain-Net, som er laget basert på en U-Net-arkitektur, og som er spesialisert på nåkasting av nedbør.

La oss klone GitHub-depotet

! git clone https://github.com/hydrogo/rainnet.git

Vi laster så ned de forhåndstrente vektene for denne modellen

!wget -O /content/rainnet/rainnet_weights.h5 https://zenodo.org/record/3630429/files/rainnet_weights.h5

Det neste trinnet er å lage en modell basert på arkitekturen som er funnet på depotet og deretter laste ned vektene som er lastet ned til denne modellen

import sys
from rainnet import rainnet
model = rainnet.rainnet()
model.load_weights('/content/rainnet/rainnet_weights.h5')
model.summary()

Bildene vi lastet ned har en størrelse på 900*900 piksler. Vi skal omforme disse bildene for å matche den forventede inngangen til Rain-Net

def Scaler(array):
   return np.log(array+0.01)


def invScaler(array):
   return np.exp(array) - 0.01


def pad_to_shape(array, from_shape=900, to_shape=928, how="mirror"):
   # calculate how much to pad in respect with native resolution
   padding = int( (to_shape - from_shape) / 2)
   # for input shape as (batch, W, H, channels)
   if how == "zero":
       array_padded = np.pad(array, ((0,0),(padding,padding),(padding,padding),(0,0)), mode="constant", constant_values=0)
   elif how == "mirror":
       array_padded = np.pad(array, ((0,0),(padding,padding),(padding,padding),(0,0)), mode="reflect")
   return array_padded


def pred_to_rad(pred, from_shape=928, to_shape=900):
   # pred shape 12,928,928
   padding = int( (from_shape - to_shape) / 2)
   return pred[::, padding:padding+to_shape, padding:padding+to_shape].copy()

'''
the spatial extent of input data has to be a multiple of 2n+1
where n is the number of max pooling layers
'''

def data_preprocessing(X):

   # 0. Right shape for batch
   X = np.moveaxis(X, 0, -1)
   X = X[np.newaxis, ::, ::, ::]
   # 1. To log scale
   '''
   We use a log scale to respond to skewness towards large values
   '''
   X = Scaler(X)
   # 2. from 900x900 to 928x928
   X = pad_to_shape(X)

   return X


def data_postprocessing(nwcst):

   # 0. Squeeze empty dimensions
   nwcst = np.squeeze(np.array(nwcst))
   # 1. Convert back to rainfall depth
   nwcst = invScaler(nwcst)
   # 2. Convert from 928x928 back to 900x900
   nwcst = pred_to_rad(nwcst)
   # 3. Return only positive values
   nwcst = np.where(nwcst>0, nwcst, 0)
   return nwcst

Vi lager så en funksjon som lager spådommene.

def prediction(model_instance, input_data, lead_time=24):

   input_data = data_preprocessing(input_data)
   nwcst = []

   for _ in range(lead_time):
       pred = model_instance.predict(input_data)
       nwcst.append(pred)
       input_data = np.concatenate([input_data[::, ::, ::, 1:], pred], axis = -1)

   nwcst = data_postprocessing(nwcst)

   return nwcst

Vi kaller deretter denne funksjonen på dataene vi lastet ned tidligere

Y_pred = prediction(model, RY_latest)

Vi kan plotte spådommene og lagre dem for å bruke resultatene som er lagret til å lage et gif-bilde som lar oss visualisere spådommene

import matplotlib.pyplot as plt
names = []
for i in range(0, 19):
   im = wrl.vis.plot_ppi(Y_pred[i])
   name = '/content/image'+str(i)+'.png'
   names.append(name)
   plt.savefig(name)

import imageio
from google.colab import files

imgs = []

for name in names:
   imgs.append(imageio.imread(name))

imageio.mimsave('/content/pred.gif', imgs, fps=4)
files.download('/content/pred.gif')

Resuts

Gratulerer for at du har kommet så langt! Du kan nå bruke et regnnett til å lage spådommer og visualisere dem.

Konklusjon

I denne artikkelen har vi brukt en maskinlæringsmodell (Rain-Net) for å gjøre nedbør nåkasting. Vi brukte en U-Net-arkitektur, som vi bygde ved hjelp av TensorFlow. Vi lastet inn en forhåndstrent modell for å forutsi satellittbilder.

Denne implementeringen kan forbedres på mange måter. For eksempel:

  1. Finjuster modellen på datasettet

  2. Bruk en oppmerksomhetsbasert modul, for eksempel CBAM (Convolutional Block Attention Module) i arkitekturen.

Referanser

Googles blogg om deres U-Net-baserte modell for værmelding

Kom til en av våre gratis workshops!

Start din karriere som dataforsker med våre gratis workshops, som er basert på en tilpasningsdyktig læreplan og veiledet av bransjeeksperter.


Career Services background pattern

Karrieretjenester

Contact Section background image

La oss holde kontakten

Code Labs Academy © 2024 Alle rettigheter forbeholdes.