RNN-Tutorial (Recurrent Neural Network): TensorFlow-Beispiel

Warum brauchen wir ein Recurrent Neural Network (RNN)?

Mit dem rekurrenten neuronalen Netzwerk (RNN) kรถnnen Sie Speichereinheiten modellieren, um Daten beizubehalten und kurzfristige Abhรคngigkeiten zu modellieren. Es wird auch in der Zeitreihenprognose zur Identifizierung von Datenkorrelationen und -mustern verwendet. Es hilft auch, prรคdiktive Ergebnisse fรผr sequentielle Daten zu erzielen, indem es ein รคhnliches Verhalten wie ein menschliches Gehirn liefert.

Die Struktur eines kรผnstlichen neuronalen Netzwerks ist relativ einfach und basiert hauptsรคchlich auf Matrixmultiplikation. Im ersten Schritt werden die Eingaben mit zunรคchst zufรคlligen Gewichten und Bias multipliziert, mit einer Aktivierungsfunktion transformiert und die Ausgabewerte zur Erstellung einer Vorhersage verwendet. Dieser Schritt vermittelt eine Vorstellung davon, wie weit das Netzwerk von der Realitรคt entfernt ist.

Die angewandte Metrik ist der Verlust. Je hรถher die Verlustfunktion, desto dรผmmer ist das Modell. Um das Wissen des Netzwerks zu verbessern, ist eine gewisse Optimierung durch Anpassung der Gewichte des Netzes erforderlich. Der stochastische Gradientenabstieg ist die Methode, die verwendet wird, um die Werte der Gewichte in die richtige Richtung zu รคndern. Sobald die Anpassung vorgenommen wurde, kann das Netzwerk einen weiteren Datensatz verwenden, um sein neues Wissen zu testen.

Der Fehler ist glรผcklicherweise geringer als zuvor, aber nicht klein genug. Der Optimierungsschritt wird iterativ durchgefรผhrt, bis der Fehler minimiert ist, dh keine Informationen mehr extrahiert werden kรถnnen.

Das Problem bei diesem Modelltyp ist, dass er keinen Speicher hat. Dies bedeutet, dass Eingabe und Ausgabe unabhรคngig sind. Mit anderen Worten, dem Modell ist es egal, was davor war. Es wirft einige Fragen auf, wenn Sie Zeitreihen oder Sรคtze vorhersagen mรผssen, da das Netzwerk Informationen รผber historische Daten oder vergangene Wรถrter benรถtigen muss.

Um dieses Problem zu lรถsen, wurde ein neuer Architekturtyp entwickelt: Recurrent Neural Network (im Folgenden RNN)

Was ist ein wiederkehrendes neuronales Netzwerk (RNN)?

A Rekurrentes neuronales Netz (RNN) ist eine Klasse von Kรผnstliche neuronale Netz bei dem die Verbindung zwischen verschiedenen Knoten einen gerichteten Graphen bildet, um ein zeitlich dynamisches Verhalten zu ergeben. Es hilft, sequentielle Daten zu modellieren, die aus Feedforward-Netzwerken abgeleitet werden. Es funktioniert รคhnlich wie das menschliche Gehirn, um prรคdiktive Ergebnisse zu liefern.

Ein wiederkehrendes neuronales Netzwerk sieht einem herkรถmmlichen neuronalen Netzwerk ziemlich รคhnlich, mit der Ausnahme, dass den Neuronen ein Speicherzustand hinzugefรผgt wird. Die Berechnung zur Einbeziehung eines Speichers ist einfach.

Stellen Sie sich ein einfaches Modell vor, bei dem nur ein Neuron von einem Datenstapel gespeist wird. In einem herkรถmmlichen neuronalen Netz erzeugt das Modell die Ausgabe durch Multiplikation der Eingabe mit der Gewichtung und der Aktivierungsfunktion. Bei einem RNN wird diese Ausgabe mehrmals an sich selbst zurรผckgesendet. Wir nennen Zeitschritt die Zeitspanne, in der die Ausgabe zur Eingabe der nรคchsten Matrizenmultiplikation wird.

