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.
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
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.
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)
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)
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. 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 i=20
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.
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.
Recommended Posts