RNN (Recurrent Neural Network) Opplæring: TensorFlow Eksempel

Hvorfor trenger vi et tilbakevendende nevralt nettverk (RNN)?

Recurrent Neural Network (RNN) lar deg modellere minneenheter for å vedvare data og modellere kortsiktige avhengigheter. Det brukes også i tidsserieprognoser for identifisering av datakorrelasjoner og mønstre. Det hjelper også å produsere prediktive resultater for sekvensielle data ved å levere lignende oppførsel som en menneskelig hjerne.

Strukturen til et kunstig nevralt nettverk er relativt enkel og handler hovedsakelig om matrisemultiplikasjon. I løpet av det første trinnet multipliseres innganger med innledningsvis tilfeldige vekter, og skjevhet, transformert med en aktiveringsfunksjon og utgangsverdiene brukes til å lage en prediksjon. Dette trinnet gir en ide om hvor langt nettverket er fra virkeligheten.

Beregningen som brukes er tapet. Jo høyere tapsfunksjon, jo dummere er modellen. For å forbedre kunnskapen om nettverket, kreves det noe optimalisering ved å justere vektene til nettet. Den stokastiske gradientnedstigningen er metoden som brukes for å endre verdiene til vektene i riktig retning. Når justeringen er gjort, kan nettverket bruke en annen batch med data for å teste sin nye kunnskap.

Feilen er heldigvis lavere enn før, men likevel ikke liten nok. Optimaliseringstrinnet gjøres iterativt inntil feilen er minimert, dvs. ingen mer informasjon kan trekkes ut.

Problemet med denne typen modell er at den ikke har noe minne. Det betyr at input og output er uavhengige. Modellen bryr seg med andre ord ikke om det som kom før. Det reiser noen spørsmål når du trenger å forutsi tidsserier eller setninger fordi nettverket trenger å ha informasjon om historiske data eller tidligere ord.

For å overvinne dette problemet er det utviklet en ny type arkitektur: Recurrent Neural Network (RNN heretter)

Hva er et tilbakevendende nevralt nettverk (RNN)?

A Tilbakevendende nevrale nettverk (RNN) er en klasse av Kunstig nevralt nettverk der forbindelsen mellom ulike noder danner en rettet graf for å gi en tidsmessig dynamisk oppførsel. Det hjelper å modellere sekvensielle data som er avledet fra feedforward-nettverk. Det fungerer på samme måte som menneskelige hjerner for å levere prediktive resultater.

Et tilbakevendende nevralt nettverk ser ganske likt ut som et tradisjonelt nevralt nettverk bortsett fra at en minnetilstand legges til nevronene. Beregningen for å inkludere et minne er enkel.

Se for deg en enkel modell med bare ett nevron som mates av en gruppe data. I et tradisjonelt nevralt nett produserer modellen utgangen ved å multiplisere inngangen med vekten og aktiveringsfunksjonen. Med en RNN sendes denne utgangen tilbake til seg selv antall ganger. Vi ringer tidstrinn hvor lang tid utgangen blir inngangen til neste matrisemultiplikasjon.

For eksempel, på bildet nedenfor, kan du se nettverket består av ett nevron. Nettverket beregner matrismultiplikasjonen mellom inngangen og vekten og legger til ikke-linearitet med aktiveringsfunksjonen. Det blir utgangen ved t-1. Denne utgangen er inngangen til den andre matrisemultiplikasjonen.

Tilbakevendende nevrale nettverk (RNN)
Tilbakevendende nevrale nettverk (RNN)

Nedenfor koder vi en enkel RNN i TensorFlow for å forstå trinnet og også formen på utgangen.

Nettverket består av:

  • Fire innganger
  • Seks nevroner
  • 2-gangs trinn

Nettverket vil fortsette som vist på bildet nedenfor.

Tilbakevendende nevrale nettverk (RNN)

Nettverket kalles "tilbakevendende" fordi det utfører den samme operasjonen i hver aktiveringsrute. Nettverket beregnet vektene til inngangene og den forrige utgangen før for å bruke en aktiveringsfunksjon.

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

Vi kan bygge nettverket med en plassholder for dataene, det tilbakevendende stadiet og utgangen.

  1. Definer plassholderen for dataene
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

Her:

  • Ingen: Ukjent og vil ta størrelsen på batchen
  • n_timesteps: Antall ganger nettverket vil sende utdata tilbake til nevronet
  • n_inputs: Antall input per batch
  1. Definer det tilbakevendende nettverket