Im Bild unten kรถnnen Sie beispielsweise sehen, dass das Netzwerk aus einem Neuron besteht. Das Netzwerk berechnet die Matrizenmultiplikation zwischen der Eingabe und dem Gewicht und fรผgt der Aktivierungsfunktion Nichtlinearitรคt hinzu. Es wird bei t-1 zur Ausgabe. Diese Ausgabe ist die Eingabe der zweiten Matrixmultiplikation.

Rekurrentes neuronales Netz (RNN)
Rekurrentes neuronales Netz (RNN)

Im Folgenden codieren wir ein einfaches RNN in TensorFlow, um den Schritt und auch die Form der Ausgabe zu verstehen.

Das Netzwerk besteht aus:

  • Vier Eingรคnge
  • Sechs Neuronen
  • 2-malige Schritte

Das Netzwerk verhรคlt sich wie im Bild unten dargestellt.

Rekurrentes neuronales Netz (RNN)

Das Netzwerk wird als โ€žrekurrentโ€œ bezeichnet, da es in jedem aktivierten Quadrat dieselbe Operation ausfรผhrt. Das Netzwerk berechnet die Gewichte der Eingaben und der vorherigen Ausgabe, bevor eine Aktivierungsfunktion verwendet wird.

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
    ])

Wir kรถnnen das Netzwerk mit einem Platzhalter fรผr die Daten, die wiederkehrende Phase und die Ausgabe aufbauen.

  1. Definieren Sie den Platzhalter fรผr die Daten
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

Hier:

  • Keine: Unbekannt und nimmt die GrรถรŸe des Stapels an
  • n_timesteps: Hรคufigkeit, mit der das Netzwerk die Ausgabe an das Neuron zurรผcksendet
  • n_inputs: Anzahl der Eingaben pro Batch
  1. Definieren Sie das wiederkehrende Netzwerk

Wie im Bild oben erwรคhnt, besteht das Netzwerk aus 6 Neuronen. Das Netzwerk berechnet zwei Skalarprodukte:

  • Geben Sie Daten mit dem ersten Satz von Gewichten ein (d. h. 6: gleich der Anzahl der Neuronen)
  • Vorherige Ausgabe mit einem zweiten Satz von Gewichten (dh 6: entsprechend der Anzahl der Ausgaben)

Beachten Sie, dass beim ersten Feedforward die Werte der vorherigen Ausgabe gleich Nullen sind, da kein Wert verfรผgbar ist.

Das Objekt zum Erstellen eines RNN ist tf.contrib.rnn.BasicRNNCell mit dem Argument num_units, um die Anzahl der Eingaben zu definieren

basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)

Nachdem das Netzwerk nun definiert ist, kรถnnen Sie die Ausgaben und Zustรคnde berechnen

outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)

Dieses Objekt verwendet eine interne Schleife, um die Matrizen entsprechend oft zu multiplizieren.

Beachten Sie, dass das rekurrente Neuron eine Funktion aller Eingaben der vorherigen Zeitschritte ist. Auf diese Weise baut das Netzwerk sein eigenes Gedรคchtnis auf. Die Informationen aus der vorherigen Zeit kรถnnen sich in der Zukunft verbreiten. Das ist die Magie des rekurrenten neuronalen Netzwerks

## 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]]

Zur Erlรคuterung drucken Sie die Werte des vorherigen Zustands aus. Die oben gedruckte Ausgabe zeigt die Ausgabe aus dem letzten Zustand. Drucken Sie nun die gesamte Ausgabe aus. Sie kรถnnen sehen, dass es sich bei den Zustรคnden um die vorherige Ausgabe jedes Stapels handelt. Das heiรŸt, die vorherige Ausgabe enthรคlt die Informationen รผber die gesamte Sequenz.e

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)

Rekurrentes neuronales Netz (RNN)

Die Ausgabe hat die Form (3, 2, 6):

  • 3: Anzahl der Chargen
  • 2: Nummer des Zeitschritts
  • 6: Anzahl der Neuronen

Die Optimierung eines rekurrenten neuronalen Netzwerks ist identisch mit der eines herkรถmmlichen neuronalen Netzwerks. Im nรคchsten Teil dieses Tutorials zu rekurrenten neuronalen Netzwerken erfahren Sie ausfรผhrlicher, wie Sie die Codeoptimierung durchfรผhren.

Anwendungen von RNN

