Nowcasting Curah Hujan dengan Machine Learning

ML
DL
CNN
Prediksi Cuaca
UNet
Nowcasting Curah Hujan dengan Machine Learning cover image

Saat ini, ahli meteorologi memperkirakan 90% prediksi cuaca benar dalam rentang 5 hari. Prediksi yang dibuat biasanya didasarkan pada dua metode terpisah :

  1. Pendekatan berbasis fisika: Pendekatan ini menggunakan model yang mengintegrasikan besaran terukur seperti tekanan, pergerakan awan, kondisi langit… Model seperti ini bagus dalam memprediksi cuaca untuk beberapa hari atau minggu mendatang.

  2. Pendekatan bebas fisika (berbasis data): Pendekatan ini menggunakan data historis untuk membuat model yang dapat membuat prediksi. Model seperti ini menunjukkan hasil yang baik dalam memprediksi cuaca hingga 6 jam atau disebut dengan Weather Nowcasting.

Pada artikel ini, kita akan membahas pendekatan kategori kedua. Kita akan membahas berbagai format data cuaca, bagaimana pembelajaran mesin dapat dimanfaatkan untuk melakukan peramalan cuaca, dan bagaimana arsitektur yang dikembangkan dapat bermanfaat untuk memecahkan masalah serupa.

Data untuk Prediksi Iklim

Karena pendekatan bebas fisika menggunakan data historis, mari kita mulai dengan melihat data yang tersedia.

Kami akan menggunakan dua sumber data utama:

  1. Data gambar: Data ini berupa citra radar atau satelit dari wilayah geografis tertentu. Ini digunakan untuk memprediksi curah hujan, pergerakan angin, atau kelembapan.

Satellite Image

  1. Data tabular : Data ini berupa catatan besaran-besaran yang dapat diukur seperti suhu, kelembaban atau kecepatan angin.

Tabular Data

Meskipun kedua sumber data tersebut penting untuk membangun model yang kuat, kami akan fokus pada sumber data sebelumnya (data gambar yang dikumpulkan dari radar atau satelit) untuk alasan kesederhanaan. Model dengan data gambar yang paling umum digunakan adalah Convolutional Neural Networks (CNNs ).