Som nevnt på bildet over, er nettverket sammensatt av 6 nevroner. Nettverket vil beregne produkt med to prikker:

  • Inndata med det første settet med vekter (dvs. 6: lik antall nevroner)
  • Forrige utgang med et andre sett med vekter (dvs. 6: tilsvarende antall utdata)

Legg merke til at under den første feedforwarden er verdiene til forrige utdata lik null fordi vi ikke har noen verdi tilgjengelig.

Objektet for å bygge en RNN er tf.contrib.rnn.BasicRNNCell med argumentet num_units for å definere antall inndata

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

Nå som nettverket er definert, kan du beregne utdataene og tilstandene

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

Dette objektet bruker en intern sløyfe for å multiplisere matrisene passende antall ganger.

Legg merke til at det tilbakevendende nevronet er en funksjon av alle inngangene til de foregående tidstrinnene. Slik bygger nettverket sitt eget minne. Informasjonen fra forrige gang kan forplante seg i fremtidig tid. Dette er magien med tilbakevendende nevrale nettverk

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

For forklarende formål skriver du ut verdiene for den forrige tilstanden. Utdataene som er skrevet ut ovenfor viser utdataene fra den siste tilstanden. Skriv ut alle utdataene, du kan legge merke til at tilstandene er den forrige utgangen for hver batch. Det vil si at den forrige utgangen inneholder informasjonen om hele sekvensen.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)

Tilbakevendende nevrale nettverk (RNN)

Utgangen har formen (3, 2, 6):

  • 3: Antall partier
  • 2: Nummer på tidstrinn
  • 6: Antall nevroner

Optimaliseringen av et tilbakevendende nevralt nettverk er identisk med et tradisjonelt nevralt nettverk. Du vil se mer detaljert hvordan du koder optimalisering i neste del av denne opplæringen for gjentatte nevrale nettverk.

Søknader fra RNN

RNN har flere bruksområder, spesielt når det gjelder å forutsi fremtiden. I finansnæringen kan RNN være behjelpelig med å forutsi aksjekurser eller tegn på børsretningen (dvs. positiv eller negativ).

RNN er nyttig for en autonom bil da den kan unngå en bilulykke ved å forutse bilens bane.

RNN er mye brukt i tekstanalyse, bildeteksting, sentimentanalyse og maskinoversettelse. For eksempel kan man bruke en filmanmeldelse for å forstå følelsen tilskueren oppfattet etter å ha sett filmen. Automatisering av denne oppgaven er veldig nyttig når filmselskapet ikke har nok tid til å vurdere, merke, konsolidere og analysere anmeldelsene. Maskinen kan gjøre jobben med et høyere nivå av nøyaktighet.

Begrensninger for RNN

I teorien er RNN ment å bære informasjonen opp til tider. Det er imidlertid ganske utfordrende å spre all denne informasjonen når tidstrinnet er for langt. Når et nettverk har for mange dype lag, blir det utrenbart. Dette problemet kalles: forsvinnende gradientproblem. Hvis du husker det, oppdaterer det nevrale nettverket vekten ved å bruke algoritmen for gradientnedstigning. Gradientene blir mindre når nettverket går ned til lavere lag.

Avslutningsvis forblir gradientene konstante, noe som betyr at det ikke er rom for forbedring. Modellen lærer av en endring i gradienten; denne endringen påvirker nettverkets utgang. Men hvis forskjellen i gradienten er for liten (dvs. vektene endrer seg litt), kan ikke nettverket lære noe og dermed utgangen. Derfor kan et nettverk som står overfor et forsvinnende gradientproblem ikke konvergere mot en god løsning.

Forbedring LSTM

For å overvinne det potensielle problemet med forsvinnende gradient som RNN står overfor, forbedret tre forskere, Hochreiter, Schmidhuber og Bengio RNN med en arkitektur kalt Long Short-Term Memory (LSTM). Kort fortalt gir LSMT nettverket relevant tidligere informasjon til nyere tid. Maskinen bruker en bedre arkitektur for å velge og frakte informasjon tilbake til senere tid.

LSTM-arkitektur er tilgjengelig i TensorFlow, tf.contrib.rnn.LSTMCell. LSTM er utenfor omfanget av opplæringen. Du kan henvise til tjenestemannen dokumentasjon for mer informasjon

RNN i tidsserier

I denne TensorFlow RNN-opplæringen vil du bruke en RNN med tidsseriedata. Tidsserier er avhengige av tidligere tid, noe som betyr at tidligere verdier inkluderer relevant informasjon som nettverket kan lære av. Ideen bak tidsserieprediksjon er å estimere den fremtidige verdien av en serie, la oss si aksjekurs, temperatur, BNP og så videre.