RNN hat vielfรคltige Einsatzmรถglichkeiten, insbesondere wenn es um die Vorhersage der Zukunft geht. In der Finanzbranche kann RNN bei der Vorhersage von Aktienkursen oder dem Vorzeichen der Bรถrsenrichtung (d. h. positiv oder negativ) hilfreich sein.

RNN ist fรผr ein autonomes Auto nรผtzlich, da es einen Autounfall vermeiden kann, indem es die Flugbahn des Fahrzeugs vorhersagt.

RNN wird hรคufig in der Textanalyse, Bildunterschrift, Stimmungsanalyse und maschinellen รœbersetzung eingesetzt. Beispielsweise kann man eine Filmrezension nutzen, um das Gefรผhl zu verstehen, das der Zuschauer nach dem Ansehen des Films empfand. Die Automatisierung dieser Aufgabe ist sehr nรผtzlich, wenn die Filmfirma nicht genรผgend Zeit hat, die Rezensionen zu prรผfen, zu kennzeichnen, zu konsolidieren und zu analysieren. Die Maschine kann die Arbeit mit hรถherer Genauigkeit erledigen.

Einschrรคnkungen von RNN

Theoretisch soll RNN die Informationen aktuell halten. Allerdings ist es ziemlich schwierig, all diese Informationen zu verbreiten, wenn der Zeitschritt zu lang ist. Wenn ein Netzwerk zu viele tiefe Schichten hat, kann es nicht mehr trainiert werden. Dieses Problem heiรŸt: verschwindendes Gradientenproblem. Wenn Sie sich erinnern, aktualisiert das neuronale Netzwerk das Gewicht mithilfe des Gradientenabstiegsalgorithmus. Die Gradienten werden kleiner, wenn das Netzwerk in tiefere Schichten vordringt.

Zusammenfassend lรคsst sich sagen, dass die Steigungen konstant bleiben, was bedeutet, dass es keinen Raum fรผr Verbesserungen gibt. Das Modell lernt aus einer ร„nderung des Gradienten; Diese ร„nderung wirkt sich auf die Ausgabe des Netzwerks aus. Wenn der Unterschied im Gradienten jedoch zu gering ist (d. h. die Gewichte รคndern sich ein wenig), kann das Netzwerk nichts lernen und damit auch die Ausgabe. Daher kann ein Netzwerk, das mit einem verschwindenden Gradientenproblem konfrontiert ist, nicht zu einer guten Lรถsung konvergieren.

Verbesserung LSTM

Um das potenzielle Problem des verschwindenden Gradienten zu รผberwinden, mit dem RNN konfrontiert ist, verbesserten drei Forscher, Hochreiter, Schmidhuber und Bengio, das RNN mit einer Architektur namens Long Short-Term Memory (LSTM). Kurz gesagt liefert LSMT dem Netzwerk relevante Informationen aus der Vergangenheit bis hin zu jรผngeren Zeiten. Die Maschine verwendet eine bessere Architektur, um Informationen auszuwรคhlen und in einen spรคteren Zeitpunkt zurรผckzutragen.

Die LSTM-Architektur ist in TensorFlow verfรผgbar, tf.contrib.rnn.LSTMCell. LSTM liegt auรŸerhalb des Umfangs dieses Tutorials. Sie kรถnnen sich auf die offizielle Dokumentation fรผr weitere Informationen

RNN in Zeitreihen

In diesem TensorFlow-RNN-Tutorial verwenden Sie ein RNN mit Zeitreihendaten. Zeitreihen hรคngen von der vorherigen Zeit ab, was bedeutet, dass vergangene Werte relevante Informationen enthalten, aus denen das Netzwerk lernen kann. Die Idee hinter der Zeitreihenvorhersage besteht darin, den zukรผnftigen Wert einer Reihe abzuschรคtzen, beispielsweise Aktienkurs, Temperatur, BIP usw.

Die Datenaufbereitung fรผr Keras RNN und Zeitreihen kann etwas knifflig sein. Zunรคchst besteht das Ziel darin, den nรคchsten Wert der Reihe vorherzusagen. Das heiรŸt, Sie verwenden die Informationen aus der Vergangenheit, um den Wert bei t + 1 zu schรคtzen. Das Label entspricht der Eingabesequenz und ist um eine Periode nach vorne verschoben. Zweitens wird die Anzahl der Eingaben auf 1 gesetzt, d. h. eine Beobachtung pro Zeit. SchlieรŸlich entspricht der Zeitschritt der Sequenz des numerischen Werts. Wenn Sie beispielsweise den Zeitschritt auf 10 setzen, wird die Eingabesequenz zehnmal hintereinander zurรผckgegeben.

