RNN (Recurrent Neural Network) Handledning: TensorFlow Exempel

Varför behöver vi ett återkommande neuralt nätverk (RNN)?

Recurrent Neural Network (RNN) låter dig modellera minnesenheter för att bevara data och modellera kortsiktiga beroenden. Det används också i tidsserieprognoser för identifiering av datakorrelationer och mönster. Det hjälper också till att producera prediktiva resultat för sekventiell data genom att leverera liknande beteende som en mänsklig hjärna.

Strukturen för ett artificiellt neuralt nätverk är relativt enkel och handlar främst om matrismultiplikation. Under det första steget multipliceras indata med initialt slumpmässiga vikter, och bias, transformeras med en aktiveringsfunktion och utgångsvärdena används för att göra en förutsägelse. Detta steg ger en uppfattning om hur långt nätverket är från verkligheten.

Det mått som används är förlusten. Ju högre förlustfunktion, desto dummare är modellen. För att förbättra kunskapen om nätverket krävs viss optimering genom att justera nätets vikter. Den stokastiska gradientnedgången är metoden som används för att ändra vikternas värden i rätt riktning. När justeringen är gjord kan nätverket använda ytterligare en sats data för att testa sin nya kunskap.

Felet är lyckligtvis lägre än tidigare, men ändå inte tillräckligt litet. Optimeringssteget görs iterativt tills felet minimeras, dvs ingen mer information kan extraheras.

Problemet med denna typ av modell är att den inte har något minne. Det betyder att ingången och utgången är oberoende. Modellen bryr sig med andra ord inte om vad som kom innan. Det väcker vissa frågor när du behöver förutsäga tidsserier eller meningar eftersom nätverket behöver ha information om historiska data eller tidigare ord.

För att lösa detta problem har en ny typ av arkitektur utvecklats: Recurrent Neural Network (RNN härefter)

Vad är ett återkommande neuralt nätverk (RNN)?

A Återkommande neurala nätverk (RNN) är en klass av Artificiellt neuralt nätverk där kopplingen mellan olika noder bildar en riktad graf för att ge ett temporalt dynamiskt beteende. Det hjälper till att modellera sekventiell data som härrör från feedforward-nätverk. Det fungerar på samma sätt som mänskliga hjärnor för att leverera prediktiva resultat.

Ett återkommande neuralt nätverk ser ganska likt ett traditionellt neuralt nätverk förutom att ett minnestillstånd läggs till neuronerna. Beräkningen för att inkludera ett minne är enkel.

Föreställ dig en enkel modell med bara en neuron som matas av en mängd data. I ett traditionellt neuralt nät producerar modellen utsignalen genom att multiplicera inmatningen med vikten och aktiveringsfunktionen. Med en RNN skickas denna utdata tillbaka till sig själv ett antal gånger. Vi ringer tidssteg den tid som utgången blir indata för nästa matrismultiplikation.

På bilden nedan kan du till exempel se att nätverket består av en neuron. Nätverket beräknar matrismultiplikationen mellan ingången och vikten och lägger till icke-linjäritet med aktiveringsfunktionen. Det blir utgången vid t-1. Denna utsignal är ingången för den andra matrismultiplikationen.

Återkommande neurala nätverk (RNN)
Återkommande neurala nätverk (RNN)

Nedan kodar vi en enkel RNN i TensorFlow för att förstå steget och även formen på utdata.

Nätverket består av:

  • Fyra ingångar
  • Sex neuroner
  • 2-gångssteg

Nätverket kommer att fortsätta som bilden nedan visar.

Återkommande neurala nätverk (RNN)

Nätverket kallas "återkommande" eftersom det utför samma operation i varje aktiveringsruta. Nätverket beräknade vikterna av ingångarna och den tidigare utsignalen innan för att använda en aktiveringsfunktion.

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 bygga nätverket med en platshållare för data, det återkommande steget och utdata.

  1. Definiera platshållaren för data
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

Här:

  • Ingen: Okänd och kommer att ta storleken på batchen
  • n_timesteps: Antal gånger nätverket kommer att skicka utdata tillbaka till neuronen
  • n_inputs: Antal input per batch
  1. Definiera det återkommande nätverket

