[PYTHON] Vorhersage von Wolkenbildern mit convLSTM

Einführung

In diesem Artikel möchte ich Bilder als Zeitreihendaten verwenden und Faltungs-LSTM verwenden, um zukünftige Bilder vorherzusagen. Ich dachte, dass convLSTM nur wenige Artikel und Implementierungsbeispiele enthält (möglicherweise weil es nicht korrekt ist), daher möchte ich es veröffentlichen, obwohl es sich um einen Schnellcode handelt. Da es sich um die Hauptimplementierung handelt, denke ich, dass Folding Lstm detailliert über die Struktur von convLSTM informiert ist.

Bibliothek laden


import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from sklearn.model_selection import train_test_split
import glob
from PIL import Image
from tqdm import tqdm
import zipfile
import io

Bild verwendet

Das verwendete Bild war das im vorherigen Artikel verwendete Satellitenbild (ich habe eine Clusteranalyse der Wetterkarte versucht). Es gab jedoch einen Wettbewerb wie diesen [SOTA] Weather Challenge: Vorhersage von Wolkenbildern, daher halte ich es für zweckmäßig, diesen Datensatz zu verwenden und dabei die Regeln zu beachten. .. In diesem Artikel betrachten wir ein Modell, das das Bild des nächsten Tages aus 5 Bildern alle 24 Stunden vorhersagt.

Bilder laden

Dieser Code wurde auf Google Colab ausgeführt, daher wird das Bild als Zip-Datei angegeben. Daher muss es dekomprimiert werden. Da das Originalbild sehr groß ist, wird die Bildgröße der Einfachheit halber reduziert.



#Bildgröße nach Verkleinerung
height = 100
width = 180

#Array zum Einfügen des geladenen Bildes
imgs=np.empty((0, height, width, 3))

#Lesen Sie eine Zip-Datei in ein Numpy-Array
zip_f = zipfile.ZipFile('drive/My Drive/Colab Notebooks/convLSTM/wide.zip')
for name in tqdm(zip_f.namelist()):
    with zip_f.open(name) as file:
        path = io.BytesIO(file.read()) #Auftauen
        img = Image.open(path)
        img = img.resize((width, height))
        img_np = np.array(img).reshape(1, height, width, 3)
        imgs = np.append(imgs, img_np, axis=0)

Datenformung

So wie es ist, werden die Daten einfach so ausgerichtet, wie sie sind. Machen Sie sie zu einem Formular, das als Zeitreihendaten verarbeitet werden kann. Die Größe ist x (Anzahl der Abtastwerte, Länge, Höhe, Breite, Anzahl der Kanäle der Zeitreihen) und y (Anzahl der Abtastwerte, Höhe, Breite, Anzahl der Kanäle).


#Ordnen Sie in einem Format, das in chronologischer Reihenfolge gelernt werden kann
n_seq = 5
n_sample = imgs.shape[0] - n_seq

x = np.zeros((n_sample, n_seq, height, width, 3))
y = np.zeros((n_sample, height, width, 3))
for i in range(n_sample):
    x[i] = imgs[i:i+n_seq]
    y[i] = imgs[i+n_seq]
x, y = (x-128)/128, (y-128)/128

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.1, shuffle = False)

Ein Modell bauen

Erstellen Sie ein Modell. Es ähnelt der Faltungsschicht, jedoch mit dem Zusatz "return_sequences" als Parameter. Dies ist, ob Zeitreihendaten erstellt und die Daten zurückgegeben werden sollen und nur die letzte convLSTM-Ebene auf False gesetzt wird. (Da ich beim Anpassen des Modells versucht habe, beispielsweise Shortcut Connection und Skip Conection zu verwenden, verwende ich die funktionale API, aber Sequential ist ausreichend.)


from keras import layers
from keras.layers.core import Activation
from tensorflow.keras.models import Model

inputs = layers.Input(shape=(5, height, width, 3))
x0 = layers.ConvLSTM2D(filters=16, kernel_size=(3,3), padding="same", return_sequences=True, data_format="channels_last")(inputs)
x0 = layers.BatchNormalization(momentum=0.6)(x0)
x0 = layers.ConvLSTM2D(filters=16, kernel_size=(3,3), padding="same", return_sequences=True, data_format="channels_last")(x0)
x0 = layers.BatchNormalization(momentum=0.8)(x0)