Schauen Sie sich die Grafik unten an. Wir haben links die Zeitreihendaten und rechts eine fiktive Eingabesequenz dargestellt. Sie erstellen eine Funktion, um fรผr jeden Tag von Januar 2001 bis Dezember 2016 einen Datensatz mit Zufallswert zurรผckzugeben

# 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)

Ausgang

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()

RNN in Zeitreihen

Der rechte Teil des Diagramms zeigt alle Reihen. Sie beginnen 2001 und enden 2019. Es ergibt keinen Sinn, alle Daten in das Netzwerk einzuspeisen. Stattdessen mรผssen Sie einen Datenstapel mit einer Lรคnge erstellen, die dem Zeitschritt entspricht. Dieser Stapel wird die X-Variable sein. Die Y-Variable ist dieselbe wie X, jedoch um eine Periode verschoben (d. h. Sie mรถchten t+1 vorhersagen).

Beide Vektoren haben die gleiche Lรคnge. Sie kรถnnen es im rechten Teil der obigen Grafik sehen. Die Linie stellt die zehn Werte der X-Eingabe dar, wรคhrend die roten Punkte die zehn Werte der Beschriftung Y darstellen. Beachten Sie, dass die Beschriftung einen Punkt vor X beginnt und einen Punkt danach endet.

Erstellen Sie ein RNN, um Zeitreihen in TensorFlow vorherzusagen

In diesem RNN-Training ist es nun an der Zeit, Ihr erstes RNN zu erstellen, um die obige Reihe vorherzusagen. Sie mรผssen einige Hyperparameter (die Parameter des Modells, z. B. die Anzahl der Neuronen usw.) fรผr das Modell angeben:

  • Anzahl der Eingรคnge: 1
  • Zeitschritt (Fenster in Zeitreihen): 10
  • Anzahl der Neuronen: 120
  • Anzahl der Ausgรคnge: 1

Ihr Netzwerk lernt aus einer Abfolge von 10 Tagen und enthรคlt 120 wiederkehrende Neuronen. Sie fรผttern das Modell mit einer Eingabe, also einem Tag. Fรผhlen Sie sich frei, die Werte zu รคndern, um zu sehen, ob sich das Modell verbessert hat.

Bevor Sie das Modell erstellen, mรผssen Sie den Datensatz in einen Zugsatz und einen Testsatz aufteilen. Der vollstรคndige Datensatz umfasst 222 Datenpunkte; Sie verwenden die ersten 201 Punkte zum Trainieren des Modells und die letzten 21 Punkte zum Testen Ihres Modells.

Nachdem Sie einen Zug- und Testsatz definiert haben, mรผssen Sie ein Objekt erstellen, das die Stapel enthรคlt. In diesen Stapeln gibt es X-Werte und Y-Werte. Denken Sie daran, dass die X-Werte um eine Periode verzรถgert sind. Daher verwenden Sie die ersten 200 Beobachtungen und der Zeitschritt ist gleich 10. Das X_batches-Objekt sollte 20 Batches der GrรถรŸe 10*1 enthalten. Das y_batches-Objekt hat die gleiche Form wie das X_batches-Objekt, jedoch mit einem Punkt voraus.

Schritt 1) Erstellen Sie den Zug und testen Sie ihn

Zunรคchst wandeln Sie die Serie in eine um numpig Array; dann definieren Sie die Fenster (d. h. die Anzahl der Lernvorgรคnge des Netzwerks), die Anzahl der Eingaben, Ausgaben und die GrรถรŸe des Trainingssatzes, wie im TensorFlow RNN-Beispiel unten gezeigt.

series = np.array(ts)
n_windows = 20   
n_input =  1
n_output = 1
size_train = 201

Danach teilen Sie das Array einfach in zwei Datensรคtze auf.

## Split data
train = series[:size_train]
test = series[size_train:]
print(train.shape, test.shape)
(201,) (21,)