Som nämnts i bilden ovan består nätverket av 6 neuroner. Nätverket kommer att beräkna produkt med två punkter:

  • Indata med den första uppsättningen vikter (dvs 6: lika med antalet neuroner)
  • Tidigare utdata med en andra uppsättning vikter (dvs 6: motsvarande antalet utdata)

Observera att, under den första feedforwarden, är värdena för föregående utdata lika med nollor eftersom vi inte har något tillgängligt värde.

Objektet för att bygga ett RNN är tf.contrib.rnn.BasicRNNCell med argumentet num_units för att definiera antalet indata

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

Nu när nätverket är definierat kan du beräkna utdata och tillstånd

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

Detta objekt använder en intern loop för att multiplicera matriserna ett lämpligt antal gånger.

Observera att den återkommande neuronen är en funktion av alla ingångar från de tidigare tidsstegen. Så bygger nätverket sitt eget minne. Informationen från föregående tid kan spridas i framtida tid. Detta är magin med återkommande neurala nätverk

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

I förklaringssyfte skriver du ut värdena för det tidigare tillståndet. Utmatningen ovan visar utdata från det senaste tillståndet. Skriv nu ut alla utdata, du kan märka att tillstånden är den föregående utmatningen för varje batch. Det vill säga, den föregående utdatan innehåller informationen om hela 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)

Återkommande neurala nätverk (RNN)

Utgången har formen av (3, 2, 6):

  • 3: Antal partier
  • 2: Tidsstegets nummer
  • 6: Antal neuroner

Optimeringen av ett återkommande neuralt nätverk är identiskt med ett traditionellt neuralt nätverk. Du kommer att se mer i detalj hur du kodar optimering i nästa del av denna självstudie för återkommande neurala nätverk.

Tillämpningar av RNN

RNN har flera användningsområden, särskilt när det gäller att förutsäga framtiden. Inom finansbranschen kan RNN vara till hjälp för att förutsäga aktiekurser eller tecken på börsriktningen (dvs. positiv eller negativ).

RNN är användbart för en autonom bil eftersom det kan undvika en bilolycka genom att förutse fordonets bana.

RNN används flitigt inom textanalys, bildtextning, sentimentanalys och maskinöversättning. Till exempel kan man använda en filmrecension för att förstå känslan åskådaren upplevde efter att ha sett filmen. Att automatisera denna uppgift är mycket användbart när filmbolaget inte har tillräckligt med tid att granska, märka, konsolidera och analysera recensionerna. Maskinen kan göra jobbet med högre noggrannhet.

Begränsningar för RNN

I teorin är RNN tänkt att bära informationen upp till tider. Det är dock ganska utmanande att sprida all denna information när tidssteget är för långt. När ett nätverk har för många djupa lager blir det oträningsbart. Detta problem kallas: försvinnande gradientproblem. Om du kommer ihåg uppdaterar det neurala nätverket vikten med algoritmen för gradientnedstigning. Gradienterna blir mindre när nätverket går ner till lägre lager.

Sammanfattningsvis förblir gradienterna konstanta vilket innebär att det inte finns något utrymme för förbättringar. Modellen lär sig av en förändring i gradienten; denna förändring påverkar nätverkets utdata. Men om skillnaden i gradienten är för liten (dvs vikterna ändras lite) kan nätverket inte lära sig någonting och så resultatet. Därför kan ett nätverk som står inför ett försvinnande gradientproblem inte konvergera mot en bra lösning.

Förbättring LSTM

För att övervinna den potentiella frågan om försvinnande gradient som RNN står inför, förbättrade tre forskare, Hochreiter, Schmidhuber och Bengio RNN med en arkitektur som kallas Long Short-Term Memory (LSTM). I korthet ger LSMT nätverket relevant tidigare information till nyare tid. Maskinen använder en bättre arkitektur för att välja och föra information tillbaka till senare tid.

LSTM-arkitektur är tillgänglig i TensorFlow, tf.contrib.rnn.LSTMCell. LSTM är utanför handledningens omfattning. Du kan hänvisa till tjänstemannen dokumentation för mer information

RNN i tidsserier

I den här TensorFlow RNN-handledningen kommer du att använda en RNN med tidsseriedata. Tidsserier är beroende av tidigare tid, vilket innebär att tidigare värden inkluderar relevant information som nätverket kan lära sig av. Tanken bakom tidsserieprediktion är att uppskatta det framtida värdet av en serie, låt oss säga aktiekurs, temperatur, BNP och så vidare.

