[PYTHON] Rekursive neuronale Netze untersuchen: Können Sie periodische Funktionen reproduzieren?

Beim tiefen Lernen habe ich versucht zu sehen, wie viel die periodische Funktion reproduziert werden kann, um das wiederkehrende neuronale Netzwerk zu untersuchen, das für die Analyse von Zeitreihendaten verwendet wird.

Definition von drei Arten von periodischen Funktionen

Hier haben wir die folgenden drei Arten von periodischen Funktionen definiert: f`` g`` h.

import numpy as np

def f(t, freq=25):
    return np.sin(2. * np.pi * t / freq)

def g(t, freq=25, amp=10, threshold = 10):
    return 1/(1 + np.exp(10 * np.sin(2 * np.pi * t / freq) + 10))

def h(t, freqs=[11, 23, 31, 41, 53, 61, 71, 83, 97]):
    value = np.zeros_like(t)
    for freq in freqs:
        value += f(t, freq)
    return value

Funktion f

Die Funktion f ist eine Dreiecksfunktion $ sin $. Hier ist der Zeitraum auf 25 $ festgelegt.

%matplotlib inline
import matplotlib.pyplot as plt

total_time_length = 1000
times = np.linspace(0, total_time_length, total_time_length + 1)

plt.figure(figsize=(15, 6))
plt.plot(f(times))
plt.xticks(np.linspace(0, 1000, 11))
plt.grid()

output_2_0.png

Funktion g

Die Funktion g transformiert die Dreiecksfunktion $ sin $ mit einer Sigmoidfunktion in eine seltsame Form. Wieder habe ich den Zyklus auf 25 $ gesetzt.

%matplotlib inline
import matplotlib.pyplot as plt

total_time_length = 1000
times = np.linspace(0, total_time_length, total_time_length + 1)

plt.figure(figsize=(15, 6))
plt.plot(g(times))
plt.xticks(np.linspace(0, 1000, 11))
plt.grid()

output_3_0.png

Funktion h

Die Funktion h ist die Summe der Dreiecksfunktionen $ sin $, deren Periode mehrere Primzahlen ist.

%matplotlib inline
import matplotlib.pyplot as plt

total_time_length = 1000
times = np.linspace(0, total_time_length, total_time_length + 1)

plt.figure(figsize=(15, 6))
plt.plot(h(times))
plt.xticks(np.linspace(0, 1000, 11))
plt.grid()

output_4_0.png

Können diese Funktionen in einem rekursiven neuronalen Netzwerk reproduziert werden?

Fourier-Transformation

Bevor wir das rekursive neuronale Netzwerk verwenden, konvertieren wir die obigen drei Funktionen durch Fourier-Transformation in Frequenzen und nehmen die inverse Zahl, um die "Periode" zu überprüfen.

plt.figure(figsize=(6,6))

sp = np.fft.fft(f(times))
freq = np.fft.fftfreq(times.shape[-1])

plt.subplot(311)
plt.plot(1/freq, abs(sp.real) + abs(sp.imag), label="f")
plt.plot(1/freq, abs(sp.real))
plt.plot(1/freq, abs(sp.imag), alpha=0.5)
plt.legend()
plt.xlim([0, 150])
plt.xticks(np.linspace(0, 150, 16))
plt.grid()

sp = np.fft.fft(g(times))
freq = np.fft.fftfreq(times.shape[-1])

plt.subplot(312)
plt.plot(1/freq, abs(sp.real) + abs(sp.imag), label="g")
plt.plot(1/freq, abs(sp.real))
plt.plot(1/freq, abs(sp.imag), alpha=0.5)
plt.legend()
plt.xlim([0, 150])
plt.xticks(np.linspace(0, 150, 16))
plt.grid()

sp = np.fft.fft(h(times))
freq = np.fft.fftfreq(times.shape[-1])

plt.subplot(313)
plt.plot(1/freq, abs(sp.real) + abs(sp.imag), label="h")
plt.plot(1/freq, abs(sp.real))
plt.plot(1/freq, abs(sp.imag), alpha=0.5)
plt.legend()
plt.xlim([0, 150])
plt.xticks(np.linspace(0, 150, 16))
plt.grid()

output_6_1.png