Schritt 2) Erstellen Sie die Funktion, um X_batches und y_batches zurรผckzugeben

Zur Vereinfachung kรถnnen Sie eine Funktion erstellen, die zwei verschiedene Arrays zurรผckgibt, eines fรผr X_batches und eines fรผr y_batches.

Schreiben wir eine RNN-TensorFlow-Funktion, um die Stapel zu erstellen.

Beachten Sie, dass die X-Batches um eine Periode verzรถgert sind (wir nehmen den Wert t-1). Die Ausgabe der Funktion sollte drei Dimensionen haben. Die erste Dimension entspricht der Anzahl der Batches, die zweite der GrรถรŸe der Fenster und die letzte der Anzahl der Eingaben.

Der schwierige Teil besteht darin, die Datenpunkte richtig auszuwรคhlen. Fรผr die X-Datenpunkte wรคhlen Sie die Beobachtungen von t = 1 bis t = 200 aus, wรคhrend Sie fรผr den Y-Datenpunkt die Beobachtungen von t = 2 bis 201 zurรผckgeben. Sobald Sie die richtigen Datenpunkte haben, ist die Umformung einfach die Serie.

Um das Objekt mit den Stapeln zu erstellen, mรผssen Sie den Datensatz in zehn Stapel gleicher Lรคnge (z. B. 20) aufteilen. Sie kรถnnen die Reshape-Methode verwenden und -1 รผbergeben, sodass die Serie der StapelgrรถรŸe รคhnelt. Der Wert 20 ist die Anzahl der Beobachtungen pro Stapel und 1 ist die Anzahl der Eingaben.

Sie mรผssen den gleichen Schritt ausfรผhren, jedoch fรผr das Etikett.

Beachten Sie, dass Sie die Daten entsprechend der Anzahl der Prognosen verschieben mรผssen. Wenn Sie beispielsweise eine Prognose fรผr einen Tag im Voraus erstellen mรถchten, verschieben Sie die Reihe um 1. Wenn Sie eine Prognose fรผr zwei Tage erstellen mรถchten, verschieben Sie die Daten um 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

Nachdem die Funktion nun definiert ist, kรถnnen Sie sie aufrufen, um die Stapel zu erstellen, wie im folgenden RNN-Beispiel gezeigt.

X_batches, y_batches = create_batches(df = train,
                                      windows = n_windows,
                                      input = n_input,
                                      output = n_output)

Sie kรถnnen die Form ausdrucken, um sicherzustellen, dass die Abmessungen korrekt sind.

print(X_batches.shape, y_batches.shape)
(10, 20, 1) (10, 20, 1)

Sie mรผssen den Testsatz mit nur einem Datenstapel und 20 Beobachtungen erstellen.

Beachten Sie, dass Sie Tage fรผr Tage prognostizieren. Dies bedeutet, dass der zweite vorhergesagte Wert auf dem wahren Wert des ersten Tages (t+1) des Testdatensatzes basiert. Tatsรคchlich wird der wahre Wert bekannt sein.

Wenn Sie t+2 (also zwei Tage im Voraus) vorhersagen mรถchten, mรผssen Sie den vorhergesagten Wert t+1 verwenden; Wenn Sie t+3 (drei Tage im Voraus) vorhersagen mรถchten, mรผssen Sie die vorhergesagten Werte t+1 und t+2 verwenden. Es macht Sinn, dass es schwierig ist, eine genaue Vorhersage fรผr t+n Tage im Voraus zu treffen.

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)

Okay, Ihre BatchgrรถรŸe ist bereit, Sie kรถnnen die RNN-Architektur erstellen. Denken Sie daran, Sie haben 120 rekurrierende Neuronen.

Schritt 3) Erstellen Sie das Modell

Um das Modell zu erstellen, mรผssen Sie drei Teile definieren:

  1. Die Variable mit den Tensoren
  2. Das RNN
  3. Der Verlust und die Optimierung

Schritt 3.1) Variablen

Sie mรผssen die X- und Y-Variablen mit der entsprechenden Form angeben. Dieser Schritt ist trivial. Der Tensor hat die gleiche Dimension wie die Objekte X_batches und y_batches.