Setelah [pekerjaan] ini(https://arxiv.org/pdf/1807.06521.pdf), kami akan menggunakan arsitektur U-Net untuk membangun model nowcasting kami sendiri.

Arsitektur

Memulai dari arsitektur yang sudah ada bermanfaat karena berbagai alasan, di antaranya:

Arsitektur berfungsi sebagai pedoman untuk menciptakan model-model baru. Orang-orang yang membuat arsitektur baru mengadopsi pendekatan coba-coba untuk mencapai hasil akhir. Dengan menggunakan kembali hasil akhirnya, kita dapat menghemat banyak waktu.

Model yang telah dilatih sebelumnya biasanya tersedia untuk segera digunakan. Saat peneliti memublikasikan arsitektur barunya, mereka biasanya juga memublikasikan parameter yang dilatih, sehingga pengguna tidak perlu bersusah payah melakukan pelatihan/pengoptimalan dari awal. Hal ini sangat berguna terutama untuk model yang sangat besar dan haus sumber daya.

Contoh arsitektur visi terkenal meliputi:

  • LeNet (parameter 60k)

LeNet

  • AlexNet (parameter 60m)

AlexNet

  • VGG-16 (parameter 138m)

VGG-16

U-Net

U-Net adalah arsitektur yang didasarkan pada jaringan yang sepenuhnya konvolusional, artinya jaringan tersebut tidak memiliki lapisan yang terhubung sepenuhnya. Ini pertama kali diperkenalkan untuk tugas segmentasi citra medis. Hasil ini menginspirasi para peneliti untuk memperluasnya ke tugas lain dalam visi komputer.

Pada tahun 2019, Google menggunakan arsitektur berbasis U-Net untuk membuat model perkiraan curah hujan.

Nama “U-Net” berasal dari bentuk arsitektur “U”.

U-net Architecture

Kami mengidentifikasi tiga komponen utama:

  1. Kontraktor / Encoder: Suksesi lapisan konvolusi/penggabungan yang memampatkan gambar masukan menjadi representasi ukuran yang lebih kecil.

  2. Bridge / Bottleneck: Bagian bawah huruf “U” menghubungkan encoder ke decoder. Itu dibentuk oleh serangkaian operasi konvolusi.

  3. Dekontrak / Decoder : Suksesi lapisan konvolusi dan konvolusi, yang “mendekompresi” keluaran dari kemacetan.

Arsitektur U-Net sejauh ini terlihat seperti auto-encoder. Namun perbedaannya terletak pada penyampaian informasi antara encoder dan decoder. Informasi ini diteruskan dengan menggabungkan hasil konvolusi dari encoder dengan hasil konvolusi atas decoder. Modifikasi ini meningkatkan resolusi, dan memungkinkan model mengeluarkan keluaran yang lebih presisi secara spasial (lokasi piksel dalam keluaran akan lebih tepat, sehingga memecahkan masalah yang terjadi pada model yang tidak menyertakan penggabungan). Penggabungan dilakukan secara simetris.

Membangun Model U-Net untuk Penyiaran Curah Hujan

Pada bagian ini, kita akan membangun model U-Net untuk memprediksi cuaca dari citra satelit. Kami akan menggunakan model terlatih yang disebut Rain-Net.

Kode di bawah tersedia di [colab] ini(https://arxiv.org/abs/1505.04597).

Pertama-tama kami menginstal wradlib, sebuah Perpustakaan Sumber Terbuka untuk Pemrosesan Data Radar Cuaca

!pip install wradlib
import wradlib as wrl

Kami kemudian menulis dua fungsi utilitas untuk mengunduh data satelit dari server data terbuka 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

Utilitas ini memungkinkan kita mengunduh 4 citra satelit terbaru, yang merupakan jumlah citra satelit yang kita perlukan untuk membuat prediksi dengan model yang telah kita latih sebelumnya.

Kita kemudian dapat menggunakan fungsi yang dibuat untuk mendapatkan 4 gambar terbaru


RY_latest, RY_latest_timestep = download_data()

Setelah mendapatkan gambar, kami menggunakan metode vis.plot_ppi wradlib untuk memplot data

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

VIS Radar

Kami sekarang telah memuat data kami. Selanjutnya mari kita memuat modelnya.

Kami mulai dengan mengimpor kelas yang relevan. Kami akan menggunakan TensorFlow di artikel ini.

dari tensorflow.keras.layers impor Input, Conv2D, Aktivasi, Concatenate, Conv2DTranspose, MaxPool2D

dari tensorflow.keras.models impor Model

Mari kita membangun 3 blok bangunan primitif. "Blok penyusun" ini akan digunakan untuk membuat keseluruhan arsitektur, sesuai dengan [implementasi] ini(https://github.com/bnsreenu/python_for_microscopists/blob/master/219-unet_model_with_functions_of_blocks.py).

Blok pertama berhubungan dengan suksesi lapisan konvolusional, kami menyebutnya "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

Blok kedua digunakan untuk membangun dari bagian encoder (blok konvolusional + max pooling). Kami menyebutnya “encoder_block”

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

Blok ketiga dan terakhir adalah “decoder_block” (konvolusi + penggabungan + konvolusi).

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

Kami menggabungkan elemen-elemen ini untuk membangun 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

Jangan ragu untuk bermain-main dengan penerapannya, memperbaikinya, atau menyesuaikannya dengan kebutuhan Anda jika Anda ingin menggunakannya untuk hal lain.

Melatih model ini bisa memakan banyak waktu. Untungnya, ada model bernama Rain-Net, yang dibuat berdasarkan arsitektur U-Net, dan khusus dalam penyiapan curah hujan.

Mari kita kloning repositori GitHub-nya

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

Kami kemudian mengunduh bobot yang telah dilatih sebelumnya untuk model ini

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

Langkah selanjutnya adalah membuat model berdasarkan arsitektur yang terdapat pada repositori kemudian memuat bobot yang diunduh ke model ini

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

Gambar yang kami unduh memiliki ukuran 900*900 piksel. Kami akan membentuk ulang gambar-gambar ini agar sesuai dengan masukan yang diharapkan dari 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

Kami kemudian membuat fungsi yang membuat prediksi.

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

Kami kemudian memanggil fungsi ini pada data yang kami unduh sebelumnya

Y_pred = prediction(model, RY_latest)

Kita dapat memplot prediksi, dan menyimpannya untuk menggunakan hasil yang disimpan untuk membuat gambar gif yang memungkinkan kita memvisualisasikan prediksi

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

Selamat telah berhasil sejauh ini! Anda sekarang dapat menggunakan Rain-Net untuk membuat prediksi dan memvisualisasikannya.

Kesimpulan

Pada artikel ini, kami telah menggunakan model pembelajaran mesin (Rain-Net) untuk melakukan pengecoran curah hujan. Kami menggunakan arsitektur U-Net, yang kami buat menggunakan TensorFlow. Kami memuat model terlatih untuk memprediksi citra satelit.

Implementasi ini dapat ditingkatkan dalam banyak cara. Misalnya:

  1. Sempurnakan model pada kumpulan data Anda

  2. Gunakan modul berbasis perhatian, seperti CBAM (Convolutional Block Attention Module) dalam arsitektur.

Referensi

Datanglah ke Salah Satu Lokakarya Gratis Kami!

Mulailah karir Anda sebagai data scientist dengan lokakarya gratis, yang didasarkan pada kurikulum yang dapat disesuaikan dan dipandu oleh pakar industri.


Career Services background pattern

Layanan Karir

Contact Section background image

Mari tetap berhubungan

Code Labs Academy © 2024 Semua hak dilindungi undang-undang.