Dataförberedelsen för Keras RNN och tidsserier kan vara lite knepig. Först och främst är målet att förutsäga nästa värde i serien, vilket innebär att du kommer att använda den tidigare informationen för att uppskatta värdet till t + 1. Etiketten är lika med inmatningssekvensen och flyttas en period framåt. För det andra sätts antalet inmatningar till 1, dvs en observation per gång. Slutligen är tidssteget lika med sekvensen av det numeriska värdet. Om du till exempel ställer in tidssteget till 10 kommer inmatningssekvensen tillbaka tio gånger i följd.

Titta på grafen nedan, vi har representerat tidsseriedata till vänster och en fiktiv inmatningssekvens till höger. Du skapar en funktion för att returnera en datauppsättning med slumpmässigt värde för varje dag från januari 2001 till december 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)

Produktion

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

Den högra delen av grafen visar alla serier. Det började från 2001 och slutar 2019. Det är ingen mening att mata all data i nätverket, istället måste du skapa ett parti data med en längd lika med tidssteget. Denna batch kommer att vara X-variabeln. Y-variabeln är densamma som X men förskjuten med en period (dvs du vill prognostisera t+1).

Båda vektorerna har samma längd. Du kan se det i den högra delen av grafen ovan. Linjen representerar de tio värdena för X-inmatningen, medan de röda prickarna är de tio värdena för etiketten, Y. Observera att etiketten börjar en period före X och slutar en period efter.

Bygg ett RNN för att förutsäga tidsserier i TensorFlow

Nu i denna RNN-utbildning är det dags att bygga ditt första RNN för att förutsäga serien ovan. Du måste ange några hyperparametrar (modellens parametrar, dvs antal neuroner, etc.) för modellen:

  • Antal ingångar: 1
  • Tidssteg (fönster i tidsserier): 10
  • Antal neuroner: 120
  • Antal utdata: 1

Ditt nätverk kommer att lära sig av en sekvens på 10 dagar och innehålla 120 återkommande neuroner. Du matar modellen med en ingång, dvs en dag. Ändra gärna värdena för att se om modellen förbättrats.

Innan du konstruerar modellen måste du dela upp datauppsättningen i en tåguppsättning och testuppsättning. Den fullständiga datamängden har 222 datapunkter; du kommer att använda de första 201 poängen för att träna modellen och de sista 21 poängen för att testa din modell.

När du har definierat ett tåg- och testset måste du skapa ett objekt som innehåller satserna. I dessa partier har du X-värden och Y-värden. Kom ihåg att X-värdena är en period fördröjd. Därför använder du de första 200 observationerna och tidssteget är lika med 10. X_batches-objektet ska innehålla 20 batcher av storleken 10*1. y_batches har samma form som X_batches-objektet men med en punkt framåt.

Steg 1) Skapa tåget och testa

Först och främst konverterar du serien till en numpy array; sedan definierar du fönstren (dvs. antalet gånger nätverket kommer att lära sig av), antalet ingångar, utdata och storleken på tågsetet som visas i TensorFlow RNN-exemplet nedan.

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

Efter det delar du helt enkelt upp arrayen i två datamängder.

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

Steg 2) Skapa funktionen för att returnera X_batches och y_batches

För att göra det enklare kan du skapa en funktion som returnerar två olika arrayer, en för X_batches och en för y_batches.

Låt oss skriva en RNN TensorFlow-funktion för att konstruera satserna.

Observera att X-satserna är fördröjda med en period (vi tar värdet t-1). Funktionens utdata ska ha tre dimensioner. De första måtten motsvarar antalet partier, den andra storleken på fönstren och den sista är antalet inmatade.

Det knepiga är att välja datapunkterna korrekt. För X-datapunkterna väljer du observationerna från t = 1 till t =200, medan för Y-datapunkten returnerar du observationerna från t = 2 till 201. När du väl har rätt datapunkter är det enkelt att omforma serien.

För att konstruera objektet med satserna måste du dela upp datasetet i tio satser av samma längd (dvs. 20). Du kan använda omformningsmetoden och skicka -1 så att serien liknar batchstorleken. Värdet 20 är antalet observationer per batch och 1 är antalet indata.

Du måste göra samma steg utom för etiketten.

