Տեղումներ Nowcasting մեքենայական ուսուցմամբ

ML
DL
CNN
Եղանակի կանխատեսում
UNet
Տեղումներ Nowcasting մեքենայական ուսուցմամբ cover image

Մեր օրերում օդերևութաբանների գնահատմամբ՝ եղանակի կանխատեսումների 90%-ը ճիշտ է 5 օրվա ընթացքում։ Կանխատեսումները, որոնք արվում են, սովորաբար հիմնված են երկու առանձին մեթոդների վրա.

  1. Ֆիզիկայի վրա հիմնված մոտեցումներ. այս մոտեցումները օգտագործում են մոդելներ, որոնք միավորում են չափելի մեծություններ, ինչպիսիք են ճնշումը, ամպերի շարժումը, երկնքի պայմանները… Նման մոդելները լավ են կանխատեսում եղանակը առաջիկա օրերի կամ շաբաթների համար:

  2. Առանց ֆիզիկայի (տվյալների վրա հիմնված) մոտեցումներ. այս մոտեցումները օգտագործում են պատմական տվյալներ՝ մոդելներ ստեղծելու համար, որոնք կարող են կանխատեսումներ անել: Նման մոդելները լավ արդյունքներ են ցույց տալիս մինչև 6 ժամ եղանակը կանխագուշակելու կամ այն, ինչ հայտնի է որպես եղանակային հեռարձակում:

Այս հոդվածում մենք կքննարկենք մոտեցումների երկրորդ կատեգորիան: Մենք կքննարկենք եղանակի տվյալների տարբեր ձևաչափերը, թե ինչպես կարող է մեքենայական ուսուցումը օգտագործել եղանակային եղանակի հիմա հեռարձակման համար և ինչպես կարող են մշակված ճարտարապետությունները օգտակար լինել նմանատիպ խնդիրների լուծման համար:

Տվյալներ կլիմայի կանխատեսման համար

Քանի որ ֆիզիկայից զերծ մոտեցումները օգտագործում են պատմական տվյալներ, եկեք սկսենք ուսումնասիրելով առկա տվյալները:

Մենք կօգտագործենք տվյալների երկու հիմնական աղբյուր.

  1. Պատկերային տվյալներ. այս տվյալները ստանում են որոշակի աշխարհագրական տարածքի ռադարային կամ արբանյակային պատկերների ձև: Այն օգտագործվում է տեղումների, քամու շարժման կամ խոնավության կանխատեսման համար:

Satellite Image

  1. Աղյուսակային տվյալներ. այս տվյալները վերցնում են չափելի քանակությունների գրանցումների ձև, ինչպիսիք են ջերմաստիճանը, խոնավությունը կամ քամու արագությունը:

Tabular Data

Թեև տվյալների երկու աղբյուրներն էլ կարևոր են հզոր մոդելներ ստեղծելու համար, մենք կկենտրոնանանք առաջինի վրա (ռադարներից կամ արբանյակներից հավաքված պատկերների տվյալները) պարզության պատճառով: Պատկերի տվյալների հետ առավել հաճախ օգտագործվող մոդելներն են Convolutional Neural Networks (CNNs )

Հետևելով այս աշխատանքին, մենք պատրաստվում ենք օգտագործել U-Net ճարտարապետություն՝ կառուցելու մեր սեփական «Nowcasting» մոդելը:

Ճարտարապետություն

Գոյություն ունեցող ճարտարապետությունից սկսելն օգտակար է բազմաթիվ պատճառներով, որոնցից են.

Ճարտարապետությունները ծառայում են որպես նոր մոդելներ ստեղծելու ուղեցույց: Մարդիկ, ովքեր ստեղծում են նոր ճարտարապետություն, ընդունում են փորձության և սխալի մոտեցում՝ իրենց վերջնական արդյունքներին հասնելու համար: Վերօգտագործելով դրանց վերջնական արդյունքները, մենք կարող ենք շատ ժամանակ խնայել:

Նախապես պատրաստված մոդելները սովորաբար հասանելի են անմիջապես օգտագործման համար: Երբ հետազոտողները հրապարակում են իրենց նոր ճարտարապետությունը, նրանք սովորաբար հրապարակում են նաև վերապատրաստված պարամետրերը, որպեսզի օգտվողները ստիպված չլինեն զրոյից վերապատրաստման/օպտիմիզացնելու դժվարությունների միջով անցնել: Սա հատկապես օգտակար է [շատ մեծ, ռեսուրսների համար ծարավ մոդելների] համար (https://twitter.com/huggingface/status/1377273424641466370?lang=en):

Հայտնի տեսողական ճարտարապետության օրինակները ներառում են.

  • LeNet (60k պարամետր)

LeNet

  • AlexNet (60 մ պարամետրեր)

AlexNet

  • VGG-16 (138 մ պարամետրեր)

VGG-16

U-Net

U-Net ճարտարապետություն է, որը հիմնված է ամբողջովին կոնվոլյուցիոն ցանցի վրա, ինչը նշանակում է, որ այն չունի լիովին միացված շերտեր: Այն առաջին անգամ ներկայացվել է բժշկական պատկերի հատվածավորման առաջադրանքի համար: Այս արդյունքները ոգեշնչեցին հետազոտողներին այն տարածել համակարգչային տեսողության այլ խնդիրների վրա:

2019 թվականին Google-ն օգտագործել է U-Net-ի վրա հիմնված ճարտարապետություն՝ տեղումների կանխատեսման մոդել ստեղծելու համար։

«U-Net» անվանումը գալիս է նրա ճարտարապետության «U» ձևից:

U-net Architecture

Մենք առանձնացնում ենք երեք հիմնական բաղադրիչ.

  1. Պայմանագրի կնքում / Կոդավորիչ. ոլորման/միավորվող շերտերի հաջորդականություն, որը սեղմում է մուտքագրված պատկերը ավելի փոքր չափի ներկայացման մեջ:

  2. Bridge / Bottleneck. «U»-ի ներքևի մասը միացնում է կոդավորիչը ապակոդավորիչին: Այն ձևավորվում է մի շարք կոնվուլյացիոն գործողությունների արդյունքում:

  3. Ապակոդավորող / Ապակոդավորող. վերափոխումների և ոլորման շերտերի հաջորդականություն, որոնք «ապակցում են» խցանման ելքը:

U-Net-ի ճարտարապետությունը մինչ այժմ կարծես ավտոմատ կոդավորիչ է: Այնուամենայնիվ, տարբերությունը կայանում է կոդավորողի և ապակոդավորողի միջև փոխանցվող տեղեկատվության մեջ: Այս տեղեկատվությունը փոխանցվում է կոդավորիչից ոլորումների արդյունքները միացնելով ապակոդավորիչի ոլորման արդյունքների հետ: Այս փոփոխությունը մեծացնում է լուծաչափը և թույլ է տալիս մոդելին ավելի տարածականորեն ճշգրիտ ելք դուրս բերել (արդյունքում պիքսելների տեղակայումը կլինի ավելի ճշգրիտ՝ լուծելով այն մոդելներում առաջացած խնդիրը, որը չի ներառում միացում): Միացումը կատարվում է սիմետրիկ:

Կառուցում ենք U-Net մոդել՝ տեղումների հիմա հեռարձակման համար

Այս բաժնում մենք կկառուցենք U-Net մոդել՝ արբանյակային պատկերներից եղանակը կանխատեսելու համար: Մենք կօգտագործենք նախապես պատրաստված մոդել, որը կոչվում է Rain-Net:

Ստորև բերված կոդը հասանելի է այս [colab]-ում (https://colab.research.google.com/drive/1jHzESsHAWKPPxIqGmWLIBY7JLhgThCZ5?usp=sharing):

Մենք նախ տեղադրում ենք wradlib բաց կոդով գրադարան եղանակային ռադարների տվյալների մշակման համար

!pip install wradlib
import wradlib as wrl

Այնուհետև մենք գրում ենք երկու օգտակար գործառույթ՝ արբանյակային տվյալները [DWD-ի բաց տվյալների սերվերից] ներբեռնելու համար (https://www.dwd.de/EN/ourservices/opendata/opendata.html)


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

Այս կոմունալ ծառայությունները մեզ թույլ են տալիս ներբեռնել արբանյակային վերջին 4 պատկերները, որոնք արբանյակային պատկերների քանակն են, որոնք մենք պետք է կանխատեսումներ անենք մեր նախապես պատրաստված մոդելով:

Այնուհետև մենք կարող ենք օգտագործել ստեղծված գործառույթները՝ վերջին 4 պատկերները ստանալու համար


RY_latest, RY_latest_timestep = download_data()

Պատկերները ստանալուց հետո մենք օգտագործում ենք wradlib-ի vis.plot_ppi մեթոդը՝ տվյալները գծագրելու համար:

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

VIS Radar

Մենք այժմ բեռնել ենք մեր տվյալները: Եկեք բեռնենք մոդելը հաջորդիվ:

Մենք սկսում ենք համապատասխան դասերի ներմուծմամբ։ Այս հոդվածում մենք կօգտագործենք TensorFlow-ը:

tensorflow.keras.layers-ից ներմուծել Input, Conv2D, Activation, Concatenate, Conv2DTranspose, MaxPool2D

tensorflow.keras.models import Model-ից

Եկեք կառուցենք 3 պարզունակ շինանյութ: Այս «շինանյութերը» կօգտագործվեն ամբողջ ճարտարապետությունը ստեղծելու համար՝ ըստ այս իրականացման:

Առաջին բլոկը համապատասխանում է կոնվոլյուցիոն շերտերի հաջորդականությանը, մենք այն անվանում ենք «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

Երկրորդ բլոկը օգտագործվում է կոդավորիչի մասից կառուցելու համար (կոնվոլյուցիոն բլոկ + առավելագույն միավորում): Մենք այն անվանում ենք «encoder_block»

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

Երրորդ և վերջին բլոկը «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

Մենք միավորում ենք այս շինանյութերը՝ U-Net մոդելը կառուցելու համար

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

Ազատորեն խաղացեք իրականացման հետ, բարելավեք այն կամ հարմարեցրեք այն ձեր կարիքներին, եթե ցանկանում եք այն օգտագործել այլ բանի համար:

Այս մոդելի ուսուցումը կարող է շատ ժամանակ խլել: Բարեբախտաբար, կա Rain-Net կոչվող մոդել, որը ստեղծվել է U-Net ճարտարապետության հիման վրա և մասնագիտացված է տեղումների հիմա հեռարձակման մեջ:

Եկեք կլոնավորենք նրա GitHub պահոցը

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

Այնուհետև մենք ներբեռնում ենք այս մոդելի համար պատրաստված կշիռները

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

Հաջորդ քայլը պահեստում հայտնաբերված ճարտարապետության վրա հիմնված մոդել ստեղծելն է, այնուհետև բեռնել այս մոդելում ներբեռնված կշիռները

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

Մեր ներբեռնած պատկերներն ունեն 900*900 պիքսել չափս։ Մենք պատրաստվում ենք վերափոխել այս պատկերները, որպեսզի համապատասխանեն 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

Այնուհետև մենք ստեղծում ենք ֆունկցիա, որը կանխատեսումներ է անում:

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

Այնուհետև մենք կանչում ենք այս գործառույթը նախկինում ներբեռնված տվյալների վրա

Y_pred = prediction(model, RY_latest)

Մենք կարող ենք գծագրել կանխատեսումները և պահպանել դրանք՝ օգտագործելու պահված արդյունքները՝ ստեղծելու gif պատկեր, որը թույլ է տալիս պատկերացնել կանխատեսումները:

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

Շնորհավորում ենք այսքանը հասնելու համար: Այժմ դուք կարող եք օգտագործել Rain-Net՝ կանխատեսումներ անելու և դրանք պատկերացնելու համար:

Եզրակացություն

Այս հոդվածում մենք օգտագործել ենք մեքենայական ուսուցման մոդելը (Rain-Net)՝ տեղումների հիմա հեռարձակում կատարելու համար: Մենք օգտագործեցինք U-Net ճարտարապետություն, որը մենք կառուցեցինք TensorFlow-ի միջոցով: Մենք բեռնեցինք նախապես պատրաստված մոդել՝ արբանյակային պատկերները կանխատեսելու համար:

Այս իրականացումը կարող է բարելավվել բազմաթիվ առումներով: Օրինակ.

  1. Մանրացնել մոդելը ձեր տվյալների բազայում

  2. Օգտագործեք ուշադրության վրա հիմնված մոդուլ, ինչպիսին է CBAM (Convolutional Block Attention Module) ճարտարապետության մեջ:

Հղումներ

Եկեք մեր անվճար սեմինարներից մեկը:

Սկսեք ձեր կարիերան որպես տվյալների գիտնական մեր անվճար սեմինարներով, որոնք հիմնված են հարմարվող ուսումնական ծրագրի վրա և առաջնորդվում են ոլորտի փորձագետների կողմից:


  • Վարպետ Machine Learning Code Labs Academy-ի հետ: Միացեք մեր առցանց Bootcamp-ին. Հասանելի են ճկուն կես դրույքով և լրիվ դրույքով ընտրանքներ:*

Career Services background pattern

Կարիերայի ծառայություններ

Contact Section background image

Եկեք մնանք կապի մեջ

Code Labs Academy © 2024 Բոլոր իրավունքները պաշտպանված են.