Prezipitazioak Nowcasting Machine Learning-ekin

ML
DL
CNN
Eguraldi Iragarpena
UNet
Prezipitazioak Nowcasting Machine Learning-ekin cover image

Gaur egun, meteorologoek kalkulatzen dute eguraldiaren iragarpenen % 90 zuzena dela bost eguneko epean. Egiten diren iragarpenak bi metodo ezberdinetan oinarritzen dira normalean:

  1. Fisikan oinarritutako planteamenduak: Planteamendu hauek kantitate neurgarriak integratzen dituzten ereduak erabiltzen dituzte, hala nola presioa, hodeien mugimendua, zeruaren baldintzak... Eredu horiek onak dira datozen egun edo asteetarako eguraldia iragartzeko.

  2. Fisikarik gabeko ikuspegiak (datuetan oinarritutakoak): ikuspegi hauek datu historikoak erabiltzen dituzte iragarpenak egin ditzaketen ereduak sortzeko. Horrelako ereduek emaitza onak erakusten dituzte eguraldia 6 orduz edo eguraldia orain iragartzeko moduan ezagutzen dena.

Artikulu honetan, planteamenduen bigarren kategoriari buruz hitz egingo dugu. Eguraldi-datuen formatu desberdinak eztabaidatuko ditugu, ikaskuntza automatikoa nola aprobetxa daitekeen eguraldia nowcasting egiteko eta garatutako arkitekturak antzeko arazoak konpontzeko nola onuragarriak izan daitezkeen.

Klimaren Iragarpenerako Datuak

Fisikarik gabeko planteamenduek datu historikoak erabiltzen dituztenez, has gaitezen eskuragarri dauden datuak aztertzen.

Bi datu iturri nagusi erabiliko ditugu:

  1. Irudi-datuak: datu hauek eremu geografiko jakin bateko radar edo satelite-irudien forma hartzen dute. Prezipitazioa, haizearen mugimendua edo hezetasuna iragartzeko erabiltzen da.

Satellite Image

  1. Datu taularrak : Datu hauek tenperatura, hezetasuna edo haizearen abiadura bezalako kantitate neurgarrien erregistroen forma hartzen dute.

Tabular Data

Datu-iturri biak eredu indartsuak eraikitzeko garrantzitsuak diren arren, lehengoan zentratuko gara (radar edo sateliteetatik jasotako irudien datuak) sinpletasun arrazoiengatik. Irudien datuekin gehien erabiltzen diren ereduak Sare neuronal konboluzionalak (CNNak dira) ).