Beispielsweise ist der Tensor X ein Platzhalter (sehen Sie sich das Tutorial zur Einfรผhrung in an). Tensorflow um Ihre Gedanken รผber die Variablendeklaration aufzufrischen) hat drei Dimensionen:

  • Hinweis: GrรถรŸe der Charge
  • n_windows: Lรคnge der Fenster. D. h. die Hรคufigkeit, mit der das Modell nach hinten blickt
  • n_input: Anzahl der Eingaben

Das Ergebnis ist:

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])

Schritt 3.2) Erstellen Sie das RNN

Im zweiten Teil dieses RNN TensorFlow-Beispiels mรผssen Sie die Architektur des Netzwerks definieren. Wie zuvor verwenden Sie das Objekt BasicRNNCell und dynamic_rnn aus dem TensorFlow-Schรคtzer.

## 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)   

Der nรคchste Teil ist etwas kniffliger, ermรถglicht aber eine schnellere Berechnung. Sie mรผssen die Laufausgabe in eine dichte Ebene umwandeln und sie dann erneut konvertieren, damit sie dieselbe Dimension wie die Eingabe hat.

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])  

Schritt 3.3) Erstellen Sie den Verlust und die Optimierung

Die Modelloptimierung hรคngt von der Aufgabe ab, die Sie ausfรผhren. Im vorherigen Tutorial zu CNNIhr Ziel war es, Bilder zu klassifizieren. In diesem RNN-Tutorial ist das Ziel etwas anders. Sie werden gebeten, eine Vorhersage fรผr eine kontinuierliche Variable im Vergleich zu einer Klasse zu treffen.

Dieser Unterschied ist wichtig, da er das Optimierungsproblem verรคndert. Das Optimierungsproblem fรผr eine kontinuierliche Variable besteht darin, den mittleren quadratischen Fehler zu minimieren. Um diese Metriken in TF zu erstellen, kรถnnen Sie Folgendes verwenden:

  • tf.reduce_sum(tf.square(outputs โ€“ y))

Der Rest des RNN-Codes ist derselbe wie zuvor; Sie verwenden einen Adam-Optimierer, um den Verlust zu reduzieren (d. h. MSE):

  • tf.train.AdamOptimizer(learning_rate=learning_rate)
  • optimierer.minimize(Verlust)

Das war's, Sie kรถnnen alles zusammenpacken und Ihr Modell ist bereit fรผr das Training.

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() 

Sie trainieren das Modell anhand von 1500 Epochen und drucken den Verlust alle 150 Iterationen aus. Sobald das Modell trainiert ist, bewerten Sie das Modell anhand des Testsatzes und erstellen ein Objekt mit den Vorhersagen, wie im folgenden Beispiel fรผr ein rekurrentes neuronales Netzwerk gezeigt.

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

In diesem RNN Deep Learning-Tutorial kรถnnen Sie schlieรŸlich den tatsรคchlichen Wert der Reihe mit dem vorhergesagten Wert grafisch darstellen. Wenn Ihr Modell korrigiert wird, sollten die vorhergesagten Werte รผber die tatsรคchlichen Werte gesetzt werden.

Wie Sie sehen, besteht bei diesem Modell noch Verbesserungspotenzial. Sie kรถnnen die Hyperparameter wie die Fenster, die BatchgrรถรŸe oder die Anzahl der rekurrierenden Neuronen รคndern.

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()
Prognose vs. Ist

Prognose vs. Ist

Zusammenfassung

Ein rekurrentes neuronales Netzwerk ist eine robuste Architektur fรผr die Verarbeitung von Zeitreihen oder Textanalysen. Die Ausgabe des vorherigen Zustands ist eine Rรผckmeldung, um das Gedรคchtnis des Netzwerks รผber die Zeit oder Wortfolgen hinweg zu bewahren.

In TensorFlow kรถnnen Sie die folgenden Codes verwenden, um ein TensorFlow Recurrent Neural Network fรผr Zeitreihen zu trainieren:

Parameter des Modells

n_windows = 20   
n_input =  1
n_output = 1
size_train = 201

Definieren Sie das Modell

X = tf.placeholder(tf.float32, [None, n_windows, n_input])   
y = tf.placeholder(tf.float32, [None, n_windows, n_output])

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])

Konstruieren Sie die Optimierung

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)                                          

Trainiere das Modell

init = tf.global_variables_initializer() 
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})

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: