Hae uuteen Data Science & AI ja Cybersecurity Osa-aikaiset kohortit

Precipitation Nowcasting koneoppimisen avulla

ML
DL
CNN
säänennustus
UNet
Precipitation Nowcasting koneoppimisen avulla cover image

Nykyään meteorologit arvioivat, että 90 % sääennusteista pitää paikkansa viiden päivän ajanjaksolla. Tehdyt ennusteet perustuvat yleensä kahteen erilliseen menetelmään:

  1. Fysiikkaan perustuvat lähestymistavat: Nämä lähestymistavat käyttävät malleja, jotka yhdistävät mitattavissa olevia suureita, kuten paineita, pilvien liikettä, taivaan olosuhteet… Tällaiset mallit ovat hyviä ennustamaan säätä tuleville päiville tai viikkoille.

  2. Fysiikkaa sisältämättömät (tietopohjaiset) lähestymistavat: Nämä lähestymistavat käyttävät historiallisia tietoja mallien luomiseen, jotka voivat tehdä ennusteita. Tällaiset mallit osoittavat hyviä tuloksia sään ennustamisessa jopa 6 tunnin ajaksi tai ns. sään nytcastingiksi.

Tässä artikkelissa käsittelemme toista lähestymistapaa. Keskustelemme säätietojen eri muodoista, siitä, kuinka koneoppimista voidaan hyödyntää säänäyttöön ja kuinka kehitetyistä arkkitehtuureista voi olla hyötyä vastaavien ongelmien ratkaisemisessa.

Tietoa ilmaston ennustamiseen

Koska fysiikkavapaat lähestymistavat käyttävät historiallisia tietoja, aloitetaan tarkastelemalla saatavilla olevia tietoja.

Käytämme kahta päätietolähdettä:

  1. Kuvatiedot: Nämä tiedot ovat tietyn maantieteellisen alueen tutka- tai satelliittikuvia. Sitä käytetään ennustamaan sademäärää, tuulen liikettä tai kosteutta.

Satellite Image

  1. Taulukkotiedot: Nämä tiedot ovat mitattavissa olevia suureita, kuten lämpötilaa, kosteutta tai tuulen nopeutta.

Tabular Data

Vaikka molemmat tietolähteet ovat tärkeitä tehokkaiden mallien rakentamisessa, keskitymme ensimmäiseen (tutkista tai satelliiteista kerättyihin kuvatietoihin) yksinkertaisuuden vuoksi. Yleisimmin käytetyt mallit kuvadatalla ovat Convolutional Neural Networks (CNN:t ).

Tämän työn jälkeen aiomme rakentaa oman nowcasting-mallimme U-Net-arkkitehtuurilla.

Arkkitehtuuri

Olemassa olevasta arkkitehtuurista aloittaminen on hyödyllistä monista syistä, kuten:

Arkkitehtuurit toimivat ohjenuorana uusien mallien luomisessa. Ihmiset, jotka luovat uusia arkkitehtuureja, ottavat käyttöön yrityksen ja erehdyksen lähestymistavan saavuttaakseen lopulliset tulokset. Käyttämällä uudelleen niiden lopullisia tuloksia voimme säästää paljon aikaa.

Esikoulutetut mallit ovat yleensä saatavilla välittömästi käyttöön. Kun tutkijat julkaisevat uusia arkkitehtuuriaan, he yleensä julkaisevat myös koulutetut parametrit, jotta käyttäjien ei tarvitse käydä läpi koulutusta/optimointia tyhjästä. Tämä on erityisen hyödyllistä erittäin suurille, resursseja kaipaaville malleille.

Esimerkkejä kuuluisista visioarkkitehtuureista ovat:

  • LeNet (60 000 parametria)

LeNet

  • AlexNet (60 metrin parametrit)

AlexNet

  • VGG-16 (138m parametrit)

VGG-16

U-Net

U-Net on täysin konvoluutioverkkoon perustuva arkkitehtuuri, mikä tarkoittaa, että siinä ei ole täysin yhdistettyjä kerroksia. Se otettiin ensimmäisen kerran käyttöön lääketieteellisen kuvan segmentointitehtävää varten. Nämä tulokset inspiroivat tutkijoita laajentamaan sitä muihin tietokonenäön tehtäviin.

Vuonna 2019 Google käytti U-Net-pohjaista arkkitehtuuria sateenennustemallin luomiseen.

Nimi "U-Net" tulee sen arkkitehtuurin "U"-muodosta.

U-net Architecture

Tunnistamme kolme pääkomponenttia:

  1. Contracting / Encoder: Convolution/pooling-kerrosten peräkkäisyys, jotka pakkaavat syöttökuvan pienempään esitykseen.

  2. Silta / pullonkaula: "U":n alaosa yhdistää kooderin dekooderiin. Se muodostuu sarjasta konvoluutiooperaatioita.

  3. Decontracting / Dekooderi: peräkkäiset ylöskonvoluutio- ja konvoluutiokerrokset, jotka "purkaavat" pullonkaulan tulosteen.

