Samouczek RNN (rekurencyjna sieć neuronowa): przykład TensorFlow
⚡ Inteligentne podsumowanie
Rekurencyjne sieci neuronowe dodają stan pamięci do zwykłych neuronów, przekazując każde wyjście jako kolejne wejście, dzięki czemu model może uczyć się w określonej kolejności. W tym przewodniku zbudujemy taką sieć w TensorFlow i prognozujemy szereg czasowy.

Dlaczego potrzebujemy rekurencyjnej sieci neuronowej (RNN)?
Rekurencyjna sieć neuronowa (RNN) umożliwia modelowanie jednostek pamięci w celu utrwalania danych i modelowania zależności krótkoterminowych. Jest również stosowany w prognozowaniu szeregów czasowych w celu identyfikacji korelacji i wzorców danych. Pomaga także w uzyskiwaniu wyników predykcyjnych dla danych sekwencyjnych, zapewniając podobne zachowanie jak ludzki mózg.
Struktura an Sztuczna sieć neuronowa jest stosunkowo prosty i polega głównie na mnożeniu macierzy. W pierwszym kroku dane wejściowe są mnożone przez początkowo losowe wagi i odchylenie, przekształcane za pomocą funkcji aktywacji, a wartości wyjściowe służą do prognozowania. Ten krok daje wyobrażenie o tym, jak bardzo sieć odbiega od rzeczywistości.
Zastosowaną metryką jest strata. Im wyższa funkcja straty, tym głupszy model. Aby poprawić wiedzę o sieci, konieczna jest pewna optymalizacja poprzez dostosowanie wag sieci. Metoda stochastycznego spadku gradientu jest stosowana w celu zmiany wartości wag w odpowiednim kierunku. Po dokonaniu dostosowania sieć może użyć kolejnej partii danych do przetestowania swojej nowej wiedzy.
Na szczęście błąd jest niższy niż poprzednio, ale wciąż niewystarczający. Etap optymalizacji jest wykonywany iteracyjnie, aż do zminimalizowania błędu, tj. do momentu, gdy nie można uzyskać więcej informacji.tracprzetrząsać.
Problem z tego typu modelem polega na tym, że nie ma on żadnej pamięci. Oznacza to, że wejście i wyjście są niezależne. Innymi słowy, model nie przejmuje się tym, co było wcześniej. Rodzi się pytanie, kiedy trzeba przewidzieć szeregi czasowe lub zdania, ponieważ sieć potrzebuje informacji o danych historycznych lub przeszłych słowach.
Aby przezwyciężyć ten problem, opracowano nowy typ architektury: rekurencyjną sieć neuronową (RNN)
Co to jest rekurencyjna sieć neuronowa (RNN)?
Rekurencyjna sieć neuronowa (RNN) to klasa sztucznych sieci neuronowych, w których połączenia między różnymi węzłami tworzą graf skierowany, co pozwala na dynamiczne zachowanie w czasie. Pomaga ona modelować dane sekwencyjne pochodzące z sieci sprzężenia zwrotnego. Działa podobnie do ludzkiego mózgu, dostarczając wyniki predykcyjne.
Rekurencyjna sieć neuronowa wygląda całkiem podobnie do tradycyjnej sieci neuronowej, z tą różnicą, że do neuronów dodawany jest stan pamięci. Obliczenia uwzględniające pamięć są proste.
Wyobraź sobie prosty model, w którym tylko jeden neuron pobiera partię danych. W tradycyjnej sieci neuronowej model generuje wynik poprzez pomnożenie danych wejściowych przez wagę i funkcję aktywacji. W sieci neuronowej (RNN) dane wyjściowe są wysyłane do siebie wielokrotnie. Nazywamy to krok czasu czas, w którym dane wyjściowe stają się danymi wejściowymi kolejnego mnożenia macierzy.
Na przykład na poniższym obrazku widać, że sieć składa się z jednego neuronu. Sieć oblicza mnożenie macierzy między wejściem a wagą i dodaje nieliniowość za pomocą funkcji aktywacji. Staje się wyjściem w t-1. Wynik ten jest wejściem drugiego mnożenia macierzy.
Powtarzalna sieć neuronowa (RNN)
Poniżej kodujemy prosty RNN w TensorFlow, aby zrozumieć krok i kształt wyniku.
Sieć składa się z:
- Cztery wejścia
- Sześć neuronów
- 2-krotne kroki
Sieć będzie działać w sposób przedstawiony na poniższym obrazku.
Sieć nazywa się „rekurencyjną”, ponieważ wykonuje tę samą operację w każdym kwadracie aktywacji. Sieć obliczała wagi danych wejściowych i poprzedniego wyjścia przed użyciem funkcji aktywacji.
Uwaga dotycząca wersji: Kod w tym samouczku dotyczy interfejsu API graficznego TensorFlow 1.x. W TensorFlow 2.x ten sam skrypt nadal działa po… import tensorflow.compat.v1 as tf plus tf.disable_v2_behavior()ponieważ symbole zastępcze, sesje i moduł rnn_cell znajdują się teraz pod tf.compat.v1. Idiomatyczny odpowiednik 2.x to tf.keras.layers.SimpleRNN.
import numpy as np import tensorflow as tf n_inputs = 4 n_neurons = 6 n_timesteps = 2 The data is a sequence of a number from 0 to 9 and divided into three batches of data. ## Data X_batch = np.array([ [[0, 1, 2, 5], [9, 8, 7, 4]], # Batch 1 [[3, 4, 5, 2], [0, 0, 0, 0]], # Batch 2 [[6, 7, 8, 5], [6, 5, 4, 2]], # Batch 3 ])
Możemy zbudować sieć z symbolem zastępczym danych, etapem cyklicznym i wynikiem.
Zdefiniuj symbol zastępczy danych
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])
Tutaj:
- Brak: nieznany i będzie odpowiadał wielkości partii
- n_timesteps: Ile razy sieć będzie wysyłać dane wyjściowe z powrotem do neuronu
- n_inputs: Liczba wejść na partię
Zdefiniuj sieć rekurencyjną
Jak widać na powyższym obrazku, sieć składa się z 6 neuronów. Sieć obliczy iloczyn dwukropkowy:
- Dane wejściowe z pierwszym zestawem wag (tj. 6: równa liczbie neuronów)
- Poprzednie wyjście z drugim zestawem wag (tj. 6: odpowiadające liczbie wyjść)
Należy zauważyć, że podczas pierwszego sprzężenia zwrotnego wartości poprzedniego wyjścia są równe zerom, ponieważ nie mamy dostępnej żadnej wartości.
Obiektem do zbudowania RNN jest tf.contrib.rnn.BasicRNNCell z argumentem num_units definiującym liczbę wejść
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)
Teraz, gdy sieć jest zdefiniowana, możesz obliczyć wyjścia i stany
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
Obiekt ten wykorzystuje pętlę wewnętrzną do mnożenia macierzy odpowiednią liczbę razy.
Należy zauważyć, że neuron rekurencyjny jest funkcją wszystkich danych wejściowych z poprzednich kroków czasowych. W ten sposób sieć buduje własną pamięć. Informacje z poprzedniego kroku czasowego mogą być propagowane w czasie przyszłym. To właśnie magia rekurencyjnej sieci neuronowej.
## Define the shape of the tensor X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs]) ## Define the network basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons) outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32) init = tf.global_variables_initializer() init = tf.global_variables_initializer() with tf.Session() as sess: init.run() outputs_val = outputs.eval(feed_dict={X: X_batch}) print(states.eval(feed_dict={X: X_batch})) [[ 0.38941205 -0.9980438 0.99750966 0.7892596 0.9978241 0.9999997 ] [ 0.61096436 0.7255889 0.82977575 -0.88226104 0.29261455 -0.15597084] [ 0.62091285 -0.87023467 0.99729395 -0.58261937 0.9811445 0.99969864]]
Dla wyjaśnienia, drukujemy wartości z poprzedniego stanu. Powyższe dane wyjściowe przedstawiają dane wyjściowe z ostatniego stanu. Teraz, drukując wszystkie dane wyjściowe, zauważysz, że stany to poprzednie dane wyjściowe każdej partii. Oznacza to, że poprzednie dane wyjściowe zawierają informacje o całej sekwencji.
print(outputs_val) print(outputs_val.shape) [[[-0.75934666 -0.99537754 0.9735819 -0.9722234 -0.14234993 -0.9984044 ] [ 0.99975264 -0.9983206 0.9999993 -1. -0.9997506 -1. ]] [[ 0.97486496 -0.98773265 0.9969686 -0.99950117 -0.7092863 -0.99998885] [ 0.9326837 0.2673438 0.2808514 -0.7535883 -0.43337247 0.5700631 ]] [[ 0.99628735 -0.9998728 0.99999213 -0.99999976 -0.9884324 -1. ] [ 0.99962527 -0.9467421 0.9997403 -0.99999714 -0.99929446 -0.9999795 ]]] (3, 2, 6)
Poniższy adnotowany widok rozbija ten sam wydrukowany tensor na partie.
Wynik ma postać (3, 2, 6):
- 3: Liczba partii
- 2: Numer kroku czasowego
- 6: Liczba neuronów
Optymalizacja rekurencyjnej sieci neuronowej jest identyczna jak w przypadku tradycyjnej sieci neuronowej. Bardziej szczegółowo, jak optymalizować kod, zobaczysz w następnej części tego samouczka dotyczącego rekurencyjnej sieci neuronowej.
Zastosowania RNN
RNN ma wiele zastosowań, szczególnie jeśli chodzi o przewidywanie przyszłości. W branży finansowej RNN może być pomocny w przewidywaniu cen akcji lub oznak kierunku rynku akcji (tj. pozytywnego lub negatywnego).
RNN jest przydatny w samochodzie autonomicznym, ponieważ może uniknąć wypadku samochodowego, przewidując trajektorię pojazdu.
RNN jest szeroko stosowany w analizie tekstu, podpisach obrazów, analizie nastrojów i tłumaczeniu maszynowym. Recenzję filmu można na przykład wykorzystać do zrozumienia uczuć, jakie odczuwa widz po obejrzeniu filmu. Automatyzacja tego zadania jest bardzo przydatna, gdy wytwórnia filmowa nie ma wystarczająco dużo czasu na przeglądanie, oznaczanie, konsolidowanie i analizowanie recenzji. Maszyna może wykonać pracę z większą dokładnością.
Ograniczenia RNN
Teoretycznie RNN ma przenosić informacje do czasu. Jednak propagowanie wszystkich tych informacji, gdy krok czasowy jest zbyt długi, jest dość trudne. Kiedy sieć ma zbyt wiele głębokich warstw, staje się niemożliwa do nauczenia. Problem ten nazywa się: znikający problem z gradientem. Jeśli pamiętasz, sieć neuronowa aktualizuje wagę za pomocą algorytmu gradientu opadania. Gradienty stają się mniejsze, gdy sieć przechodzi do niższych warstw.
Podsumowując, gradienty pozostają stałe, co oznacza brak możliwości poprawy. Model uczy się na podstawie zmiany gradientu; zmiana ta wpływa na wynik sieci. Jeśli jednak różnica w gradiencie jest zbyt mała (tj. wagi zmieniają się nieznacznie), sieć nie może się niczego nauczyć, a tym samym na wynik. Dlatego sieć napotykająca problem znikającego gradientu nie może zbiegać się do dobrego rozwiązania.
Ulepszenie LSTM
Aby rozwiązać potencjalny problem zanikającego gradientu, z którym boryka się sieć neuronowa RNN, trzej badacze, Hochreiter, Schmidhuber i Bengio, udoskonalili sieć RNN, stosując architekturę zwaną pamięcią długoterminową (LSTM). W skrócie, LSTM dostarcza sieci istotne informacje z przeszłości, odnoszące się do czasów współczesnych. Maszyna wykorzystuje lepszą architekturę do selekcji i przenoszenia informacji do późniejszych okresów.
Architektura LSTM jest dostępna w TensorFlow, tf.contrib.rnn.LSTMCell. LSTM nie jest objęty zakresem tego samouczka. Możesz zapoznać się z oficjalną dokumentacja dalszych informacji
W TensorFlow 2.x do tej komórki dociera się jako tf.compat.v1.nn.rnn_cell.LSTMCell, podczas gdy nowy kod zwykle używa tf.keras.layers.LSTM lub z bramką zapalniczki tf.keras.layers.GRU, który osiąga porównywalną dokładność przy mniejszej liczbie parametrów.
RNN w szeregach czasowych
W tym samouczku dotyczącym sieci neuronowych TensorFlow RNN wykorzystasz sieć neuronową RNN z danymi szeregów czasowych. Szeregi czasowe są zależne od danych z przeszłości, co oznacza, że wartości z przeszłości zawierają istotne informacje, z których sieć może się uczyć. Ideą stojącą za predykcją szeregów czasowych jest oszacowanie przyszłej wartości szeregu, na przykład ceny akcji, temperatury, PKB itd.
Przygotowanie danych dla Keras RNN i szeregów czasowych może być trochę trudne. Przede wszystkim celem jest przewidzenie następnej wartości szeregu, co oznacza, że użyjesz informacji z przeszłości, aby oszacować wartość w t + 1. Etykieta jest równa sekwencji wejściowej i przesunięta o jeden okres do przodu. Po drugie, liczba danych wejściowych jest ustawiona na 1, tj. jedna obserwacja na czas. Na koniec, krok czasowy jest równy sekwencji wartości liczbowej. Na przykład, jeśli ustawisz krok czasowy na 10, sekwencja wejściowa zwróci dziesięć kolejnych razy.
Spójrz na poniższy wykres. Po lewej stronie przedstawiliśmy dane szeregów czasowych, a po prawej fikcyjną sekwencję wejściową. Tworzysz funkcję zwracającą zbiór danych z losową wartością dla każdego dnia od stycznia 2001 r. do grudnia 2016 r.
# To plot pretty figures %matplotlib inline import matplotlib import matplotlib.pyplot as plt import pandas as pd def create_ts(start = '2001', n = 201, freq = 'M'): rng = pd.date_range(start=start, periods=n, freq=freq) ts = pd.Series(np.random.uniform(-18, 18, size=len(rng)), rng).cumsum() return ts ts= create_ts(start = '2001', n = 192, freq = 'M') ts.tail(5)
Wydajność
2016-08-31 -93.459631 2016-09-30 -95.264791 2016-10-31 -95.551935 2016-11-30 -105.879611 2016-12-31 -123.729319 Freq: M, dtype: float64
ts = create_ts(start = '2001', n = 222) # Left plt.figure(figsize=(11,4)) plt.subplot(121) plt.plot(ts.index, ts) plt.plot(ts.index[90:100], ts[90:100], "b-", linewidth=3, label="A training instance") plt.title("A time series (generated)", fontsize=14) # Right plt.subplot(122) plt.title("A training instance", fontsize=14) plt.plot(ts.index[90:100], ts[90:100], "b-", markersize=8, label="instance") plt.plot(ts.index[91:101], ts[91:101], "bo", markersize=10, label="target", markerfacecolor='red') plt.legend(loc="upper left") plt.xlabel("Time") plt.show()
Prawa część wykresu przedstawia wszystkie serie. Rozpoczyna się ona w 2001 roku i kończy w 2019 roku. Nie ma sensu wprowadzać wszystkich danych do sieci, zamiast tego należy utworzyć partię danych o długości równej krokowi czasowemu. Ta partia będzie zmienną X. Zmienna Y jest taka sama jak X, ale przesunięta o jeden okres (tj. chcemy prognozować t+1).
Obydwa wektory mają tę samą długość. Widać to w prawej części powyższego wykresu. Linia reprezentuje dziesięć wartości wejścia X, podczas gdy czerwone kropki to dziesięć wartości etykiety Y. Należy pamiętać, że etykieta zaczyna się jeden okres przed X i kończy jeden okres po.
Zbuduj RNN, aby przewidzieć szeregi czasowe w TensorFlow
Teraz, w trakcie tego szkolenia RNN, nadszedł czas na zbudowanie pierwszego RNN, który będzie przewidywał powyższą serię. Należy określić pewne hiperparametry (parametry modelu, tj. liczbę neuronów itp.) dla modelu:
- Liczba wejść: 1
- Krok czasowy (okna w szeregu czasowym): 10
- Liczba neuronów: 120
- Liczba wyjść: 1
Twoja sieć będzie uczyć się na podstawie sekwencji 10 dni i będzie zawierać 120 neuronów rekurencyjnych. Podajesz modelowi jedno dane wejściowe, tj. jeden dzień. Możesz swobodnie zmieniać wartości, aby sprawdzić, czy model się poprawił.
Przed skonstruowaniem modelu należy podzielić zbiór danych na zbiór treningowy i testowy. Pełny zbiór danych zawiera 222 punkty danych; pierwszych 201 punktów użyjesz do trenowania modelu, a ostatnich 21 do jego przetestowania.
Po zdefiniowaniu zbioru treningowego i testowego należy utworzyć obiekt zawierający partie. W tych partiach znajdują się wartości X i Y. Należy pamiętać, że wartości X są opóźnione o jeden okres. Dlatego należy użyć pierwszych 200 obserwacji, a krok czasowy wynosi 10. Obiekt X_batches powinien zawierać 20 partii o rozmiarze 10*1. Obiekt y_batches ma taki sam kształt jak obiekt X_batches, ale z jednym okresem do przodu.
Krok 1) Utwórz pociąg i przetestuj
Przede wszystkim konwertujesz serię na a numpy tablica; następnie definiujesz okna (czyli liczbę czasów, w których sieć będzie się uczyć), liczbę danych wejściowych, wyjściowych i rozmiar zestawu treningowego, jak pokazano w poniższym przykładzie TensorFlow RNN.
series = np.array(ts) n_windows = 20 n_input = 1 n_output = 1 size_train = 201
Następnie wystarczy podzielić tablicę na dwa zbiory danych.
## Split data train = series[:size_train] test = series[size_train:] print(train.shape, test.shape) (201,) (21,)
Krok 2) Utwórz funkcję zwracającą X_batches i y_batches
Aby to ułatwić, możesz utworzyć funkcję zwracającą dwie różne tablice, jedną dla X_batches i jedną dla y_batches.
Napiszmy funkcję RNN TensorFlow, aby skonstruować partie.
Należy zauważyć, że partie X są opóźnione o jeden okres (bierzemy wartość t-1). Wyjście funkcji powinno mieć trzy wymiary. Pierwszy wymiar jest równy liczbie partii, drugi rozmiarowi okien, a ostatni liczbie danych wejściowych.
Trudną częścią jest prawidłowe wybranie punktów danych. Dla punktów danych X wybierasz obserwacje od t = 1 do t = 200, natomiast dla punktu danych Y zwracasz obserwacje od t = 2 do 201. Gdy masz już prawidłowe punkty danych, zmiana kształtu jest prosta Serie.
Aby skonstruować obiekt z partii, należy podzielić zbiór danych na dziesięć partii o równej długości (tj. 20). Możesz użyć metody reshape i przekazać -1, aby seria była podobna do wielkości partii. Wartość 20 to liczba obserwacji na partię, a 1 to liczba danych wejściowych.
Musisz wykonać ten sam krok, ale dla etykiety.
Pamiętaj, że musisz przesunąć dane o liczbę razy, którą chcesz prognozować. Na przykład, jeśli chcesz prognozować jeden raz do przodu, przesuń serię o 1. Jeśli chcesz prognozować dwa dni, przesuń dane o 2.
x_data = train[:size_train-1]: Select all the training instance minus one day X_batches = x_data.reshape(-1, windows, input): create the right shape for the batch e.g (10, 20, 1) def create_batches(df, windows, input, output): ## Create X x_data = train[:size_train-1] # Select the data X_batches = x_data.reshape(-1, windows, input) # Reshape the data ## Create y y_data = train[n_output:size_train] y_batches = y_data.reshape(-1, windows, output) return X_batches, y_batches
Teraz, gdy funkcja jest zdefiniowana, możesz ją wywołać, aby utworzyć partie, jak pokazano w poniższym przykładzie RNN.
X_batches, y_batches = create_batches(df = train,
windows = n_windows,
input = n_input,
output = n_output)
Możesz wydrukować kształt, aby upewnić się, że wymiary są prawidłowe.
print(X_batches.shape, y_batches.shape)
(10, 20, 1) (10, 20, 1)
Musisz utworzyć zbiór testowy zawierający tylko jedną partię danych i 20 obserwacji.
Należy pamiętać, że prognozujesz dni po dniach, co oznacza, że druga przewidywana wartość będzie oparta na prawdziwej wartości z pierwszego dnia (t+1) testowego zbioru danych. Tak naprawdę, prawdziwa wartość będzie znana.
Jeśli chcesz prognozować t+2 (tj. dwa dni do przodu), musisz użyć przewidywanej wartości t+1; jeśli zamierzasz przewidzieć t+3 (trzy dni do przodu), musisz użyć przewidywanej wartości t+1 i t+2. Ma to sens, że trudno jest dokładnie przewidzieć t+n dni do przodu.
X_test, y_test = create_batches(df = test, windows = 20,input = 1, output = 1)
print(X_test.shape, y_test.shape)
(10, 20, 1) (10, 20, 1)
Dobrze, rozmiar Twojej partii jest gotowy, możesz zbudować architekturę RNN. Pamiętaj, masz 120 neuronów rekurencyjnych.
Krok 3) Zbuduj model
Aby utworzyć model, należy zdefiniować trzy części:
- Zmienna z tensorami
- RNN
- Strata i optymalizacja
Krok 3.1) Zmienne
Musisz określić zmienne X i Y o odpowiednim kształcie. Ten krok jest banalny. Tensor ma ten sam wymiar co obiekty X_batches i y_batches.
Na przykład tensor X jest symbolem zastępczym (sprawdź samouczek na Wprowadzenie do TensorFlow aby odświeżyć zdanie na temat deklaracji zmiennej) ma trzy wymiary:
- Uwaga: wielkość partii
- n_windows: Długość okien, czyli liczba razy, w których model przegląda się wstecz
- n_input: Liczba wejść
Wynik to:
tf.placeholder(tf.float32, [None, n_windows, n_input])
## 1. Construct the tensors X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output])
Krok 3.2) Utwórz RNN
W drugiej części tego przykładu RNN TensorFlow musisz zdefiniować architekturę sieci. Tak jak poprzednio, używasz obiektu BasicRNNCell i dynamic_rnn z estymatora TensorFlow.
## 2. create the model
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)
rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
Następna część jest nieco trudniejsza, ale umożliwia szybsze obliczenia. Musisz przekształcić wynik uruchomienia w gęstą warstwę, a następnie przekonwertować go ponownie, aby miał ten sam wymiar co dane wejściowe.
stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])
Krok 3.3) Utwórz stratę i optymalizację
Optymalizacja modelu zależy od wykonywanego zadania. W poprzednim samouczku dotyczącym CNNTwoim celem była klasyfikacja obrazów, w tym samouczku RNN cel jest nieco inny. Twoim zadaniem jest dokonanie predykcji na zmiennej ciągłej w porównaniu z klasą.
Różnica ta jest istotna, ponieważ zmieni problem optymalizacji. Problem optymalizacji zmiennej ciągłej polega na minimalizacji błędu średniokwadratowego. Aby skonstruować te metryki w TF, możesz użyć:
tf.reduce_sum(tf.square(wyjścia – y))
Pozostała część kodu RNN jest taka sama jak poprzednio; używasz optymalizatora Adama, aby zmniejszyć straty (tj. MSE):
tf.train.AdamOptimizer(learning_rate=learning_rate)
optymalizator.minimize(strata)
To tyle, możesz wszystko spakować w jedną całość i Twój model jest gotowy do treningu.
tf.reset_default_graph() r_neuron = 120 ## 1. Construct the tensors X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output]) ## 2. create the model basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu) rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32) stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output]) ## 3. Loss + optimization learning_rate = 0.001 loss = tf.reduce_sum(tf.square(outputs - y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) training_op = optimizer.minimize(loss) init = tf.global_variables_initializer()
Będziesz trenował model przy użyciu 1500 epok i drukował stratę co 150 iteracji. Po wyszkoleniu modelu oceniasz go na zestawie testowym i tworzysz obiekt zawierający przewidywania, jak pokazano w poniższym przykładzie rekurencyjnej sieci neuronowej.
iteration = 1500 with tf.Session() as sess: init.run() for iters in range(iteration): sess.run(training_op, feed_dict={X: X_batches, y: y_batches}) if iters % 150 == 0: mse = loss.eval(feed_dict={X: X_batches, y: y_batches}) print(iters, "\tMSE:", mse) y_pred = sess.run(outputs, feed_dict={X: X_test}) 0 MSE: 502893.34 150 MSE: 13839.129 300 MSE: 3964.835 450 MSE: 2619.885 600 MSE: 2418.772 750 MSE: 2110.5923 900 MSE: 1887.9644 1050 MSE: 1747.1377 1200 MSE: 1556.3398 1350 MSE: 1384.6113
Wreszcie, w tym samouczku dotyczącym głębokiego uczenia się RNN, możesz wykreślić rzeczywistą wartość szeregu z wartością przewidywaną. Jeśli model zostanie poprawiony, wartości przewidywane należy nałożyć na wartości rzeczywiste.
Jak widać, model ma potencjał do poprawy. Od Ciebie zależy zmiana hiperparametrów, takich jak okna, rozmiar partii czy liczba neuronów rekurencyjnych.
plt.title("Forecast vs Actual", fontsize=14) plt.plot(pd.Series(np.ravel(y_test)), "bo", markersize=8, label="Actual", color='green') plt.plot(pd.Series(np.ravel(y_pred)), "r.", markersize=8, label="Forecast", color='red') plt.legend(loc="lower left") plt.xlabel("Time") plt.show()
Prognoza vs faktyczna





