Մեր օրերում օդերևութաբանների գնահատմամբ՝ եղանակի կանխատեսումների 90%-ը ճիշտ է 5 օրվա ընթացքում։ Կանխատեսումները, որոնք արվում են, սովորաբար հիմնված են երկու առանձին մեթոդների վրա.
-
Ֆիզիկայի վրա հիմնված մոտեցումներ. այս մոտեցումները օգտագործում են մոդելներ, որոնք միավորում են չափելի մեծություններ, ինչպիսիք են ճնշումը, ամպերի շարժումը, երկնքի պայմանները… Նման մոդելները լավ են կանխատեսում եղանակը առաջիկա օրերի կամ շաբաթների համար:
-
Առանց ֆիզիկայի (տվյալների վրա հիմնված) մոտեցումներ. այս մոտեցումները օգտագործում են պատմական տվյալներ՝ մոդելներ ստեղծելու համար, որոնք կարող են կանխատեսումներ անել: Նման մոդելները լավ արդյունքներ են ցույց տալիս մինչև 6 ժամ եղանակը կանխագուշակելու կամ այն, ինչ հայտնի է որպես եղանակային հեռարձակում:
Այս հոդվածում մենք կքննարկենք մոտեցումների երկրորդ կատեգորիան: Մենք կքննարկենք եղանակի տվյալների տարբեր ձևաչափերը, թե ինչպես կարող է մեքենայական ուսուցումը օգտագործել եղանակային եղանակի հիմա հեռարձակման համար և ինչպես կարող են մշակված ճարտարապետությունները օգտակար լինել նմանատիպ խնդիրների լուծման համար:
Տվյալներ կլիմայի կանխատեսման համար
Քանի որ ֆիզիկայից զերծ մոտեցումները օգտագործում են պատմական տվյալներ, եկեք սկսենք ուսումնասիրելով առկա տվյալները:
Մենք կօգտագործենք տվյալների երկու հիմնական աղբյուր.
- Պատկերային տվյալներ. այս տվյալները ստանում են որոշակի աշխարհագրական տարածքի ռադարային կամ արբանյակային պատկերների ձև: Այն օգտագործվում է տեղումների, քամու շարժման կամ խոնավության կանխատեսման համար:
- Աղյուսակային տվյալներ. այս տվյալները վերցնում են չափելի քանակությունների գրանցումների ձև, ինչպիսիք են ջերմաստիճանը, խոնավությունը կամ քամու արագությունը:
Թեև տվյալների երկու աղբյուրներն էլ կարևոր են հզոր մոդելներ ստեղծելու համար, մենք կկենտրոնանանք առաջինի վրա (ռադարներից կամ արբանյակներից հավաքված պատկերների տվյալները) պարզության պատճառով: Պատկերի տվյալների հետ առավել հաճախ օգտագործվող մոդելներն են Convolutional Neural Networks (CNNs )
Հետևելով այս աշխատանքին, մենք պատրաստվում ենք օգտագործել U-Net ճարտարապետություն՝ կառուցելու մեր սեփական «Nowcasting» մոդելը:
Ճարտարապետություն
Գոյություն ունեցող ճարտարապետությունից սկսելն օգտակար է բազմաթիվ պատճառներով, որոնցից են.
Ճարտարապետությունները ծառայում են որպես նոր մոդելներ ստեղծելու ուղեցույց: Մարդիկ, ովքեր ստեղծում են նոր ճարտարապետություն, ընդունում են փորձության և սխալի մոտեցում՝ իրենց վերջնական արդյունքներին հասնելու համար: Վերօգտագործելով դրանց վերջնական արդյունքները, մենք կարող ենք շատ ժամանակ խնայել:
Նախապես պատրաստված մոդելները սովորաբար հասանելի են անմիջապես օգտագործման համար: Երբ հետազոտողները հրապարակում են իրենց նոր ճարտարապետությունը, նրանք սովորաբար հրապարակում են նաև վերապատրաստված պարամետրերը, որպեսզի օգտվողները ստիպված չլինեն զրոյից վերապատրաստման/օպտիմիզացնելու դժվարությունների միջով անցնել: Սա հատկապես օգտակար է [շատ մեծ, ռեսուրսների համար ծարավ մոդելների] համար (https://twitter.com/huggingface/status/1377273424641466370?lang=en):
Հայտնի տեսողական ճարտարապետության օրինակները ներառում են.
- LeNet (60k պարամետր)
- AlexNet (60 մ պարամետրեր)
- VGG-16 (138 մ պարամետրեր)
U-Net
U-Net ճարտարապետություն է, որը հիմնված է ամբողջովին կոնվոլյուցիոն ցանցի վրա, ինչը նշանակում է, որ այն չունի լիովին միացված շերտեր: Այն առաջին անգամ ներկայացվել է բժշկական պատկերի հատվածավորման առաջադրանքի համար: Այս արդյունքները ոգեշնչեցին հետազոտողներին այն տարածել համակարգչային տեսողության այլ խնդիրների վրա:
2019 թվականին Google-ն օգտագործել է U-Net-ի վրա հիմնված ճարտարապետություն՝ տեղումների կանխատեսման մոդել ստեղծելու համար։
«U-Net» անվանումը գալիս է նրա ճարտարապետության «U» ձևից:
Մենք առանձնացնում ենք երեք հիմնական բաղադրիչ.
-
Պայմանագրի կնքում / Կոդավորիչ. ոլորման/միավորվող շերտերի հաջորդականություն, որը սեղմում է մուտքագրված պատկերը ավելի փոքր չափի ներկայացման մեջ:
-
Bridge / Bottleneck. «U»-ի ներքևի մասը միացնում է կոդավորիչը ապակոդավորիչին: Այն ձևավորվում է մի շարք կոնվուլյացիոն գործողությունների արդյունքում:
-
Ապակոդավորող / Ապակոդավորող. վերափոխումների և ոլորման շերտերի հաջորդականություն, որոնք «ապակցում են» խցանման ելքը:
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])
Մենք այժմ բեռնել ենք մեր տվյալները: Եկեք բեռնենք մոդելը հաջորդիվ:
Մենք սկսում ենք համապատասխան դասերի ներմուծմամբ։ Այս հոդվածում մենք կօգտագործենք 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')
Շնորհավորում ենք այսքանը հասնելու համար: Այժմ դուք կարող եք օգտագործել Rain-Net՝ կանխատեսումներ անելու և դրանք պատկերացնելու համար:
Եզրակացություն
Այս հոդվածում մենք օգտագործել ենք մեքենայական ուսուցման մոդելը (Rain-Net)՝ տեղումների հիմա հեռարձակում կատարելու համար: Մենք օգտագործեցինք U-Net ճարտարապետություն, որը մենք կառուցեցինք TensorFlow-ի միջոցով: Մենք բեռնեցինք նախապես պատրաստված մոդել՝ արբանյակային պատկերները կանխատեսելու համար:
Այս իրականացումը կարող է բարելավվել բազմաթիվ առումներով: Օրինակ.
-
Մանրացնել մոդելը ձեր տվյալների բազայում
-
Օգտագործեք ուշադրության վրա հիմնված մոդուլ, ինչպիսին է CBAM (Convolutional Block Attention Module) ճարտարապետության մեջ:
Հղումներ
Եկեք մեր անվճար սեմինարներից մեկը:
Սկսեք ձեր կարիերան որպես տվյալների գիտնական մեր անվճար սեմինարներով, որոնք հիմնված են հարմարվող ուսումնական ծրագրի վրա և առաջնորդվում են ոլորտի փորձագետների կողմից:
- Վարպետ Machine Learning Code Labs Academy-ի հետ: Միացեք մեր առցանց Bootcamp-ին. Հասանելի են ճկուն կես դրույքով և լրիվ դրույքով ընտրանքներ:*