Dataforberedelsen for Keras RNN og tidsserier kan være litt vanskelig. Først av alt er målet å forutsi neste verdi av serien, noe som betyr at du vil bruke tidligere informasjon til å estimere verdien til t + 1. Etiketten er lik inngangssekvensen og forskjøvet en periode frem. For det andre settes antall inndata til 1, dvs. én observasjon per gang. Til slutt er tidstrinnet lik rekkefølgen til den numeriske verdien. For eksempel, hvis du setter tidstrinnet til 10, vil inndatasekvensen returnere ti påfølgende ganger.

Se på grafen nedenfor, vi har representert tidsseriedata til venstre og en fiktiv inngangssekvens til høyre. Du oppretter en funksjon for å returnere et datasett med tilfeldig verdi for hver dag fra januar 2001 til desember 2016

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

Produksjon

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 i tidsserien

Høyre del av grafen viser alle serier. Det startet fra 2001 og avsluttes i 2019. Det gir ingen mening å mate alle dataene i nettverket, i stedet må du lage en batch med data med en lengde lik tidstrinnet. Denne batchen vil være X-variabelen. Y-variabelen er den samme som X, men forskjøvet med én periode (dvs. du vil forutsi t+1).

Begge vektorene har samme lengde. Du kan se det i høyre del av grafen ovenfor. Linjen representerer de ti verdiene til X-inngangen, mens de røde prikkene er de ti verdiene til etiketten, Y. Merk at etiketten starter én periode foran X og slutter én periode etter.

Bygg en RNN for å forutsi tidsserier i TensorFlow

Nå i denne RNN-treningen er det på tide å bygge ditt første RNN for å forutsi serien ovenfor. Du må spesifisere noen hyperparametre (parametrene til modellen, dvs. antall nevroner osv.) for modellen:

  • Antall innganger: 1
  • Tidstrinn (vinduer i tidsserier): 10
  • Antall nevroner: 120
  • Antall utganger: 1

Nettverket ditt vil lære av en sekvens på 10 dager og inneholde 120 tilbakevendende nevroner. Du mater modellen med én inngang, dvs. én dag. Endre gjerne verdiene for å se om modellen ble bedre.

Før du konstruerer modellen, må du dele opp datasettet i et togsett og testsett. Hele datasettet har 222 datapunkter; du vil bruke de første 201 poengene til å trene modellen og de siste 21 poengene til å teste modellen din.

Etter at du har definert et tog- og testsett, må du opprette et objekt som inneholder batchene. I denne batchen har du X-verdier og Y-verdier. Husk at X-verdiene er én periode forsinket. Derfor bruker du de første 200 observasjonene og tidstrinnet er lik 10. X_batches-objektet skal inneholde 20 batcher av størrelsen 10*1. y_batches har samme form som X_batches-objektet, men med en periode foran.

Trinn 1) Lag toget og test

Først av alt konverterer du serien til en følelsesløs array; så definerer du vinduene (dvs. antall ganger nettverket skal lære av), antall input, output og størrelsen på togsettet som vist i TensorFlow RNN-eksemplet nedenfor.

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

Etter det deler du bare arrayet i to datasett.

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

Trinn 2) Opprett funksjonen for å returnere X_batches og y_batches

For å gjøre det enklere kan du lage en funksjon som returnerer to forskjellige arrays, en for X_batches og en for y_batches.

La oss skrive en RNN TensorFlow-funksjon for å konstruere batchene.

Merk at X-partiene er etterslepet med én periode (vi tar verdien t-1). Utgangen til funksjonen skal ha tre dimensjoner. De første dimensjonene tilsvarer antall partier, den andre størrelsen på vinduene og den siste er antall inndata.

Den vanskelige delen er å velge datapunktene riktig. For X-datapunktene velger du observasjonene fra t = 1 til t =200, mens for Y-datapunktet returnerer du observasjonene fra t = 2 til 201. Når du har de riktige datapunktene, er det enkelt å omforme serien.

For å konstruere objektet med batchene, må du dele datasettet i ti batcher av samme lengde (dvs. 20). Du kan bruke omformingsmetoden og sende -1 slik at serien er lik batchstørrelsen. Verdien 20 er antall observasjoner per batch og 1 er antall inndata.

Du må gjøre det samme trinnet unntatt for etiketten.

