Aplikuj do naszych nowych kohort Data Science & AI i Cybersecurity w niepełnym wymiarze godzin

Przesyłanie informacji o opadach za pomocą uczenia maszynowego

ML
DL
CNN
prognoza pogody
UNet
Przesyłanie informacji o opadach za pomocą uczenia maszynowego cover image

Obecnie meteorolodzy szacują, że 90% prognoz pogody sprawdza się w ciągu 5 dni. Dokonywane przewidywania opierają się zwykle na dwóch oddzielnych metodach:

  1. Podejścia oparte na fizyce: Podejścia te wykorzystują modele, które integrują mierzalne wielkości, takie jak ciśnienie, ruch chmur, stan nieba… Takie modele dobrze przewidują pogodę na nadchodzące dni lub tygodnie.

  2. Podejścia niefizyczne (oparte na danych): podejścia te wykorzystują dane historyczne do tworzenia modeli, które umożliwiają przewidywanie. Modele takie wykazują dobre wyniki w przewidywaniu pogody na okres do 6 godzin, czyli w tzw. prognozowaniu pogody.

W tym artykule omówimy drugą kategorię podejść. Będziemy omawiać różne formaty danych pogodowych, w jaki sposób można wykorzystać uczenie maszynowe do prognozowania pogody oraz w jaki sposób opracowane architektury mogą być korzystne w rozwiązywaniu podobnych problemów.

Dane do prognoz klimatycznych

Ponieważ podejścia wolne od fizyki wykorzystują dane historyczne, zacznijmy od przejrzenia dostępnych danych.

Będziemy korzystać z dwóch głównych źródeł danych:

  1. Dane obrazowe: Dane te mają postać zdjęć radarowych lub satelitarnych określonego obszaru geograficznego. Służy do przewidywania opadów, ruchu wiatru lub wilgotności.

Satellite Image

  1. Dane tabelaryczne: Dane te mają formę zapisów mierzalnych wielkości, takich jak temperatura, wilgotność czy prędkość wiatru.

Tabular Data

Chociaż oba źródła danych są ważne przy budowaniu wydajnych modeli, ze względu na prostotę skupimy się na tym pierwszym (dane obrazowe zebrane z radarów lub satelitów). Najpopularniejsze modele z danymi obrazu to konwolucyjne sieci neuronowe (CNN ).

Po tej pracy użyjemy architektury U-Net do zbudowania własnego modelu nowcastingu.

Architektura

Rozpoczęcie od istniejącej architektury jest pomocne z wielu powodów, między innymi:

Architektury służą jako wytyczne do tworzenia nowych modeli. Osoby tworzące nowe architektury stosują metodę prób i błędów, aby uzyskać ostateczne rezultaty. Wykorzystując ponownie ich ostateczne wyniki, możemy zaoszczędzić mnóstwo czasu.

Wstępnie przeszkolone modele są zwykle dostępne do natychmiastowego użycia. Kiedy badacze publikują swoje nowe architektury, zwykle publikują również wyszkolone parametry, dzięki czemu użytkownicy nie będą musieli zadawać sobie trudu uczenia/optymalizacji od zera. Jest to szczególnie przydatne w przypadku bardzo dużych, zasobożernych modeli.

Przykładowe znane architektury wizyjne obejmują:

  • LeNet (60 tys. parametrów)

LeNet

  • AlexNet (parametry 60m)

AlexNet

  • VGG-16 (parametry 138m)

VGG-16

Sieć U

U-Net to architektura oparta na sieci w pełni splotowej, co oznacza, że ​​nie posiada ona żadnych w pełni połączonych warstw. Po raz pierwszy wprowadzono go do zadania segmentacji obrazu medycznego. Wyniki te zainspirowały badaczy do rozszerzenia go na inne zadania związane z widzeniem komputerowym.

W 2019 roku Google wykorzystał architekturę opartą na sieci U-Net, aby utworzyć model prognozowania opadów.

Nazwa „U-Net” pochodzi od kształtu litery „U” w architekturze.

U-net Architecture

Wyróżniamy trzy główne elementy:

  1. Kontraktowanie / Koder: Następstwo warstw splotu/łączenia, które kompresują obraz wejściowy do reprezentacji o mniejszym rozmiarze.

  2. Mostek/wąskie gardło: Dolna część litery „U” łączy koder z dekoderem. Powstaje w wyniku szeregu operacji splotu.

  3. Dekontraktowanie / Dekoder: Następstwo splotów w górę i warstw splotu, które „dekompresują” sygnał wyjściowy wąskiego gardła.

Architektura sieci U-Net na razie przypomina automatyczny koder. Różnica polega jednak na przekazywaniu informacji pomiędzy koderem i dekoderem. Informacje te są przekazywane poprzez połączenie wyników splotów z kodera z wynikami splotu w górę dekodera. Ta modyfikacja zwiększa rozdzielczość i pozwala na uzyskanie przez model bardziej precyzyjnych przestrzennie wyników (lokalizacja pikseli na wyjściu będzie dokładniejsza, co rozwiąże problem, który występował w modelach, które nie uwzględniały łączenia). Łączenie odbywa się symetrycznie.

Budowa modelu U-Net do prognozowania opadów

W tej sekcji zbudujemy model U-Net do przewidywania pogody na podstawie zdjęć satelitarnych. Będziemy używać wstępnie wytrenowanego modelu o nazwie Rain-Net.

Poniższy kod jest dostępny w tym colabie.

Najpierw instalujemy wradlib, bibliotekę open source do przetwarzania danych z radarów pogodowych

!pip install wradlib
import wradlib as wrl

Następnie piszemy dwie funkcje narzędziowe do pobierania danych satelitarnych z otwartego serwera danych DWD


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

Narzędzia te pozwalają nam pobrać najnowsze 4 zdjęcia satelitarne, czyli liczbę zdjęć satelitarnych potrzebnych do przewidywania za pomocą naszego wstępnie wyszkolonego modelu.

Możemy następnie skorzystać z utworzonych funkcji, aby uzyskać 4 najnowsze obrazy


RY_latest, RY_latest_timestep = download_data()

Po pobraniu obrazów używamy metody vis.plot_ppi wradlib do wykreślenia danych

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

VIS Radar

Załadowaliśmy teraz nasze dane. Następnie załadujmy model.

Zaczynamy od zaimportowania odpowiednich klas. W tym artykule będziemy używać TensorFlow.

z tensorflow.keras.layers importuj dane wejściowe, Conv2D, aktywacja, łączenie, Conv2DTranspose, MaxPool2D

z tensorflow.keras.models importuj model

Zbudujmy 3 prymitywne klocki. Te „cegiełki” zostaną użyte do stworzenia całej architektury zgodnie z tą implementacją.

Pierwszy blok odpowiada kolejności warstw splotowych, nazywamy go „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

Drugi blok służy do zbudowania części kodera (blok splotowy + maksymalne łączenie). Nazywamy to „blokiem kodera”

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

Trzeci i ostatni blok to „dekoder_blok” (splatanie w górę + konkatenacja + splot).

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

Łączymy te elementy, aby skonstruować model 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

Możesz pobawić się wdrożeniem, ulepszyć je lub dostosować do swoich potrzeb, jeśli chcesz wykorzystać je do czegoś innego.

Trenowanie tego modelu może zająć dużo czasu. Na szczęście istnieje model o nazwie Rain-Net, który został stworzony w oparciu o architekturę U-Net i specjalizuje się w prognozowaniu opadów.

Sklonujmy jego repozytorium GitHub

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

Następnie pobieramy wstępnie wytrenowane ciężary dla tego modelu

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

Następnym krokiem jest utworzenie modelu w oparciu o architekturę znalezioną w repozytorium, a następnie załadowanie pobranych do tego modelu wag

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

Pobrane przez nas obrazy mają rozmiar 900*900 pikseli. Zamierzamy przekształcić te obrazy, aby odpowiadały oczekiwanym wkładom 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

Następnie tworzymy funkcję, która dokonuje prognoz.

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

Następnie wywołujemy tę funkcję na danych, które pobraliśmy wcześniej

Y_pred = prediction(model, RY_latest)

Możemy wykreślić przewidywania i zapisać je, aby wykorzystać zapisane wyniki do stworzenia obrazu GIF, który pozwala nam wizualizować przewidywania

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

Gratulacje, że dotarłeś tak daleko! Możesz teraz używać Rain-Net do prognozowania i wizualizacji ich.

Wniosek

W tym artykule wykorzystaliśmy model uczenia maszynowego (Rain-Net) do prognozowania opadów. Wykorzystaliśmy architekturę U-Net, którą zbudowaliśmy przy użyciu TensorFlow. Załadowaliśmy wstępnie wyszkolony model do przewidywania zdjęć satelitarnych.

Implementację tę można ulepszyć na wiele sposobów. Na przykład:

  1. Dostosuj model w zestawie danych

  2. Użyj w architekturze modułu opartego na uwadze, takiego jak CBAM (Convolutional Block Attention Module).

Bibliografia

Colab

Oryginalny dokument U-Net

Blog Google na temat modelu przewidywania pogody opartego na sieci U-Net

Przyjdź na jeden z naszych bezpłatnych warsztatów!

Rozpocznij karierę jako analityk danych dzięki naszym bezpłatnym warsztatom, które opierają się na elastycznym programie nauczania i są prowadzone przez ekspertów branżowych.


Career Services background pattern

Usługi związane z karierą

Contact Section background image

Pozostańmy w kontakcie

Code Labs Academy © 2024 Wszelkie prawa zastrzeżone.