Прогноз опадів за допомогою машинного навчання

ML
DL
CNN
Прогноз погоди
UNet
Прогноз опадів за допомогою машинного навчання cover image

Сьогодні метеорологи вважають, що 90% прогнозів погоди є правильними протягом 5 днів. Прогнози, які робляться, зазвичай базуються на двох окремих методах:

  1. Підходи, засновані на фізиці: ці підходи використовують моделі, які об’єднують вимірювані величини, такі як тиск, рух хмар, стан неба… Такі моделі добре прогнозують погоду на найближчі дні або тижні.

  2. Підходи без фізики (на основі даних): ці підходи використовують історичні дані для створення моделей, які можуть робити прогнози. Такі моделі показують хороші результати в прогнозуванні погоди на термін до 6 годин або так звані прогноз погоди.

У цій статті ми обговоримо другу категорію підходів. Ми обговоримо різні формати даних про погоду, як можна використовувати машинне навчання для прогнозування погоди та як розроблені архітектури можуть бути корисними для вирішення подібних проблем.

Дані для прогнозування клімату

Оскільки підходи без фізики використовують історичні дані, давайте почнемо з вивчення наявних даних.

Ми будемо використовувати два основних джерела даних:

  1. Дані зображення: ці дані приймають форму радіолокаційних або супутникових зображень певної географічної області. Він використовується для прогнозування опадів, руху вітру або вологості.

Satellite Image

  1. Табличні дані: ці дані мають форму записів вимірних величин, таких як температура, вологість або швидкість вітру.

Tabular Data

Хоча обидва джерела даних важливі для створення потужних моделей, ми зосередимося на першому (дані зображення, зібрані з радарів або супутників) з міркувань простоти. Найпоширенішими моделями із зображеннями є конволюційні нейронні мережі (CNN ).

Після цієї роботи ми збираємося використовувати архітектуру U-Net, щоб побудувати нашу власну модель поточної прогнозу.

Архітектура

Починати з існуючої архітектури корисно з багатьох причин, серед яких:

Архітектури служать орієнтирами для створення нових моделей. Люди, які створюють нові архітектури, використовують підхід проб і помилок, щоб досягти кінцевих результатів. Повторно використовуючи їхні кінцеві результати, ми можемо заощадити багато часу.

Попередньо підготовлені моделі зазвичай доступні для негайного використання. Коли дослідники публікують свої нові архітектури, вони зазвичай також публікують навчені параметри, щоб користувачам не доводилося мучитися з навчанням/оптимізацією з нуля. Це особливо корисно для дуже великих моделей, які потребують ресурсів.

Приклади відомих архітектур бачення включають:

  • LeNet (60k параметрів)

LeNet

  • AlexNet (параметри 60м)

AlexNet

  • ВГГ-16 (параметри 138м)

VGG-16

U-Net

U-Net — це архітектура, заснована на повністю згортковій мережі, тобто в ній немає повноцінно зв’язаних рівнів. Вперше його було введено для завдання сегментації медичних зображень. Ці результати надихнули дослідників поширити його на інші завдання комп’ютерного зору.

У 2019 році Google використав архітектуру на основі U-Net, щоб створити модель прогнозування опадів.

Назва «U-Net» походить від «U» форми його архітектури.

U-net Architecture

Ми виділяємо три основні компоненти:

  1. Згортання/кодер: послідовність шарів згортки/об’єднання, які стискають вхідне зображення до представлення меншого розміру.

  2. Міст/вузьке місце: нижня частина «U» з’єднує кодер із декодером. Він формується серією операцій згортки.

  3. Деконтрактування/декодер: послідовність згорток угору та шарів згортки, які «розпаковують» вихід вузького місця.

Архітектура U-Net поки що виглядає як автоматичний кодер. Однак різниця полягає в інформації, що передається між кодером і декодером. Ця інформація передається шляхом конкатенації результатів згортки від кодера з результатами згортки вгору декодера. Ця модифікація покращує роздільну здатність і дозволяє моделі виводити просторово точніші результати (розташування пікселів у виводі буде більш точним, вирішуючи проблему, яка виникала в моделях, які не включали конкатенацію). З’єднання виконується симетрично.

Побудова моделі U-Net для прогнозу опадів

У цьому розділі ми створимо модель U-Net для прогнозування погоди за супутниковими знімками. Ми будемо використовувати попередньо навчену модель під назвою Rain-Net.

Наведений нижче код доступний у цій colab.

Спочатку ми встановлюємо wradlib, бібліотеку з відкритим кодом для обробки даних метеорологічних радарів

!pip install wradlib
import wradlib as wrl

Потім ми пишемо дві службові функції для завантаження супутникових даних із сервера відкритих даних 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

Ці утиліти дозволяють нам завантажувати останні 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 імпорт моделі

Давайте побудуємо 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» (згортка вгору + конкатенація + згортка).

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 (Модуль згорткового блоку уваги).

Посилання

Colab

Блог Google про їхню модель прогнозування погоди на основі U-Net

Приходьте на один із наших безкоштовних майстер-класів!

Розпочніть свою кар’єру спеціаліста з даних із наших безкоштовних семінарів, які базуються на адаптованій навчальній програмі та проводяться експертами галузі.


Career Services background pattern

Кар'єрні послуги

Contact Section background image

Давайте залишатися на зв'язку

Code Labs Academy © 2024 Всі права захищені.