Ansøg til vores nye Data Science & AI og Cybersecurity Deltidsårgange

Nedbør Nowcasting med Machine Learning

ML
DL
CNN
Vejrudsigt
UNet
Nedbør Nowcasting med Machine Learning cover image

I dag vurderer meteorologer, at 90 % af vejrudsigterne er korrekte i løbet af 5 dage. De forudsigelser, der foretages, er normalt baseret på to separate metoder:

  1. Fysik-baserede tilgange: Disse tilgange bruger modeller, der integrerer målbare størrelser såsom tryk, skyernes bevægelse, himmelforhold... Sådanne modeller er gode til at forudsige vejret for de kommende dage eller uger.

  2. Fysikfrie (databaserede) tilgange: Disse tilgange bruger historiske data til at skabe modeller, der kan lave forudsigelser. Sådanne modeller viser gode resultater med at forudsige vejret i op til 6 timer eller det, der er kendt som weather nowcasting.

I denne artikel vil vi diskutere den anden kategori af tilgange. Vi vil diskutere de forskellige formater af vejrdata, hvordan maskinlæring kan udnyttes til at lave vejr-nowcasting, og hvordan de udviklede arkitekturer kan være gavnlige til at løse lignende problemer.

Data til klimaforudsigelse

Da de fysikfrie tilgange bruger historiske data, lad os starte med at se nærmere på de tilgængelige data.

Vi vil bruge to hovedkilder til data:

  1. Billeddata: Disse data har form af radar- eller satellitbilleder af et specificeret geografisk område. Det bruges til at forudsige nedbør, vindbevægelser eller fugtighed.

Satellite Image

  1. Tabeldata: Disse data har form af registreringer af målbare størrelser såsom temperatur, fugtighed eller vindhastighed.

Tabular Data

Mens begge datakilder er vigtige for at bygge kraftfulde modeller, vil vi fokusere på førstnævnte (billeddata indsamlet fra radarer eller satellitter) af enkelthedsgrunde. De mest almindeligt anvendte modeller med billeddata er Convolutional Neural Networks (CNNs ).

Efter dette arbejde, vil vi bruge en U-Net-arkitektur til at bygge vores egen nowcasting-model.

Arkitektur

At tage udgangspunkt i en eksisterende arkitektur er nyttigt af mange grunde, blandt andet:

Arkitekturer tjener som retningslinjer for at skabe nye modeller. Folk, der skaber nye arkitekturer, bruger en trial and error-tilgang for at nå frem til deres endelige resultater. Ved at genbruge deres endelige resultater kan vi spare en masse tid.

Foruddannede modeller er normalt tilgængelige til øjeblikkelig brug. Når forskere udgiver deres nye arkitekturer, offentliggør de som regel også de trænede parametre, så brugerne ikke skal igennem besværet med at træne/optimere fra bunden. Dette er især nyttigt for meget store, ressourcetørstige modeller.

Eksempler på berømte visionsarkitekturer inkluderer:

  • LeNet (60k parametre)

LeNet

  • AlexNet (60m parametre)

AlexNet

  • VGG-16 (138m parametre)

VGG-16

U-Net

U-Net er en arkitektur baseret på et fuldt foldet netværk, hvilket betyder, at det ikke har nogen fuldt forbundne lag. Det blev først introduceret til en medicinsk billedsegmenteringsopgave. Disse resultater inspirerede forskere til at udvide det til andre opgaver inden for computersyn.

I 2019 brugte Google en U-Net-baseret arkitektur til at skabe en nedbørsprognosemodel.

Navnet "U-Net" kommer fra "U"-formen af ​​dets arkitektur.

U-net Architecture

Vi identificerer tre hovedkomponenter:

  1. Contracting / Encoder: Succession af foldning/pooling-lag, som komprimerer inputbilledet til en repræsentation i mindre størrelse.

  2. Bro / Flaskehals: Den nederste del af "U"'et forbinder encoderen med dekoderen. Det er dannet af en række foldningsoperationer.

  3. Dekontraktering / Dekoder: Succession af upconvolutions og foldningslag, som "dekomprimerer" outputtet fra flaskehalsen.