[Lan] honen ondoren (https://arxiv.org/pdf/1807.06521.pdf), U-Net arkitektura bat erabiliko dugu gure nowcasting eredua eraikitzeko.

Arkitektura

Lehendik dagoen arkitektura batetik hastea lagungarria da hainbat arrazoirengatik, besteak beste:

Arkitekturak eredu berriak sortzeko jarraibide gisa balio dute. Arkitektura berriak sortzen dituzten pertsonek proba eta akatsen ikuspegia hartzen dute azken emaitzetara iristeko. Haien azken emaitzak berrerabiliz, denbora asko aurreztu dezakegu.

Aurrez prestatutako ereduak berehala erabiltzeko eskuragarri egon ohi dira. Ikertzaileek beren arkitektura berriak argitaratzen dituztenean, normalean trebatutako parametroak ere argitaratzen dituzte, erabiltzaileek hutsetik entrenatzeko/optimizatzeko arazorik izan ez dezaten. Hau bereziki erabilgarria da eredu oso handi eta baliabide egarrientzat.

Ikusmen-arkitektura ospetsuen adibideak hauek dira:

  • LeNet (60k parametro)

LeNet

  • AlexNet (60m parametroak)

AlexNet

  • VGG-16 (138m parametroak)

VGG-16

U-Net

U-Net sare guztiz konbolutibo batean oinarritutako arkitektura bat da, hau da, ez du guztiz konektatutako geruzarik. Irudi medikoen segmentazio-zeregin baterako sartu zen lehen aldiz. Emaitza hauek ikertzaileak ikusmen informatikoko beste zeregin batzuetara zabaltzera bultzatu zituzten.

2019an, Google-k U-Net-en oinarritutako arkitektura bat erabili zuen prezipitazioen iragarpen-eredu bat sortzeko.

"U-Net" izena bere arkitekturaren "U" formatik dator.

U-net Architecture

Hiru osagai nagusi identifikatzen ditugu:

  1. Kontratazioa / Encoder: Sarrerako irudia tamaina txikiagoko irudikapen batean konprimitzen duten konboluzio/bilketa geruzen segida.

  2. Zubia / Botilako lepoa: "U"ren beheko zatiak kodetzailea deskodetzaileari lotzen du. Bihurketa-eragiketa batzuen bidez eratzen da.

  3. Deskontratazioa / Deskodetzailea: Goranzko biribilduren eta konboluzio-geruzen segida, botila-lepoaren irteera "deskonprimitzen" dutenak.

U-Net baten arkitekturak auto-kodetzaile baten itxura du orain arte. Hala ere, aldea kodetzailearen eta deskodetzailearen artean igarotzen den informazioan dago. Informazio hori kodegailuko konboluzioen emaitzak deskodetzailearen gorako konboluzioarekin kateatuz pasatzen da. Aldaketa honek bereizmena hobetzen du, eta ereduak irteera espazialki zehatzago bat ateratzeko aukera ematen du (irteeran pixelen kokapena zehatzagoa izango da, kateatzea barne hartzen ez zuten ereduetan gertatutako arazo bat konponduz). Kateamendua simetrikoki egiten da.

Prezipitazioen Nowcasting U-Net eredua eraikitzen

Atal honetan, satelite-irudietatik eguraldia aurreikusteko U-Net eredua eraikiko dugu. Aurrez prestatutako eredua erabiliko dugu Rain-Net.

Beheko kodea [colab] honetan dago eskuragarri (https://arxiv.org/abs/1505.04597).

Lehenik eta behin wradlib instalatzen dugu, Eguraldi Radar datuen tratamendurako kode irekiko liburutegia.

!pip install wradlib
import wradlib as wrl

Ondoren, bi erabilgarritasun-funtzio idazten ditugu sateliteen datuak deskargatzeko DWDren datu irekien zerbitzaritik


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

Utilitate hauei esker, azken 4 satelite irudiak deskargatu ditzakegu, hau da, aurrez prestatutako ereduarekin iragarpenak egiteko behar ditugun satelite irudien kopurua.

Ondoren, sortutako funtzioak erabil ditzakegu azken 4 irudiak lortzeko


RY_latest, RY_latest_timestep = download_data()

Irudiak lortu ondoren, wradlib-ren vis.plot_ppi metodoa erabiltzen dugu datuak irudikatzeko

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

VIS Radar

Orain gure datuak kargatu ditugu. Karga dezagun hurrengo eredua.

Dagokion klaseak inportatzen hasiko gara. Artikulu honetan TensorFlow erabiliko dugu.

tensorflow.keras.layers inportatu Sarrera, Conv2D, Activation, Concatenate, Conv2DTranspose, MaxPool2D

tensorflow.keras.models inportazio eredua

Eraiki ditzagun 3 eraikuntza-bloke primitibo. "Eraikuntza-bloke" hauek arkitektura osoa sortzeko erabiliko dira, [inplementazio] honen arabera (https://github.com/bnsreenu/python_for_microscopists/blob/master/219-unet_model_with_functions_of_blocks.py).

Lehenengo blokea geruza konbolutiboen segidari dagokio, "conv_block" deitzen diogu

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

Bigarren blokea kodetzailearen zatitik (bloke konboluzionala + bilketa maximoa) eraikitzeko erabiltzen da. "encoder_block" deitzen diogu

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

Hirugarren eta azken blokea "deskodetzaile_blokea" da (gora-konboluzioa + kateatzea + konboluzioa).

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

Eraikuntza-bloke hauek konbinatzen ditugu U-Net eredua eraikitzeko

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

Anima zaitez inplementazioarekin jolastu, hobetu edo zure beharretara egokitu beste zerbaitetarako erabili nahi baduzu.

Eredu hau entrenatzeak denbora asko behar izan dezake. Zorionez, badago Rain-Net izeneko eredu bat, U-Net arkitekturan oinarrituta sortu dena, eta prezipitazioaren nowcasting-ean espezializatua.

Klon dezagun bere GitHub biltegia

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

Ondoren, eredu honetarako aurrez prestatutako pisuak deskargatzen ditugu

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

Hurrengo pausoa biltegian aurkitutako arkitekturan oinarritutako eredu bat sortzea da, gero eredu honetara deskargatutako pisuak kargatzea.

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

Deskargatu ditugun irudiek 900*900 pixeleko tamaina dute. Irudi hauek birmoldatuko ditugu Rain-Net-en esperotako sarrerarekin bat etor daitezen

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

Ondoren, iragarpenak egiten dituen funtzio bat sortzen dugu.

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

Ondoren, funtzio honi lehen deskargatu ditugun datuei deitzen diegu

Y_pred = prediction(model, RY_latest)

Iragarpenak irudikatu ditzakegu, eta gorde itzazu gordetako emaitzak erabiltzeko iragarpenak ikusteko aukera ematen duen gif irudi bat sortzeko.

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

Zorionak honaino iristeagatik! Orain Rain-Net bat erabil dezakezu iragarpenak egiteko eta haiek ikusteko.

Ondorioa

Artikulu honetan, ikaskuntza automatikoko eredu bat (Rain-Net) erabili dugu prezipitazioen orain-ematea egiteko. U-Net arkitektura bat erabili dugu, TensorFlow erabiliz eraiki duguna. Satelite-irudiak iragartzeko aurrez prestatutako eredu bat kargatu dugu.

Inplementazio hau modu askotan hobetu daiteke. Adibidez:

  1. Egokitu eredua zure datu multzoan

  2. Erabili arretan oinarritutako modulu bat, adibidez CBAM (Convolutional Block Attention Module) arkitekturan.

Erreferentziak

Zatoz gure doako tailer batera!

Hasi zure karrera datu-zientzialari gisa gure doako tailerrak, curriculum moldagarri batean oinarritutakoak eta industriako adituek gidatutakoak.


Career Services background pattern

Lanbide Zerbitzuak

Contact Section background image

Jarrai gaitezen harremanetan

Code Labs Academy © 2024 Eskubide guztiak erreserbatuta.