Die Funktion f besteht nur aus Sinuswellen mit einer Periode von $ 25 $. Sie sehen, dass die Funktion h aus einer Kombination von Perioden der angegebenen Primzahlen besteht. Auf der anderen Seite können Sie sehen, dass die Funktion g verschiedene andere Komponenten als den angegebenen Zeitraum von $ 25 $ enthält.

Erstellen eines Zeitreihendatensatzes

Erstellen wir nun einen Zeitreihendatensatz, um ein rekursives neuronales Netzwerk zu trainieren. Wenn Sie in einem rekursiven neuronalen Netzwerk die Ausgabe $ X_ {t, t + w} $ vom Zeitpunkt $ t $ bis $ t + w $ eingeben, wird die Ausgabe $ X_ {t + w + 1} $ beim nächsten Mal vorhergesagt. Ziel ist es, ein Modell zu erstellen.

import numpy as np
from sklearn.model_selection import train_test_split

func = f #Sie können die Funktion ändern, indem Sie hier neu schreiben
#func = g
#func = h

total_time_length = 10000 #Alle Zeitbreiten zu handhaben
pred_length = 1000 #Voraussichtliche Zeitbreite
learning_time_length = 100 #Zeitbreite zum Lernen

time_series_T = np.linspace(0, total_time_length, total_time_length + 1) #Gravieren Sie die vorhergesagte Zeit T (entsprechend der horizontalen Achse des Diagramms).
time_series_X = func(time_series_T) #Funktionsausgang X (entspricht der vertikalen Achse des Graphen)

X_learn = [] #Zeit t ~ t+learning_time_Speichert X bis zur Länge
Y_learn = [] #Zeit t+learning_time_length+Speichern Sie 1 X.
for i in range(total_time_length - learning_time_length):
    X_learn.append(time_series_X[i:i+learning_time_length].reshape(1, learning_time_length).T)
    Y_learn.append([time_series_X[i+learning_time_length]])

#Unterteilt in Trainingsdaten und Verifizierungsdaten
#Mischen für Zeitreihendaten=Muss falsch sein
X_train, X_val, Y_train, Y_val = \
train_test_split(X_learn, Y_learn, test_size=0.2, shuffle=False)

# scikit-Zum Lernen in Datentyp konvertieren
X_train2sklearn = [list(x.reshape(1, len(x))[0]) for x in X_train]
Y_train2sklearn = [y[0] for y in Y_train]

Deep-Learning-Methode

MLP (Multi-Layer Perceptron)

Zum Vergleich verwenden wir Multi-Layer Perceptron (MLP), das einfachste Modell für tiefes Lernen. Ich habe das mehrschichtige Perceptron verwendet, weil Scikit-Lernen einfach und schnell ist.

%%time
from sklearn.neural_network import MLPRegressor
regressor = MLPRegressor(hidden_layer_sizes=(100, 100, 100), 
                         early_stopping=True, max_iter=10000) 
regressor.fit(X_train2sklearn, Y_train2sklearn) 
CPU times: user 2.84 s, sys: 1.41 s, total: 4.25 s
Wall time: 2.22 s

Die Lernkurve wurde wie folgt gezeichnet.

plt.plot(regressor.loss_curve_)
%matplotlib inline
import matplotlib.pyplot as plt
plt.subplot(211)
plt.plot(regressor.loss_curve_, label='train_loss')
plt.legend()
plt.grid()
plt.subplot(212)
plt.plot(regressor.loss_curve_, label='train_loss')
plt.yscale('log')
plt.legend()
plt.grid()

output_11_0.png

Geben Sie dem trainierten Modell die ersten Stunden (nur die Länge von "pred_length") als Eingabe, um die Ausgabe beim nächsten Mal vorherzusagen. Fügen Sie den vorhergesagten Wert der Ausgabe zur Eingabe hinzu, um die Ausgabe beim nächsten Mal vorherzusagen. Wiederholen Sie es endlos.

%%time
pred_length = 1000
X_pred_length = np.linspace(0, pred_length , pred_length + 1)
Y_observed = func(X_pred_length)
Y_pred = Y_observed[:learning_time_length+1]

for i in range(pred_length):
    X_ = [Y_pred[i:i+learning_time_length]]
    Y_ = regressor.predict(X_)
    Y_pred = np.append(Y_pred, Y_)
CPU times: user 383 ms, sys: 279 ms, total: 662 ms
Wall time: 351 ms

Die auf diese Weise erhaltene Kurve des vorhergesagten Wertes und die tatsächliche Kurve werden dargestellt und verglichen.

plt.figure(figsize=(36, 6))
times = np.linspace(0, Y_pred.shape[0] - 1, Y_pred.shape[0])
plt.plot(func(times), label="time series")
plt.plot(Y_pred, alpha=0.5, label="predicted")
plt.xticks(np.linspace(0, 1000, 11))
plt.xlim([0, 1000])
plt.grid()
plt.legend()

output_13_1.png

Wenn die Figur klein und schwer zu sehen ist, können Sie sie vergrößern, indem Sie darauf klicken. Bis zum Zeitpunkt $ 100 $ werden die Trainingsdaten so verwendet, wie sie sind, sodass sie übereinstimmen. Nach dem Zeitpunkt $ 100 $ können Sie jedoch sehen, dass sich der tatsächliche Wert (Wert der Funktion f) und der vorhergesagte Wert allmählich verschieben. ..

Vergleichen wir die Ergebnisse der Fourier-Transformation.

plt.figure(figsize=(6,4))

sp = np.fft.fft(func(times))
freq = np.fft.fftfreq(times.shape[-1])

plt.subplot(211)
plt.plot(1/freq, abs(sp.real) + abs(sp.imag), label="observed")
plt.plot(1/freq, abs(sp.real))
plt.plot(1/freq, abs(sp.imag), alpha=0.5)
plt.legend()
plt.xlim([0, 150])
plt.xticks(np.linspace(0, 150, 16))
plt.grid()

sp = np.fft.fft(Y_pred)
freq = np.fft.fftfreq(times.shape[-1])

plt.subplot(212)
plt.plot(1/freq, abs(sp.real) + abs(sp.imag), label="predicted")
plt.plot(1/freq, abs(sp.real))
plt.plot(1/freq, abs(sp.imag), alpha=0.5)
plt.legend()
plt.xlim([0, 150])
plt.xticks(np.linspace(0, 150, 16))
plt.grid()

output_14_1.png

Der vorhergesagte Zyklus liegt nahe am tatsächlichen Zyklus, scheint jedoch leicht abweichen zu können.

Rekursives neuronales Netzwerk

Bauen wir nun ein rekursives neuronales Netzwerk auf. Hier wird PyTorch verwendet, eine Bibliothek für tiefes Lernen.

Richten Sie zuerst das Gerät ein. Wenn Sie die GPU verwenden können, verwenden Sie die GPU, und wenn nicht, verwenden Sie die CPU wie folgt.

import torch
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

Bereiten Sie eine Funktion für EarlyStopping vor. Eine vorzeitige Beendigung ist der Prozess des Abbruchs des Lernens, wenn festgestellt wird, dass das Lernen nicht weitergeht.

Beim tiefen Lernen wird der Vorhersagefehler als Verlust bezeichnet. Um eine Überanpassung (auch als Überanpassung bezeichnet) zu verhindern, wird hier anstelle des "Verlusts" der Trainingsdaten das Lernen gestoppt, wenn beurteilt wird, dass der "Verlust" der nicht für das Training verwendeten Verifizierungsdaten nicht mehr abnimmt. .. Als Urteil führen wir das Konzept der "Geduld" ein. Wenn "Geduld = 20", vergleichen Sie den Mindestwert für "Verlust" von $ 20 $ in letzter Zeit mit dem Mindestwert für "Verlust" davor, und wenn ersterer größer ist, beurteilen Sie, dass "es nicht besser sein wird" und lernen Sie. Ich werde aufhören.

def EarlyStopping(log, patience=20):
    if len(log) <= patience:
        return False
    min1 = log[:len(log)-patience].min()
    min2 = log[len(log)-patience:].min()
    if min1 <= min2:
        return True
    else:
        return False

RNN(Recurrent Neural Network)

Es ist ein bisschen verwirrend, aber RNN (Recurrent Neural Network) hat "RNN im weitesten Sinne" und "RNN im engeren Sinne". RNN im engeren Sinne kann in PyTorch wie folgt implementiert werden.

import torch
class RNN(torch.nn.Module):
    def __init__(self, hidden_dim):
        super().__init__()
        self.l1 = torch.nn.RNN(1, hidden_dim,
                         nonlinearity='tanh',
                         batch_first=True)
        self.l2 = torch.nn.Linear(hidden_dim, 1)
        torch.nn.init.xavier_normal_(self.l1.weight_ih_l0)
        torch.nn.init.orthogonal_(self.l1.weight_hh_l0)

    def forward(self, x):
        h, _ = self.l1(x)
        y = self.l2(h[:, -1])
        return y

LSTM (Long Short-Term Memory)

LSTM (Long Short-Term Memory) ist entweder lang oder kurz! !! Es ist ein Name, der Lust macht, sich zu vertiefen, aber es ist eine Art "RNN im weitesten Sinne". Es wird gesagt, dass das Langzeitgedächtnis "RNN im engeren Sinne" überlegen ist. Sie können es in PyTorch wie folgt implementieren:

import torch
class LSTM(torch.nn.Module):
    def __init__(self, hidden_dim):
        super().__init__()
        self.l1 = torch.nn.LSTM(1, hidden_dim, batch_first=True)
        self.l2 = torch.nn.Linear(hidden_dim, 1)
        torch.nn.init.xavier_normal_(self.l1.weight_ih_l0)
        torch.nn.init.orthogonal_(self.l1.weight_hh_l0)

    def forward(self, x):
        h, _ = self.l1(x)
        y = self.l2(h[:, -1])
        return y

GRU (Gated Recurrent Unit)

Die GRU ist keine Glavnoye Razvedyvatelnoye Upravleniye, sondern eine Gated Recurrent Unit. Es wird gesagt, dass die Berechnungszeit kurz ist, während die gleiche oder eine bessere Leistung wie bei LSTM erzielt wird.

import torch
class GRU(torch.nn.Module):
    def __init__(self, hidden_dim):
        super().__init__()
        self.l1 = torch.nn.GRU(1, hidden_dim, batch_first=True)
        self.l2 = torch.nn.Linear(hidden_dim, 1)
        torch.nn.init.xavier_normal_(self.l1.weight_ih_l0)
        torch.nn.init.orthogonal_(self.l1.weight_hh_l0)

    def forward(self, x):
        h, _ = self.l1(x)
        y = self.l2(h[:, -1])
        return y

Lernausführung durch RNN

Ich habe wie folgt gelernt. Der folgende Code gilt für RNN. Sie können ihn jedoch in LSTM oder GRU ändern, indem Sie ihn an einer Stelle neu schreiben.

%%time
from sklearn.utils import shuffle
model = RNN(50).to(device) #Sie können das Netzwerk ändern, indem Sie hier neu schreiben
#model = LSTM(50).to(device)
#model = GRU(50).to(device)
criterion = torch.nn.MSELoss(reduction='mean')
optimizer = torch.optim.Adam(model.parameters(), lr=0.001, 
                            betas=(0.9, 0.999), amsgrad=True)

epochs = 1000
batch_size = 100
n_batches_train = len(X_train) // batch_size - 1
n_batches_test = len(X_val) // batch_size - 1
hist = {'train_loss':[], 'val_loss':[]}

for epoch in range(epochs):
    train_loss = 0.
    val_loss = 0.
    X_, Y_ = shuffle(X_train, Y_train)

    for batch in range(n_batches_train):
        start = batch * batch_size
        end = start + batch_size
        X = torch.Tensor(X_[start:end])
        Y = torch.Tensor(Y_[start:end])
        model.train()
        Y_pred = model(X)
        loss = criterion(Y, Y_pred)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        train_loss += loss.item()

    for batch in range(n_batches_test):
        start = batch * batch_size
        end = start + batch_size
        X = torch.Tensor(X_val[start:end])
        Y = torch.Tensor(Y_val[start:end])
        model.eval()
        Y_pred = model(X)
        loss = criterion(Y, Y_pred)
        val_loss += loss.item()
    
    train_loss /= n_batches_train
    val_loss /= n_batches_test
    hist['train_loss'].append(train_loss)
    hist['val_loss'].append(val_loss)
    print("Epoch:", epoch + 1, "Train loss:", train_loss, "Val loss:", val_loss)

    if EarlyStopping(np.array(hist['val_loss'])):
        print("Early stopping at epoch", epoch + 1)
        break
Epoch: 1 Train loss: 0.024917872337913975 Val loss: 6.828008190495893e-05
Epoch: 2 Train loss: 3.570798083110742e-05 Val loss: 3.464157634880394e-05
Epoch: 3 Train loss: 2.720728588638639e-05 Val loss: 1.954806430148892e-05
...
Epoch: 580 Train loss: 5.4337909078255436e-08 Val loss: 4.0113718569045886e-08
Epoch: 581 Train loss: 6.47745306281422e-08 Val loss: 5.6099906942108646e-08
Epoch: 582 Train loss: 5.797503896896836e-08 Val loss: 1.620698952820021e-07
Early stopping at epoch 582
CPU times: user 26min 9s, sys: 21.6 s, total: 26min 31s
Wall time: 26min 39s

Lernen ist vorbei. Gibt die Lernkurve aus.

%matplotlib inline
import matplotlib.pyplot as plt
plt.subplot(211)
plt.plot(hist['train_loss'], label='train_loss')
plt.plot(hist['val_loss'], label='val_loss')
plt.legend()
plt.grid()
plt.subplot(212)
plt.plot(hist['train_loss'], label='train_loss')
plt.plot(hist['val_loss'], label='val_loss')
plt.yscale('log')
plt.legend()
plt.grid()

output_27_0.png

Geben Sie dem trainierten Modell die ersten Stunden (nur die Länge von "pred_length") als Eingabe, um die Ausgabe beim nächsten Mal vorherzusagen. Fügen Sie den vorhergesagten Wert der Ausgabe zur Eingabe hinzu, um die Ausgabe beim nächsten Mal vorherzusagen. Wiederholen Sie es endlos.

%%time
total_time_length = 10000
pred_length = 1000
learning_time_length = 100

X_pred_length = np.linspace(0, pred_length , pred_length + 1)
Y_observed = func(X_pred_length)
Y_pred = Y_observed[:learning_time_length+1]

for i in range(pred_length):
    X_ = Y_pred[i:i+learning_time_length+1].reshape(1, learning_time_length + 1, 1)
    Y_ = model(torch.Tensor(X_)).detach().numpy()
    Y_pred = np.append(Y_pred, Y_)
CPU times: user 2.54 s, sys: 5.97 ms, total: 2.55 s
Wall time: 2.55 s

Die auf diese Weise erhaltene Kurve des vorhergesagten Wertes und die tatsächliche Kurve werden dargestellt und verglichen.

plt.figure(figsize=(36, 6))
times = np.linspace(0, Y_pred.shape[0] - 1, Y_pred.shape[0])
plt.plot(func(times), label="time series")
plt.plot(Y_pred, alpha=0.5, label="predicted")
plt.xticks(np.linspace(0, 1000, 11))
plt.xlim([0, 1000])
plt.grid()
plt.legend()

output_29_1.png

Wenn die Figur klein und schwer zu sehen ist, können Sie sie vergrößern, indem Sie darauf klicken. Bis zu einem Zeitpunkt von 100 $ werden die Trainingsdaten so verwendet, wie sie sind. Daher ist es natürlich, dass sie übereinstimmen. Nach 100 $ können Sie jedoch feststellen, dass sie perfekt übereinstimmen.

Vergleichen wir die Ergebnisse der Fourier-Transformation.

plt.figure(figsize=(6,4))

sp = np.fft.fft(func(times))
freq = np.fft.fftfreq(times.shape[-1])

plt.subplot(211)
plt.plot(1/freq, abs(sp.real) + abs(sp.imag), label="observed")
plt.plot(1/freq, abs(sp.real))
plt.plot(1/freq, abs(sp.imag), alpha=0.5)
plt.legend()
plt.xlim([0, 150])
plt.xticks(np.linspace(0, 150, 16))
plt.grid()

sp = np.fft.fft(Y_pred)
freq = np.fft.fftfreq(times.shape[-1])

plt.subplot(212)
plt.plot(1/freq, abs(sp.real) + abs(sp.imag), label="predicted")
plt.plot(1/freq, abs(sp.real))
plt.plot(1/freq, abs(sp.imag), alpha=0.5)
plt.legend()
plt.xlim([0, 150])
plt.xticks(np.linspace(0, 150, 16))
plt.grid()