Observera att du måste flytta data till det antal gånger du vill prognostisera. Om du till exempel vill förutsäga en tid framåt, flyttar du serien med 1. Om du vill prognostisera två dagar, flytta sedan data 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

Nu när funktionen är definierad kan du anropa den för att skapa batcherna som visas i nedanstående RNN-exempel.

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

Du kan skriva ut formen för att se till att måtten är korrekta.

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

Du behöver skapa testsetet med endast en batch data och 20 observationer.

Observera att du prognostiserar dagar efter dagar betyder att det andra förutsagda värdet kommer att baseras på det sanna värdet för den första dagen (t+1) i testdatauppsättningen. Faktum är att det verkliga värdet kommer att vara känt.

Om du vill prognostisera t+2 (dvs två dagar framåt), måste du använda det förutsagda värdet t+1; om du ska förutsäga t+3 (tre dagar framåt), måste du använda det förutsagda värdet t+1 och t+2. Det är logiskt att det är svårt att förutsäga exakt t+n dagar framåt.

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)

Okej, din batchstorlek är klar, du kan bygga RNN-arkitekturen. Kom ihåg att du har 120 återkommande neuroner.

Steg 3) Bygg modellen

För att skapa modellen måste du definiera tre delar:

  1. Variabeln med tensorerna
  2. RNN
  3. Förlusten och optimeringen

Steg 3.1) variabler

Du måste ange X- och y-variablerna med lämplig form. Detta steg är trivialt. Tensorn har samma dimension som objekten X_batches och y_batches.

Tensor X är till exempel en platshållare (kolla handledningen om Introduktion till Tensorflöde för att fräscha upp ditt sinne om variabeldeklaration) har tre dimensioner:

  • Obs: satsens storlek
  • n_windows: Fönstrens längd. dvs hur många gånger modellen tittar bakåt
  • n_input: Antal ingångar

Resultatet är:

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

Steg 3.2) Skapa RNN

I den andra delen av detta RNN TensorFlow-exempel måste du definiera nätverkets arkitektur. Som tidigare använder du objektet BasicRNNCell och dynamic_rnn från 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)   

Nästa del är lite knepigare men möjliggör snabbare beräkning. Du måste omvandla körutdata till ett tätt lager och sedan konvertera det igen för att ha samma dimension som indata.

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

Steg 3.3) Skapa förlusten och optimering

Modelloptimeringen beror på vilken uppgift du utför. I föregående handledning på CNN, ditt mål var att klassificera bilder, i denna RNN-handledning är målet något annorlunda. Du ombeds göra en förutsägelse på en kontinuerlig variabel jämfört med en klass.

Denna skillnad är viktig eftersom den kommer att förändra optimeringsproblemet. Optimeringsproblemet för en kontinuerlig variabel är att minimera medelkvadratfelet. För att konstruera dessa mätvärden i TF kan du använda:

  • tf.reduce_sum(tf.square(utgångar – y))

Resten av RNN-koden är densamma som tidigare; du använder en Adam-optimerare för att minska förlusten (dvs. MSE):

  • tf.train.AdamOptimizer(learning_rate=learning_rate)
  • optimizer.minimize(förlust)

Det är allt, du kan packa ihop allt och din modell är redo att träna.

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 kommer att träna modellen med 1500 epoker och skriva ut förlusten var 150:e iteration. När modellen är tränad utvärderar du modellen på testsetet och skapar ett objekt som innehåller förutsägelserna som visas i exemplet nedan för återkommande neurala nätverk.

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

Äntligen i denna RNN Deep Learning-handledning kan du plotta det faktiska värdet av serien med det förutsagda värdet. Om din modell är korrigerad bör de förutsagda värdena läggas ovanpå de faktiska värdena.

Som du kan se har modellen utrymme för förbättringar. Det är upp till dig att ändra hyperparametrarna som windows, batchstorleken på antalet återkommande neuroner.

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()
Prognos kontra faktisk

Prognos kontra faktisk

Sammanfattning

Ett återkommande neuralt nätverk är en robust arkitektur för att hantera tidsserier eller textanalys. Utsignalen från det tidigare tillståndet är återkoppling för att bevara nätverkets minne över tid eller sekvens av ord.

I TensorFlow kan du använda följande koder för att träna ett TensorFlow Recurrent Neural Network för tidsserier:

Modellens parametrar

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

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

Konstruera optimeringen

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)                                          

Träna 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})