Arkitekturen af ​​et U-Net ligner en auto-encoder indtil videre. Forskellen ligger imidlertid i den information, der passerer mellem koderen og dekoderen. Denne information videregives ved at sammenkæde resultaterne af foldninger fra koderen med resultaterne af foldningen af ​​dekoderen. Denne modifikation forbedrer opløsningen og gør det muligt for modellen at udsende et mere rumligt præcist output (placeringen af ​​pixels i outputtet vil være mere præcis, hvilket løser et problem, der opstod i modeller, der ikke inkluderede sammenkædning). Sammenkædningen sker symmetrisk.

Opbygning af en U-Net-model til nedbør nucasting

I dette afsnit vil vi bygge en U-Net-model til at forudsige vejret ud fra satellitbilleder. Vi vil bruge en præ-trænet model kaldet Rain-Net.

Koden nedenfor er tilgængelig i denne colab.

Vi installerer først wradlib, et Open Source-bibliotek til databehandling af vejrradarer

!pip install wradlib
import wradlib as wrl

Vi skriver derefter to hjælpefunktioner til at downloade satellitdata fra DWD's åbne 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 hjælpeprogrammer giver os mulighed for at downloade de seneste 4 satellitbilleder, som er antallet af satellitbilleder, som vi skal bruge for at lave forudsigelser med vores fortrænede model.

Vi kan så bruge de oprettede funktioner til at få de seneste 4 billeder


RY_latest, RY_latest_timestep = download_data()

Efter at have fået billederne bruger vi wradlibs vis.plot_ppi metode til at plotte dataene

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

VIS Radar

Vi har nu indlæst vores data. Lad os indlæse modellen næste gang.

Vi starter med at importere de relevante klasser. Vi vil bruge TensorFlow i denne artikel.

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

fra tensorflow.keras.models import Model

Lad os konstruere 3 primitive byggeklodser. Disse "byggeklodser" vil blive brugt til at skabe hele arkitekturen ifølge denne implementering.

Den første blok svarer til rækkefølgen af ​​foldningslag, vi kalder 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 anden blok bruges til at bygge fra indkoderdelen (foldningsblok + max pooling). Vi kalder 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 sidste blok er en "dekoder_blok" (opkonvolution + sammenkædning + foldning).

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 byggeklodser for at 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

Du er velkommen til at lege lidt med implementeringen, forbedre den eller tilpasse den til dine behov, hvis du vil bruge den til noget andet.

Træning af denne model kan tage meget tid. Heldigvis er der en model kaldet Rain-Net, som er blevet skabt baseret på en U-Net arkitektur og er specialiseret i nedbør nucasting.

Lad os klone dets GitHub-depot

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

Vi downloader derefter de fortrænede vægte til denne model

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

Det næste trin er at oprette en model baseret på arkitekturen fundet på depotet og derefter indlæse vægtene, der er downloadet til denne model

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

Billederne vi downloadede har en størrelse på 900*900 pixels. Vi vil omforme disse billeder, så de matcher det forventede input fra 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 opretter derefter en funktion, der laver forudsigelserne.

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 kalder så denne funktion på de data, vi downloadede tidligere

Y_pred = prediction(model, RY_latest)

Vi kan plotte forudsigelserne og gemme dem for at bruge de gemte resultater til at skabe et gif-billede, der giver os mulighed for at visualisere forudsigelserne

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

Tillykke med at nå så langt! Du er nu i stand til at bruge et regnnet til at lave forudsigelser og visualisere dem.

Konklusion

I denne artikel har vi brugt en maskinlæringsmodel (Rain-Net) til at lave nedbør nucasting. Vi brugte en U-Net-arkitektur, som vi byggede ved hjælp af TensorFlow. Vi indlæste en fortrænet model til at forudsige satellitbilleder.

Denne implementering kan forbedres på mange måder. For eksempel:

  1. Finjuster modellen på dit datasæt

  2. Brug et opmærksomhedsbaseret modul, såsom CBAM (Convolutional Block Attention Module) i arkitekturen.

Referencer

Kom til en af ​​vores gratis workshops!

Start din karriere som dataforsker med vores gratis workshops, som er baseret på en tilpasselig læseplan og guidet af brancheeksperter.


Career Services background pattern

Karriereservice

Contact Section background image

Lad os holde kontakten

Code Labs Academy © 2024 Alle rettigheder forbeholdes.