x0 = layers.ConvLSTM2D(filters=3, kernel_size=(3,3), padding="same", return_sequences=False, data_format="channels_last")(x0)
out = Activation('tanh')(x0)
model = Model(inputs=inputs, outputs=out)
model.summary()

Die Details des Modells sind so


Model: "functional_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 5, 100, 180, 3)]  0         
_________________________________________________________________
conv_lst_m2d (ConvLSTM2D)    (None, 5, 100, 180, 16)   11008     
_________________________________________________________________
batch_normalization (BatchNo (None, 5, 100, 180, 16)   64        
_________________________________________________________________
conv_lst_m2d_1 (ConvLSTM2D)  (None, 5, 100, 180, 16)   18496     
_________________________________________________________________
batch_normalization_1 (Batch (None, 5, 100, 180, 16)   64        
_________________________________________________________________
conv_lst_m2d_2 (ConvLSTM2D)  (None, 100, 180, 3)       2064      
_________________________________________________________________
activation (Activation)      (None, 100, 180, 3)       0         
=================================================================
Total params: 31,696
Trainable params: 31,632
Non-trainable params: 64

Lass uns lernen. Im Fall von colab wird die Speicherauslastung überschritten, wenn die Stapelgröße erhöht wird, sodass sie verringert wird. (Ich möchte eine sehr leistungsstarke Maschine kaufen und sie lokal betreiben können ...)


model.compile(optimizer='rmsprop',
              loss='mae', metrics=['mse'])
call_backs=[EarlyStopping(monitor="val_loss",patience=5)]
model.fit(x_train, y_train, batch_size=16, epochs=100, verbose=2, validation_split=0.2, shuffle=True, callbacks=call_backs)

Der laufende Verlust sieht so aus. image.png Es fühlt sich nicht sehr gut an ...

Lassen Sie uns das Ausführungsergebnis in der Abbildung anzeigen.


#Zeichnung
%matplotlib inline
i=15
fig, axes = plt.subplots(1, 2, figsize=(12,6))
axes[0].imshow((y_test[i]+1)/2)
axes[1].imshow((model.predict(x_test[[i]]).reshape(100,180,3)+1)/2)

Das richtige Bild und das vorhergesagte Bild werden nebeneinander angezeigt. i=0 image.png i=20 image.png

Bei Betrachtung dieses Ergebnisses stellte sich heraus, dass es sehr vage war. Dies kann auf die Tatsache zurückzuführen sein, dass Unschärfe im Durchschnitt zu höheren Punktzahlen führt als eindeutige Ergebnisse. Ich denke, es besteht die Möglichkeit, dass es verbessert werden kann, indem die Verlustfunktion auf eine andere geändert wird oder indem das Bild einige Stunden später vorhergesagt wird, was wahrscheinlich eine genauere Vorhersage ergibt.

Entwicklung

Es wurde ein Wettbewerb zur Vorhersage von Cloud-Bildern ähnlich diesem Artikel veranstaltet, und viele Bemühungen zur Verbesserung der Genauigkeit werden hilfreich sein. Obwohl es in Chainer implementiert ist, gibt es im Forum Beispielcode, daher denke ich, dass es hilfreich sein wird.

Verweise

Recommended Posts

Vorhersage von Wolkenbildern mit convLSTM
Bildsegmentierung mit U-Net
Versuchen Sie es mit Jupyters Docker-Image
Generieren Sie ein Docker-Image mit Fabric
Drucken Sie PDF mit Google Cloud Print. (GoogleAPI)
Bilderfassung von Firefox mit Python
[Python] Verwenden von OpenCV mit Python (Bildfilterung)
Beurteilung des hintergrundbeleuchteten Bildes mit OpenCV
Geotag-Vorhersage aus Bildern mit DNN
[Python] Verwenden von OpenCV mit Python (Bildtransformation)
Verwenden von Cloud-Speicher aus Python3 (Einführung)
Umweltfreundliches Scraping mit Bildverarbeitung
[FSL] Bildmessung mit ROI (VOI)
Binarisierung von Bildern mittels linearer Diskriminanzanalyse
Bilderkennung von Früchten mit VGG16
100 Sprachverarbeitung Knock-74 (mit Scicit-Learn): Vorhersage