Merk at du må flytte dataene til antall ganger du vil spå. For eksempel, hvis du ønsker å forutsi en tid fremover, så flytter du serien med 1. Hvis du vil varsle to dager, flytter du dataene med 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

Nå som funksjonen er definert, kan du kalle den for å lage batchene som vist i RNN-eksemplet nedenfor.

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

Du kan skrive ut formen for å sikre at dimensjonene er riktige.

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

Du må lage testsettet med bare én batch med data og 20 observasjoner.

Merk at du forutsetter dager etter dager, betyr at den andre anslåtte verdien vil være basert på den sanne verdien av den første dagen (t+1) i testdatasettet. Faktisk vil den sanne verdien være kjent.

Hvis du vil forutsi t+2 (dvs. to dager frem), må du bruke den anslåtte verdien t+1; hvis du skal forutsi t+3 (tre dager frem), må du bruke den anslåtte verdien t+1 og t+2. Det er fornuftig at det er vanskelig å forutsi nøyaktig t+n dager fremover.

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)

Greit, batchstørrelsen din er klar, du kan bygge RNN-arkitekturen. Husk at du har 120 tilbakevendende nevroner.

Trinn 3) Bygg modellen

For å lage modellen må du definere tre deler:

  1. Variabelen med tensorene
  2. RNN
  3. Tapet og optimaliseringen

Trinn 3.1) Variabler

Du må spesifisere X- og y-variablene med riktig form. Dette trinnet er trivielt. Tensoren har samme dimensjon som objektene X_batches og y_batches.

Tensor X er for eksempel en plassholder (Sjekk veiledningen på Introduksjon til tensorflow for å friske opp tankene dine om variabeldeklarasjon) har tre dimensjoner:

  • Merk: størrelsen på partiet
  • n_windows: Lengde på vinduene. dvs. antall ganger modellen ser bakover
  • n_input: Antall innganger

Resultatet er:

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

Trinn 3.2) Lag RNN

I den andre delen av dette RNN TensorFlow-eksemplet må du definere arkitekturen til nettverket. Som før bruker du objektet BasicRNNCell og dynamic_rnn fra TensorFlow estimator.

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

Den neste delen er litt vanskeligere, men tillater raskere beregning. Du må transformere kjøreutgangen til et tett lag og deretter konvertere den igjen for å ha samme dimensjon som inngangen.

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

Trinn 3.3) Skap tapet og optimalisering

Modelloptimaliseringen avhenger av oppgaven du utfører. I den forrige opplæringen på CNN, målet ditt var å klassifisere bilder, i denne RNN-opplæringen er målet litt annerledes. Du blir bedt om å gjøre en prediksjon på en kontinuerlig variabel sammenlignet med en klasse.

Denne forskjellen er viktig fordi den vil endre optimaliseringsproblemet. Optimaliseringsproblemet for en kontinuerlig variabel er å minimere den gjennomsnittlige kvadratfeilen. For å konstruere disse beregningene i TF, kan du bruke:

  • tf.reduce_sum(tf.square(utganger – y))

Resten av RNN-koden er den samme som før; du bruker en Adam optimizer for å redusere tapet (dvs. MSE):

  • tf.train.AdamOptimizer(learning_rate=learning_rate)
  • optimizer.minimize(tap)

Det er det, du kan pakke alt sammen, og modellen din er klar til å trene.

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

Du vil trene modellen ved å bruke 1500 epoker og skrive ut tapet hver 150. iterasjon. Når modellen er trent, evaluerer du modellen på testsettet og lager et objekt som inneholder spådommene som vist i eksemplet med gjentatte nevrale nettverk nedenfor.

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

Endelig i denne RNN Deep Learning-opplæringen kan du plotte den faktiske verdien av serien med den anslåtte verdien. Hvis modellen din er korrigert, bør de predikerte verdiene legges på toppen av de faktiske verdiene.

Som du kan se, har modellen rom for forbedring. Det er opp til deg å endre hyperparametrene som vinduene, batchstørrelsen på antall tilbakevendende nevroner.

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 kontra faktisk

Prognose kontra faktisk

Oppsummering

Et tilbakevendende nevralt nettverk er en robust arkitektur for å håndtere tidsserier eller tekstanalyse. Utgangen fra den forrige tilstanden er tilbakemelding for å bevare nettverkets minne over tid eller rekkefølge av ord.

I TensorFlow kan du bruke følgende koder for å trene opp et TensorFlow gjentatte nevrale nettverk for tidsserier:

Parametre til modellen

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

Definer modellen

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

Konstruer optimaliseringen

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)                                          

Tren modellen

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