En apprentissage profond, j'ai essayé de voir à quel point la fonction périodique peut être reproduite afin d'étudier le réseau neuronal récurrent utilisé pour l'analyse des données de séries chronologiques.
Ici, nous avons défini les trois types de fonctions périodiques suivants: 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
La fonction f
est une fonction triangulaire $ sin $. Ici, la période est fixée à 25 $.
%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()
La fonction g
transforme la fonction triangulaire $ sin $ avec une fonction sigmoïde en une forme étrange. Encore une fois, j'ai mis le cycle à 25 $.
%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()
La fonction «h» est la somme des fonctions triangulaires $ sin $ dont la période est de plusieurs nombres premiers.
%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()
Ces fonctions peuvent-elles être reproduites dans un réseau de neurones récursif?
Avant d'utiliser le réseau de neurones récursif, convertissons les trois fonctions ci-dessus en fréquences par transformée de Fourier et prenons le nombre inverse pour vérifier la "période".
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()
La fonction f
consiste uniquement en des ondes sin avec une période de 25 $. Vous pouvez voir que la fonction «h» consiste en une combinaison de périodes des nombres premiers spécifiés. D'autre part, vous pouvez voir que la fonction g
contient divers composants autres que la période spécifiée de 25 $.
Créons maintenant un ensemble de données chronologiques pour entraîner un réseau de neurones récursif. Dans un réseau de neurones récursif, si vous entrez la sortie $ X_ {t, t + w} $ du temps $ t $ à $ t + w $, la sortie $ X_ {t + w + 1} $ à la prochaine fois est prédite. Visez à créer un modèle à faire.
import numpy as np
from sklearn.model_selection import train_test_split
func = f #Vous pouvez changer la fonction en réécrivant ici
#func = g
#func = h
total_time_length = 10000 #Toutes les largeurs de temps à gérer
pred_length = 1000 #Largeur de temps prévue
learning_time_length = 100 #Largeur de temps utilisée pour l'apprentissage
time_series_T = np.linspace(0, total_time_length, total_time_length + 1) #Graver le temps prévu T (correspondant à l'axe horizontal du graphique)
time_series_X = func(time_series_T) #Sortie de fonction X (correspond à l'axe vertical du graphique)
X_learn = [] #Heure t ~ t+learning_time_Stocke X jusqu'à la longueur
Y_learn = [] #Heure t+learning_time_length+Stocker 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]])
#Divisé en données d'entraînement et données de vérification
#Aléatoire pour les données de séries chronologiques=Doit être faux
X_train, X_val, Y_train, Y_val = \
train_test_split(X_learn, Y_learn, test_size=0.2, shuffle=False)
# scikit-Convertir en type de données pour apprendre
X_train2sklearn = [list(x.reshape(1, len(x))[0]) for x in X_train]
Y_train2sklearn = [y[0] for y in Y_train]
MLP (Multi-Layer Perceptron)
À titre de comparaison, nous utilisons Multi-Layer Perceptron (MLP), qui est le modèle le plus simple d'apprentissage en profondeur. J'ai utilisé le Perceptron multicouche car scikit-learn est facile et rapide.
%%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
La courbe d'apprentissage a été dessinée comme suit.
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()
Donnez au modèle entraîné les premières heures (uniquement la longueur de pred_length
) comme entrée pour prédire la sortie à la prochaine fois. Ajoutez la valeur prévue de sortie à l'entrée pour prédire la sortie à la prochaine fois. Répétez-le à l'infini.
%%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
La courbe de la valeur prédite obtenue de cette manière et la courbe réelle sont illustrées et comparées.
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()
Si la figure est petite et difficile à voir, vous pouvez l'agrandir en cliquant dessus. Jusqu'à 100 $, les données d'entraînement sont utilisées telles quelles, donc elles correspondent, mais après 100 $, vous pouvez voir que la valeur réelle (valeur de la fonction f
) et la valeur prédite changent progressivement. ..
Comparons les résultats de la transformée de Fourier.
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()
Le cycle prévu est proche du cycle réel, mais semble être légèrement décalé.
Construisons maintenant un réseau de neurones récursif. Ici, PyTorch, une bibliothèque pour l'apprentissage en profondeur, est utilisée.
Commencez par configurer l'appareil. Si vous pouvez utiliser le GPU, utilisez le GPU, et sinon, utilisez le CPU comme suit.
import torch
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
Préparez une fonction pour EarlyStopping. L'arrêt prématuré est le processus d'interruption de l'apprentissage lorsqu'il est déterminé que l'apprentissage ne se poursuivra plus.
Dans l'apprentissage profond, l'erreur de prédiction est appelée perte. Afin d'éviter le surajustement (également appelé surajustement), ici, au lieu de la «perte» des données d'apprentissage, l'apprentissage est arrêté lorsqu'il est jugé que la «perte» des données de vérification non utilisées pour l'entraînement ne diminuera plus. .. En tant que jugement, nous introduisons le concept de «patience». Si patience = 20
, comparez la valeur minimale de perte
de 20 $ récemment avec la valeur minimale de perte
avant cela, et si la première est plus grande, jugez que" ce ne sera pas mieux "et apprenez. Je vais interrompre.
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)
C'est un peu déroutant, mais RNN (Recurrent Neural Network) a "RNN au sens large" et "RNN au sens étroit". RNN au sens strict peut être implémenté dans PyTorch comme suit.
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) est long ou court! !! C'est un nom qui donne envie de creuser, mais c'est une sorte de "RNN au sens large". On dit que la mémoire à long terme est supérieure à "RNN au sens étroit". Il peut être implémenté dans PyTorch comme suit:
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)
Le GRU n'est pas un Glavnoye Razvedyvatelnoye Upravleniye, mais une unité récurrente fermée. On dit que le temps de calcul est court tout en ayant des performances identiques ou supérieures au LSTM.
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
J'ai appris comme suit. Le code suivant est pour RNN, mais vous pouvez le changer en LSTM ou GRU en le réécrivant au même endroit.
%%time
from sklearn.utils import shuffle
model = RNN(50).to(device) #Vous pouvez changer de réseau en réécrivant ici
#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
L'apprentissage est terminé. Sort la courbe d'apprentissage.
%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()
Donnez au modèle entraîné les premières heures (uniquement la longueur de pred_length
) comme entrée pour prédire la sortie à la prochaine fois. Ajoutez la valeur prévue de sortie à l'entrée pour prédire la sortie à la prochaine fois. Répétez-le à l'infini.
%%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
La courbe de la valeur prédite obtenue de cette manière et la courbe réelle sont illustrées et comparées.
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()
Si la figure est petite et difficile à voir, vous pouvez l'agrandir en cliquant dessus. Jusqu'à 100 $, les données d'entraînement sont utilisées telles quelles, il est donc naturel qu'elles correspondent, mais après 100 $, vous pouvez voir qu'elles correspondent parfaitement.
Comparons les résultats de la transformée de Fourier.
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()
Il semble que les cycles soient exactement les mêmes.
Comme mentionné ci-dessus, l'apprentissage du LSTM réécrit simplement «model = RNN (50) .to (device)» dans le code ci-dessus en «model = LSTM (50) .to (device)».
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
CPU times: user 7.67 s, sys: 14 ms, total: 7.68 s
Wall time: 7.69 s
Il semble que c'était aussi une prédiction parfaite.
Comme mentionné ci-dessus, l'apprentissage de GRU remplace simplement «model = RNN (50) .to (device)» dans le code ci-dessus par «model = GRU (50) .to (device)».
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
CPU times: user 8.81 s, sys: 7.04 ms, total: 8.81 s
Wall time: 8.82 s
Il semble que c'était aussi une prédiction parfaite.
Maintenant que je sais comment le déplacer, essayons enfin de changer la forme et la période de la fonction. Le résultat est le suivant.
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Même si le cycle devient grand, il n'y a pas de grand changement dans le nombre d'époques passées jusqu'à la fin précoce. La forme de la courbe ne s'est pas effondrée de manière significative, mais il y a eu un changement dans le cycle. La hauteur de sortie (amplitude) a été préservée lorsque la période était courte, mais on a constaté qu'elle avait tendance à diminuer à mesure que la période devenait plus longue.
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Le nombre d'époques passées pour finir tôt avait tendance à diminuer à mesure que le cycle augmentait. La courbe de prédiction a fait de bonnes prédictions dans le cycle court (25) ou cycle moyen (50), mais a perdu sa forme de manière significative dans le cycle long (100). Dans la prévision à longue période, un pic net a été observé à un endroit étrange.
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Le nombre d'époques passées avant l'arrêt anticipé peut (bien que peu clair) diminuer avec des cycles plus longs. De bonnes prédictions ont été faites pour l'ensemble du cycle court (25), du cycle moyen (50) et du cycle long (100).
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
J'ai entendu dire que GRU est plus rapide que LSTM, mais le nombre d'époques passées avant la résiliation anticipée était plutôt long (atteignant 1000 époques). De bonnes prédictions ont été faites pour l'ensemble du cycle court (25), du cycle moyen (50) et du cycle long (100).
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Le nombre d'époques passées jusqu'à la fin précoce est pratiquement inchangé même si le cycle change. La forme approximative est préservée, mais le cycle a tendance à se déplacer lorsque les pieds sont robustes et que la hauteur du pic est faible. En regardant la figure de la transformée de Fourier, il semble que de nombreux pics (périodes) sont captés (bien qu'ils ne soient pas alignés).
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Celui avec un cycle court (25) est une bonne prédiction. Celui avec le cycle médian (50) capte les pics principaux, mais ils ne sont pas alignés. Dans le cycle long (100), RNN semble avoir abandonné prématurément la prédiction. Parmi les nombreux cycles, il semble que seuls des cycles relativement courts soient repris.
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Étonnamment, cela ne fonctionnait pas dans tous les cycles. Le cycle court a bien fonctionné avec RNN, mais pas avec LSTM, enregistrant un pic improbable. Le résultat du cycle intermédiaire est le meilleur, mais le cycle était toujours désactivé. J'entends la voix dire que j'ai abandonné la prédiction pour le long cycle.
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
C'est également surprenant. LSTM était pire que RNN, mais GRU était pire. Le cycle court est un peu meilleur, mais le cycle intermédiaire donne l'impression que j'ai abandonné.
Au début, je pensais mélanger des cycles plus diversifiés, mais après avoir vu les résultats ci-dessus, j'ai pensé qu'il serait préférable de mélanger un peu moins.
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
La reprise du cycle semble être relativement réussie. Cependant, comme l'amplitude n'est pas bien captée, le résultat est une prédiction avec une erreur importante.
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
Je prends généralement le cycle, mais quelque chose n'est pas synchronisé. L'amplitude a augmenté pour une raison quelconque.
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
J'ai ramassé quelques cycles, mais j'ai ramassé plusieurs cycles qui ne sont pas là. En ce sens, RNN est-il un peu mieux?
Courbe d'apprentissage
Courbe de prédiction
Transformée de Fourier
C'est encore pire que LSTM.
Ceci est le résumé. Pour autant que j'ai traité de certaines fonctions périodiques
Je n'ai pas encore assez étudié, donc il peut y avoir des parties étranges, mais j'apprécierais que vous puissiez souligner les points que vous avez remarqués ... (ヽ ´ω`)