output_30_1.png

Es scheint, dass die Zyklen genau gleich sind.

Lernausführung durch LSTM

Wie oben erwähnt, ersetzt das Lernen von LSTM einfach "model = RNN (50) .to (Gerät)" im obigen Code durch "model = LSTM (50) .to (Gerät)".

Epoch: 1 Train loss: 0.24947839844315192 Val loss: 0.0037629783619195223
Epoch: 2 Train loss: 0.0010665786028720248 Val loss: 0.0004544752591755241
Epoch: 3 Train loss: 0.000281030429528656 Val loss: 0.00014765093510504812
...
Epoch: 397 Train loss: 1.9865108783006072e-08 Val loss: 1.99065262052045e-08
Epoch: 398 Train loss: 1.840841412067617e-08 Val loss: 1.814414751777349e-08
Epoch: 399 Train loss: 1.7767042196444784e-08 Val loss: 1.9604467382805524e-08
Early stopping at epoch 399
CPU times: user 48min 40s, sys: 51.2 s, total: 49min 31s
Wall time: 49min 41s

output_33_0.png

CPU times: user 7.67 s, sys: 14 ms, total: 7.68 s
Wall time: 7.69 s

output_35_1.png

output_36_1.png

Es scheint, dass dies auch eine perfekte Vorhersage war.

Lernausführung durch GRU

Wie oben erwähnt, ersetzt das Lernen von GRU einfach "model = RNN (50) .to (Gerät)" im obigen Code durch "model = GRU (50) .to (Gerät)".

Epoch: 1 Train loss: 0.2067998453276232 Val loss: 0.0007729934877716005
Epoch: 2 Train loss: 0.0005770771786979495 Val loss: 0.00023205751494970173
Epoch: 3 Train loss: 0.00018625847849015816 Val loss: 0.00014329736586660147
...
Epoch: 315 Train loss: 5.816128262764026e-09 Val loss: 5.750611098420677e-09
Epoch: 316 Train loss: 5.757192062114896e-09 Val loss: 5.7092033323158375e-09
Epoch: 317 Train loss: 5.780735246610847e-09 Val loss: 5.6715170337895415e-09
Early stopping at epoch 317
CPU times: user 34min 51s, sys: 42.1 s, total: 35min 33s
Wall time: 35min 40s

output_39_0.png

CPU times: user 8.81 s, sys: 7.04 ms, total: 8.81 s
Wall time: 8.82 s

output_41_1.png

output_42_1.png

Es scheint, dass dies auch eine perfekte Vorhersage war.

Experimentieren Sie, um die Form und Periode einer Funktion zu ändern

Nachdem ich nun weiß, wie man es bewegt, experimentieren wir endlich mit der Änderung der Form und des Zeitraums der Funktion. Das Ergebnis ist wie folgt.

Erhöhen Sie die Funktionsdauer f

MLP, Funktion f

MLP, Funktion f, Periode = 25

Lernkurve

output_11_0.png

Vorhersagekurve

output_13_1.png

Fourier-Transformation

output_14_1.png

MLP, Funktion f, Periode = 50

Lernkurve

output_11_0.png

Vorhersagekurve

output_13_1.png

Fourier-Transformation

output_14_1.png

MLP, Funktion f, Periode = 100

Lernkurve

output_11_0.png

Vorhersagekurve

output_13_1.png

Fourier-Transformation

output_14_1.png

MLP, Funktion f Zusammenfassung

Selbst wenn der Zyklus groß wird, ändert sich die Anzahl der bis zum frühen Ende verbrachten Epochen nicht wesentlich. Die Form der Kurve kollabierte nicht signifikant, aber es gab eine Verschiebung im Zyklus. Die Ausgangshöhe (Amplitude) blieb erhalten, wenn die Periode kurz war, es wurde jedoch festgestellt, dass sie dazu neigte, abzunehmen, wenn die Periode länger wurde.

RNN, Funktion f

RNN, Funktion f, Periode = 25

Lernkurve

output_27_0.png

Vorhersagekurve

output_29_1.png

Fourier-Transformation

output_30_1.png

RNN, Funktion f, Periode = 50

Lernkurve

output_27_0.png

Vorhersagekurve

output_29_1.png

Fourier-Transformation

output_30_1.png