U-Netin arkkitehtuuri näyttää toistaiseksi automaattiselta enkooderilta. Ero on kuitenkin kooderin ja dekooderin välillä kulkevassa informaatiossa. Tämä informaatio välitetään ketjuttamalla kooderin konvoluutioiden tulokset dekooderin ylöskonvoluutioten kanssa. Tämä muutos parantaa resoluutiota ja antaa mallille mahdollisuuden tuottaa spatiaalisesti tarkemman tulosteen (pikseleiden sijainti tulosteessa on tarkempi, mikä ratkaisee ongelman, joka ilmeni malleissa, joissa ei ollut ketjutusta). Yhdistäminen tapahtuu symmetrisesti.

U-Net-mallin rakentaminen sadetta varten

Tässä osiossa rakennamme U-Net-mallin ennustamaan säätä satelliittikuvien perusteella. Käytämme esikoulutettua mallia nimeltä Rain-Net.

Alla oleva koodi on saatavilla tässä colabissa.

Asennamme ensin wradlib, avoimen lähdekoodin kirjaston säätutkatietojen käsittelyä varten

!pip install wradlib
import wradlib as wrl

Tämän jälkeen kirjoitamme kaksi aputoimintoa satelliittitietojen lataamiseksi DWD:n avoimelta datapalvelimelta


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

Näiden apuohjelmien avulla voimme ladata viimeisimmät 4 satelliittikuvaa, mikä on niiden satelliittikuvien määrä, jotka tarvitsemme ennusteiden tekemiseen esiopetetulla mallillamme.

Voimme sitten käyttää luotuja toimintoja saadaksemme 4 viimeisintä kuvaa


RY_latest, RY_latest_timestep = download_data()

Kun kuvat on saatu, käytämme wradlibin vis.plot_ppi -menetelmää tietojen kuvaamiseen

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

VIS Radar

Olemme nyt ladaneet tietomme. Ladataan malli seuraavaksi.

Aloitamme tuomalla asiaankuuluvat luokat. Käytämme TensorFlow'ta tässä artikkelissa.

osoitteesta tensorflow.keras.layers tuontisyöttö, Conv2D, aktivointi, ketjuttaminen, Conv2DTranspose, MaxPool2D

osoitteesta tensorflow.keras.models tuonti Malli

Rakennetaan 3 primitiivistä rakennuspalikka. Näitä "rakennuspalikoita" käytetään koko arkkitehtuurin luomiseen tämän [toteutuksen] mukaisesti (https://github.com/bnsreenu/python_for_microscopists/blob/master/219-unet_model_with_functions_of_blocks.py).

Ensimmäinen lohko vastaa konvoluutiokerrosten peräkkäisyyttä, kutsumme sitä "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

Toista lohkoa käytetään enkooderin muodostamiseen (konvoluutiolohko + max pooling). Kutsumme sitä "encoder_blockiksi"

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

Kolmas ja viimeinen lohko on "decoder_block" (upconvolution + concatenation + convolution).

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

Yhdistämme nämä rakennuspalikat U-Net-mallin rakentamiseksi

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

Voit vapaasti leikkiä toteutuksen kanssa, parantaa sitä tai mukauttaa sitä tarpeisiisi, jos haluat käyttää sitä johonkin muuhun.

Tämän mallin kouluttaminen voi viedä paljon aikaa. Onneksi on olemassa malli nimeltä Rain-Net, joka on luotu U-Net-arkkitehtuuriin perustuen ja on erikoistunut sateen nytvalamiseen.

Kloonataan sen GitHub-arkisto

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

Lataamme sitten esikoulutetut painot tälle mallille

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

Seuraava askel on luoda malli arkistosta löytyneen arkkitehtuurin perusteella ja ladata sitten tähän malliin ladatut painot

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

Lataamiemme kuvien koko on 900*900 pikseliä. Muotoilemme nämä kuvat uudelleen vastaamaan Rain-Netin odotettua syöttöä

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

Luomme sitten funktion, joka tekee ennusteet.

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

Kutsumme sitten tätä toimintoa aiemmin lataamiemme tietojen perusteella

Y_pred = prediction(model, RY_latest)

Voimme piirtää ennusteet ja tallentaa ne käyttääksemme tallennettuja tuloksia gif-kuvan luomiseen, jonka avulla voimme visualisoida ennusteet

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

Onnittelut, että olet päässyt näin pitkälle! Nyt voit käyttää sadeverkkoa ennustamaan ja visualisoimaan niitä.

Johtopäätös

Tässä artikkelissa olemme käyttäneet koneoppimismallia (Rain-Net) sademäärän laskemiseen. Käytimme U-Net-arkkitehtuuria, jonka rakensimme TensorFlow'lla. Latasimme esikoulutetun mallin ennustamaan satelliittikuvia.

Tätä toteutusta voidaan parantaa monella tapaa. Esimerkiksi:

  1. Hienosäädä mallia tietojoukossasi

  2. Käytä arkkitehtuurissa huomiopohjaista moduulia, kuten CBAM:ia (Convolutional Block Attention Module).

Viitteet

Tule johonkin ilmaisista työpajoistamme!

Aloita urasi datatieteilijänä ilmaisilla työpajoillamme, jotka perustuvat mukautuvaan opetussuunnitelmaan ja joita ohjaavat alan asiantuntijat.


Career Services background pattern

Urapalvelut

Contact Section background image

Pidetään yhteyttä

Code Labs Academy © 2024 Kaikki oikeudet pidätetään.