RNN, Funktion f, Periode = 100

Lernkurve

output_27_0.png

Vorhersagekurve

output_29_1.png

Fourier-Transformation

output_30_1.png

RNN, Funktion f Zusammenfassung

Die Anzahl der Epochen, die bis zum frühen Ende verbracht wurden, nahm tendenziell mit zunehmendem Zyklus ab. Die Vorhersagekurve machte gute Vorhersagen im kurzen Zyklus (25) oder mittleren Zyklus (50), verlor jedoch im langen Zyklus (100) ihre Form signifikant. Bei der Langzeitvorhersage wurde an einer seltsamen Stelle ein scharfer Peak beobachtet.

LSTM, Funktion f

LSTM, Funktion f, Periode = 25

Lernkurve

output_33_0.png

Vorhersagekurve

output_35_1.png

Fourier-Transformation

output_36_1.png

LSTM, Funktion f, Periode = 50

Lernkurve

output_33_0.png

Vorhersagekurve

output_35_1.png

Fourier-Transformation

output_36_1.png

LSTM, Funktion f, Periode = 100

Lernkurve

output_33_0.png

Vorhersagekurve

output_35_1.png

Fourier-Transformation

output_36_1.png

LSTM, Funktion f Zusammenfassung

Die Anzahl der vor der vorzeitigen Beendigung verbrachten Epochen kann mit längeren Zyklen (wenn auch unklar) abnehmen. Gute Vorhersagen wurden im gesamten kurzen Zyklus (25), mittleren Zyklus (50) und langen Zyklus (100) gemacht.

GRU, Funktion f

GRU, Funktion f, Periode = 25

Lernkurve

output_39_0.png

Vorhersagekurve

output_41_1.png

Fourier-Transformation

output_42_1.png

GRU, Funktion f, Periode = 50

Lernkurve

output_39_0.png

Vorhersagekurve

output_41_1.png

Fourier-Transformation

output_42_1.png

GRU, Funktion f, Periode = 100

Lernkurve

output_39_0.png

Vorhersagekurve

output_41_1.png

Fourier-Transformation

output_42_1.png

GRU, Funktion f

Ich habe gehört, dass GRU schneller als LSTM ist, aber die Anzahl der Epochen, die vor der vorzeitigen Beendigung verbracht wurden, war ziemlich lang (bis zu 1000 Epochen). Gute Vorhersagen wurden im gesamten kurzen Zyklus (25), mittleren Zyklus (50) und langen Zyklus (100) gemacht.

Erhöhen Sie die Funktionsdauer g

MLP, Funktion g

MLP, Funktion g, Periode = 25

Lernkurve

output_11_0.png

Vorhersagekurve

output_13_1.png

Fourier-Transformation

output_14_1.png

MLP, Funktion g, Periode = 50

Lernkurve

output_11_0.png

Vorhersagekurve

output_13_1.png

Fourier-Transformation

output_14_1.png

MLP, Funktion g, Periode = 100

Lernkurve

output_11_0.png

Vorhersagekurve

output_13_1.png

Fourier-Transformation

output_14_1.png

MLP, Funktion g Zusammenfassung

Die Anzahl der Epochen bis zum frühen Ende bleibt nahezu unverändert, selbst wenn sich der Zyklus ändert. Die ungefähre Form bleibt erhalten, aber es besteht die Tendenz, dass sich der Zyklus verschiebt, wenn die Füße robust sind und die Spitzenhöhe niedrig ist. Betrachtet man die Figur der Fourier-Transformation, so scheint es, dass viele Peaks (Perioden) aufgenommen werden (obwohl sie nicht ausgerichtet sind).

RNN, Funktion g

RNN, Funktion g, Periode = 25

Lernkurve

output_27_0.png

Vorhersagekurve

output_29_1.png

Fourier-Transformation

output_30_1.png

RNN, Funktion g, Periode = 50

Lernkurve

output_27_0.png

Vorhersagekurve

output_29_1.png

Fourier-Transformation

output_30_1.png

RNN, Funktion g, Periode = 100

Lernkurve

output_27_0.png

Vorhersagekurve

output_29_1.png

Fourier-Transformation

output_30_1.png

RNN, Funktion g Zusammenfassung

Der mit einem kurzen Zyklus (25) ist eine gute Vorhersage. Der mit dem mittleren Zyklus (50) nimmt die Hauptpeaks auf, aber sie sind nicht ausgerichtet. Im langen Zyklus (100) scheint RNN die Vorhersage frühzeitig aufgegeben zu haben. Von den vielen Zyklen scheinen nur relativ kurze Zyklen aufgenommen zu werden.

LSTM, Funktion g

LSTM, Funktion g, Periode = 25

Lernkurve

output_33_0.png

Vorhersagekurve

output_35_1.png

Fourier-Transformation

output_36_1.png

LSTM, Funktion g, Periode = 50

Lernkurve

output_33_0.png

Vorhersagekurve

output_35_1.png

Fourier-Transformation

output_36_1.png

LSTM, Funktion g, Periode = 100

Lernkurve

output_33_0.png

Vorhersagekurve

output_35_1.png

Fourier-Transformation

output_36_1.png

LSTM, Funktion g Zusammenfassung

Überraschenderweise funktionierte es nicht in jedem Zyklus. Der kurze Zyklus funktionierte gut mit RNN, aber nicht mit LSTM, und erreichte einen unwahrscheinlichen Höhepunkt. Das Ergebnis des mittleren Zyklus ist das beste, aber der Zyklus war immer noch ausgeschaltet. Ich kann die Stimme sagen hören, dass ich die Vorhersage für den langen Zyklus aufgegeben habe.

GRU, Funktion g

GRU, Funktion g, Periode = 25

Lernkurve

output_39_0.png

Vorhersagekurve

output_41_1.png

Fourier-Transformation

output_42_1.png

GRU, Funktion g, Periode = 50

Lernkurve

output_39_0.png

Vorhersagekurve

output_41_1.png

Fourier-Transformation

output_42_1.png

GRU, Funktion g, Periode = 100

Lernkurve

output_39_0.png

Vorhersagekurve

output_41_1.png

Fourier-Transformation

output_42_1.png

GRU, Funktion g Zusammenfassung

Das ist auch überraschend. LSTM war schlechter als RNN, aber GRU war schlechter. Der kurze Zyklus ist etwas besser, aber der mittlere Zyklus fühlt sich an, als hätte ich aufgegeben.

Funktion mit verschiedenen Perioden h

Zuerst dachte ich daran, mehr verschiedene Zyklen zu mischen, aber nachdem ich die obigen Ergebnisse gesehen hatte, dachte ich, es wäre besser, etwas weniger zu mischen.

MLP, Funktion h

Lernkurve

output_11_0.png

Vorhersagekurve

output_13_1.png

Fourier-Transformation

output_14_1.png

Das Aufnehmen des Zyklus scheint relativ erfolgreich zu sein. Da die Amplitude jedoch nicht gut aufgenommen wird, ist das Ergebnis eine Vorhersage mit einem großen Fehler.

RNN, Funktion h

Lernkurve

output_27_0.png

Vorhersagekurve

output_29_1.png

Fourier-Transformation

output_30_1.png

Normalerweise nehme ich den Zyklus auf, aber etwas ist nicht synchron. Die Amplitude hat aus irgendeinem Grund zugenommen.

LSTM, Funktion h

Lernkurve

output_33_0.png

Vorhersagekurve

output_35_1.png

Fourier-Transformation

output_36_1.png

Ich habe einige Zyklen aufgenommen, aber ich habe einige Zyklen aufgenommen, die nicht da sind. Ist RNN in diesem Sinne etwas besser?

GRU, Funktion h

Lernkurve

output_39_0.png

Vorhersagekurve

output_41_1.png

Fourier-Transformation

output_42_1.png

Es fühlt sich noch schlimmer an als LSTM.

Zusammenfassung

Dies ist die Zusammenfassung. Soweit ich mich mit einigen periodischen Funktionen befasst habe

Ich habe noch nicht genug gelernt, daher kann es einige seltsame Teile geben, aber ich würde es begrüßen, wenn Sie auf Punkte hinweisen könnten, die Sie bemerkt haben ... (ヽ ´ω`)

Recommended Posts

Rekursive neuronale Netze untersuchen: Können Sie periodische Funktionen reproduzieren?
Rekursives neuronales Netzwerk: Eine Einführung in RNN
Funktionen, die in der for-Anweisung verwendet werden können