RNN (Recurrent Neural Network) -opetusohjelma: TensorFlow-esimerkki

Miksi tarvitsemme toistuvan hermoverkon (RNN)?

Recurrent Neural Network (RNN) mahdollistaa muistiyksiköiden mallintamisen pysyviä tietoja varten ja lyhytaikaisten riippuvuuksien mallintamisen. Sitä käytetään myös aikasarjaennusteissa tietojen korrelaatioiden ja kuvioiden tunnistamiseen. Se auttaa myös tuottamaan ennustavia tuloksia peräkkäisille tiedoille toimittamalla samanlaista käyttäytymistä kuin ihmisen aivot.

Keinotekoisen hermoverkon rakenne on suhteellisen yksinkertainen ja liittyy pääasiassa matriisikertomiseen. Ensimmäisessä vaiheessa tulot kerrotaan alun perin satunnaisilla painoilla ja bias, muunnetaan aktivointifunktiolla ja lähtöarvoja käytetään ennusteen tekemiseen. Tämä vaihe antaa käsityksen siitä, kuinka kaukana verkko on todellisuudesta.

Käytetty mittari on tappio. Mitä suurempi häviöfunktio, sitä typerämpi malli on. Verkon tuntemuksen parantamiseksi tarvitaan jonkin verran optimointia säätämällä verkon painoja. Stokastinen gradienttilasku on menetelmä, jota käytetään painojen arvojen muuttamiseksi oikeaan suuntaan. Kun säätö on tehty, verkko voi testata uutta tietoaan toisella tietoerällä.

Virhe on onneksi pienempi kuin ennen, mutta ei kuitenkaan tarpeeksi pieni. Optimointivaihetta tehdään iteratiivisesti, kunnes virhe on minimoitu, eli informaatiota ei voida poimia enempää.

Tämän tyyppisen mallin ongelmana on, että siinä ei ole muistia. Se tarkoittaa, että tulo ja lähtö ovat riippumattomia. Toisin sanoen malli ei välitä siitä, mitä oli ennen. Se herättää kysymyksiä, kun sinun täytyy ennustaa aikasarjoja tai lauseita, koska verkossa on oltava tietoa historiallisista tiedoista tai menneistä sanoista.

Tämän ongelman ratkaisemiseksi on kehitetty uudenlainen arkkitehtuuri: Recurrent Neural network (RNN, jäljempänä)

Mikä on toistuva hermoverkko (RNN)?

A Toistuva hermoverkko (RNN) on luokkaa Keinotekoinen hermoverkko jossa eri solmujen välinen yhteys muodostaa suunnatun graafin antamaan ajallisen dynaamisen käyttäytymisen. Se auttaa mallintamaan peräkkäistä dataa, joka on johdettu myötäkytkentäverkoista. Se toimii samalla tavalla kuin ihmisen aivot ja tuottaa ennakoivia tuloksia.

Toistuva hermoverkko näyttää melko samanlaiselta kuin perinteinen hermoverkko, paitsi että neuroneille lisätään muistitila. Muistin lisääminen on yksinkertaista.

Kuvittele yksinkertainen malli, jossa vain yksi neuroni syöttää dataerän. Perinteisessä hermoverkossa malli tuottaa lähdön kertomalla syötteen painolla ja aktivointifunktiolla. RNN:llä tämä lähtö lähetetään takaisin itselleen monta kertaa. Kutsumme aika askel aika, jonka lähdöstä tulee seuraavan matriisin kertolaskutulo.

Esimerkiksi alla olevassa kuvassa näet, että verkko koostuu yhdestä neuronista. Verkko laskee syötteen ja painon väliset matriisikertoimet ja lisää epälineaarisuuden aktivointifunktiolla. Siitä tulee lähtö t-1:ssä. Tämä lähtö on toisen matriisikertolaskun tulo.

Toistuva hermoverkko (RNN)
Toistuva hermoverkko (RNN)

Alla koodaamme yksinkertaisen RNN:n TensorFlow'ssa ymmärtääksemme vaiheen ja myös lähdön muodon.

Verkko koostuu:

  • Neljä tuloa
  • Kuusi neuronia
  • 2-kertaiset askeleet

Verkko toimii alla olevan kuvan mukaisesti.

Toistuva hermoverkko (RNN)

Verkkoa kutsutaan "toistuvaksi", koska se suorittaa saman toiminnon jokaisessa aktivointiruudussa. Verkko laski tulojen ja edellisen lähdön painot ennen aktivointitoiminnon käyttöä.

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

Voimme rakentaa verkon käyttämällä paikkamerkkiä datalle, toistuvalle vaiheelle ja ulostulolle.

  1. Määritä tiedoille paikkamerkki
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

Tässä:

  • Ei mitään: Tuntematon ja kestää erän koon
  • n_timesteps: Kuinka monta kertaa verkko lähettää ulostulon takaisin neuroniin
  • n_inputs: Syötteiden lukumäärä erää kohti
  1. Määritä toistuva verkko

Kuten yllä olevassa kuvassa mainittiin, verkko koostuu kuudesta neuronista. Verkko laskee kahden pisteen tuotteen:

  • Syötä tiedot ensimmäisellä painosarjalla (eli 6: yhtä suuri kuin neuronien lukumäärä)
  • Edellinen tulos toisella painosarjalla (eli 6: vastaa tulosteiden määrää)

Huomaa, että ensimmäisen myötäkytkennän aikana edellisen lähdön arvot ovat nollia, koska arvoja ei ole saatavilla.

RNN:n luomisobjekti on tf.contrib.rnn.BasicRNNCell argumentilla num_units, joka määrittää syötteiden määrän

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

Nyt kun verkko on määritetty, voit laskea lähdöt ja tilat

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

Tämä objekti käyttää sisäistä silmukkaa kertomaan matriisit sopivan määrän kertoja.

Huomaa, että toistuva neuroni on kaikkien edellisten aikavaiheiden syötteiden funktio. Näin verkko rakentaa oman muistinsa. Edellisen ajan tiedot voivat levitä tulevassa ajassa. Tämä on toistuvan hermoverkon taika

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

Selvitystarkoituksessa tulostat edellisen tilan arvot. Yllä tulostettu tulos näyttää tulosteen viimeisestä tilasta. Tulosta nyt kaikki tulosteet, voit huomata, että tilat ovat kunkin erän edellinen tulos. Eli edellinen tulos sisältää tiedot koko sekvenssistä.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)

Toistuva hermoverkko (RNN)

Tulosteen muoto on (3, 2, 6):

  • 3: Erien lukumäärä
  • 2: Aikavaiheen numero
  • 6: Hermosolujen lukumäärä

Toistuvan hermoverkon optimointi on identtinen perinteisen hermoverkon kanssa. Näet yksityiskohtaisemmin kuinka optimoida koodi tämän toistuvan hermoverkon opetusohjelman seuraavassa osassa.

RNN:n sovellukset

RNN:llä on useita käyttötarkoituksia, varsinkin kun on kyse tulevaisuuden ennustamisesta. Rahoitusalalla RNN:stä voi olla apua osakekurssien tai osakemarkkinoiden suunnan (eli positiivisen tai negatiivisen) merkkien ennustamisessa.

RNN on hyödyllinen autonomiselle autolle, koska se voi välttää auto-onnettomuuden ennakoimalla ajoneuvon liikeradan.

RNN:tä käytetään laajalti tekstianalyysissä, kuvien tekstityksissä, tunneanalyysissä ja konekäännöksissä. Esimerkiksi elokuva-arvostelun avulla voidaan ymmärtää tunnetta, jonka katsoja koki elokuvan katsomisen jälkeen. Tämän tehtävän automatisointi on erittäin hyödyllistä, kun elokuvayhtiöllä ei ole tarpeeksi aikaa arvioida, merkitä, yhdistää ja analysoida arvosteluja. Kone pystyy suorittamaan työn korkeammalla tarkkuudella.

RNN:n rajoitukset

Teoriassa RNN:n oletetaan kuljettavan tietoa aikojaan. On kuitenkin melko haastavaa levittää kaikkea tätä tietoa, kun aikavaihe on liian pitkä. Kun verkossa on liian monta syvää kerrosta, siitä tulee kouluttamaton. Tätä ongelmaa kutsutaan: häviävä kaltevuusongelma. Jos muistat, hermoverkko päivittää painon gradientin laskeutumisalgoritmin avulla. Gradientit pienenevät, kun verkko etenee alemmille tasoille.

Yhteenvetona voidaan todeta, että gradientit pysyvät vakiona, mikä tarkoittaa, että parantamisen varaa ei ole. Malli oppii gradientin muutoksesta; tämä muutos vaikuttaa verkon lähtöön. Jos ero gradientissa on kuitenkin liian pieni (eli painot muuttuvat hieman), verkko ei voi oppia mitään ja siten tulos. Siksi verkko, joka kohtaa katoavan gradienttiongelman, ei voi konvergoida kohti hyvää ratkaisua.

LSTM:n parannus

Kolme tutkijaa, Hochreiter, Schmidhuber ja Bengio, paransivat RNN:ää arkkitehtuurilla, jota kutsutaan nimellä Long Short-Term Memory (LSTM). Lyhyesti sanottuna LSMT tarjoaa verkolle relevanttia menneisyyttä uudempaan aikaan. Kone käyttää parempaa arkkitehtuuria tietojen valitsemiseen ja siirtämiseen myöhempään aikaan.

LSTM-arkkitehtuuri on saatavilla TensorFlow:ssa, tf.contrib.rnn.LSTMCell. LSTM ei kuulu opetusohjelman piiriin. Voit viitata virkamiehelle dokumentointi lisätietoja

RNN aikasarjassa

Tässä TensorFlow RNN -opetusohjelmassa käytät RNN:tä aikasarjatietojen kanssa. Aikasarjat ovat riippuvaisia ​​edellisestä ajasta, mikä tarkoittaa, että aikaisemmat arvot sisältävät oleellista tietoa, josta verkko voi oppia. Aikasarjaennustuksen ideana on arvioida sarjan tuleva arvo, esimerkiksi osakekurssi, lämpötila, BKT ja niin edelleen.

Keras RNN:n ja aikasarjojen tietojen valmistelu voi olla hieman hankalaa. Ensinnäkin tavoitteena on ennustaa sarjan seuraava arvo, mikä tarkoittaa, että käytät aiempia tietoja arvon estimoimiseen kohdassa t + 1. Tunniste on yhtä suuri kuin syöttösekvenssi ja siirretty jakso eteenpäin. Toiseksi syötteiden määräksi asetetaan 1, eli yksi havainto kerrallaan. Lopuksi aikaaskel on yhtä suuri kuin numeerisen arvon sekvenssi. Jos esimerkiksi asetat aikaaskeleeksi 10, syöttösekvenssi palauttaa kymmenen kertaa peräkkäin.

Katso alla olevaa kaaviota, olemme esittäneet aikasarjadataa vasemmalla ja kuvitteellista syöttösekvenssiä oikealla. Luot funktion, joka palauttaa tietojoukon satunnaisella arvolla jokaiselle päivälle tammikuusta 2001 joulukuuhun 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)

ulostulo

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 aikasarjassa

Kaavion oikea osa näyttää kaikki sarjat. Se alkoi vuodesta 2001 ja päättyy vuonna 2019 Ei ole mitään järkeä syöttää kaikkea verkossa olevaa dataa, vaan sinun on luotava tietojoukko, jonka pituus on yhtä pitkä kuin aika-askel. Tämä erä on X-muuttuja. Y-muuttuja on sama kuin X, mutta siirtynyt yhdellä jaksolla (ts. haluat ennustaa t+1).

Molemmilla vektoreilla on sama pituus. Näet sen yllä olevan kaavion oikealla puolella. Viiva edustaa X-syötteen kymmentä arvoa, kun taas punaiset pisteet ovat tunnisteen Y kymmentä arvoa. Huomaa, että tarra alkaa yhden pisteen X:n edellä ja päättyy yhden pisteen jälkeen.

Rakenna RNN ennustaaksesi aikasarjan TensorFlow'ssa

Nyt tässä RNN-koulutuksessa on aika rakentaa ensimmäinen RNN ennustaaksesi yllä olevan sarjan. Sinun on määritettävä mallille joitain hyperparametreja (mallin parametrit, eli neuronien lukumäärä jne.):

  • Tulojen määrä: 1
  • Aikaaskel (ikkunat aikasarjassa): 10
  • Hermosolujen lukumäärä: 120
  • Tulosteiden määrä: 1

Verkkosi oppii 10 päivän jaksosta ja sisältää 120 toistuvaa neuronia. Syötät mallin yhdellä syötteellä eli yhdellä päivällä. Voit vapaasti muuttaa arvoja nähdäksesi, onko malli parantunut.

Ennen mallin rakentamista sinun on jaettava tietojoukko junajoukoksi ja testijoukoksi. Koko tietojoukossa on 222 datapistettä; käytät ensimmäistä 201 pistettä mallin kouluttamiseen ja viimeiset 21 pistettä mallin testaamiseen.

Kun olet määrittänyt junan ja testijoukon, sinun on luotava erät sisältävä objekti. Tässä erässä sinulla on X-arvot ja Y-arvot. Muista, että X-arvot ovat yhden jakson jälkeen. Siksi käytät ensimmäiset 200 havaintoa ja aikaaskel on 10. X_batches-objektin tulee sisältää 20 erää, joiden koko on 10*1. Y_batches-objektilla on sama muoto kuin X_batches-objektilla, mutta siinä on yksi jakso eteenpäin.

Vaihe 1) Luo juna ja testaa

Ensinnäkin muutat sarjan a numpy joukko; sitten määrität ikkunat (eli kuinka monta kertaa verkko oppii), syötteiden, lähdön ja junajoukon koon alla olevan TensorFlow RNN -esimerkin mukaisesti.

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

Sen jälkeen jaat taulukon kahdeksi tietojoukoksi.

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

Vaihe 2) Luo funktio palauttamaan X_batches ja y_batches

Helpottaaksesi voit luoda funktion, joka palauttaa kaksi erilaista taulukkoa, yhden X_batchesille ja toisen y_batchesille.

Kirjoitetaan RNN TensorFlow -funktio eräiden muodostamiseksi.

Huomaa, että X erät ovat yhden jakson viiveellä (otamme arvon t-1). Funktion tulosteen tulee olla kolmiulotteinen. Ensimmäiset mitat vastaavat erien määrää, toinen ikkunoiden kokoa ja viimeinen syötteiden lukumäärää.

Hankala osa on valita datapisteet oikein. X-datapisteille valitset havainnot välillä t = 1 - t =200, kun taas Y-datapisteelle palautat havainnot arvosta t = 2 arvoon 201. Kun sinulla on oikeat datapisteet, on helppo muotoilla uudelleen. sarja.

Jotta voit rakentaa objektin erien kanssa, sinun on jaettava tietojoukko kymmeneen yhtä pitkäksi eräksi (eli 20). Voit käyttää uudelleenmuotoilumenetelmää ja ohittaa -1, jotta sarja on samanlainen kuin eräkoko. Arvo 20 on havaintojen määrä erää kohti ja 1 on syötteiden lukumäärä.

Sinun on tehtävä sama vaihe, mutta etikettiä varten.

Huomaa, että sinun on siirrettävä tietoja niin monta kertaa kuin haluat ennustaa. Jos esimerkiksi haluat ennustaa yhden ajan eteenpäin, siirrä sarjaa 1:llä. Jos haluat ennustaa kaksi päivää, siirrä tietoja kahdella.

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

Nyt kun funktio on määritetty, voit kutsua sitä luodaksesi erät alla olevan RNN-esimerkin mukaisesti.

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

Voit tulostaa muodon varmistaaksesi, että mitat ovat oikein.

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

Sinun on luotava testisarja, jossa on vain yksi tietoerä ja 20 havaintoa.

Huomaa, että ennustat päivistä toiseen, se tarkoittaa, että toinen ennustettu arvo perustuu testitietojoukon ensimmäisen päivän todelliseen arvoon (t+1). Itse asiassa todellinen arvo tiedetään.

Jos haluat ennustaa t+2 (eli kaksi päivää eteenpäin), sinun on käytettävä ennustettua arvoa t+1; jos aiot ennustaa t+3 (kolme päivää eteenpäin), sinun on käytettävä ennustettua arvoa t+1 ja t+2. On järkevää, että on vaikea ennustaa tarkasti t+n päivää eteenpäin.

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)

Selvä, eräkokosi on valmis, voit rakentaa RNN-arkkitehtuurin. Muista, että sinulla on 120 toistuvaa neuronia.

Vaihe 3) Rakenna malli

Mallin luomiseksi sinun on määritettävä kolme osaa:

  1. Muuttuja tensoreiden kanssa
  2. RNN
  3. Häviö ja optimointi

Vaihe 3.1) Muuttujat

Sinun on määritettävä X- ja y-muuttujat sopivalla muodolla. Tämä vaihe on triviaali. Tensorilla on sama ulottuvuus kuin objekteilla X_batches ja y_batches.

Esimerkiksi tensori X on paikkamerkki (Katso opetusohjelma kohdasta Johdanto Tensorflow virkistääksesi mieltäsi muuttujamäärityksestä) on kolme ulottuvuutta:

  • Huomautus: erän koko
  • n_windows: Ikkunoiden pituus. eli kuinka monta kertaa malli katsoo taaksepäin
  • n_input: Tulon määrä

Tulos on:

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

Vaihe 3.2) Luo RNN

Tämän RNN TensorFlow -esimerkin toisessa osassa sinun on määritettävä verkon arkkitehtuuri. Kuten ennenkin, käytät TensorFlow-estimaattorin objektia BasicRNNCell ja dynamic_rnn.

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

Seuraava osa on hieman hankalampi, mutta mahdollistaa nopeamman laskennan. Sinun on muutettava ajon tulos tiheäksi kerrokseksi ja muutettava se sitten uudelleen niin, että sillä on sama mitta kuin tulolla.

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

Vaihe 3.3) Luo menetys ja optimointi

Mallin optimointi riippuu suorittamastasi tehtävästä. Edellisessä opetusohjelmassa CNN, tavoitteesi oli luokitella kuvat, tässä RNN-opetusohjelmassa tavoite on hieman erilainen. Sinua pyydetään tekemään ennuste jatkuvasta muuttujasta verrattuna luokkaan.

Tämä ero on tärkeä, koska se muuttaa optimointiongelman. Jatkuvan muuttujan optimointiongelma on minimoida keskineliövirhe. Näiden mittareiden muodostamiseksi TF:ssä voit käyttää:

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

Loppuosa RNN-koodista on sama kuin ennen; käytät Adam-optimointiohjelmaa häviön vähentämiseksi (eli MSE):

  • tf.train.AdamOptimizer(learning_rate=oppimisnopeus)
  • optimoija.minimize(tappio)

Siinä kaikki, voit pakata kaiken yhteen ja mallisi on valmis harjoitteluun.

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

Harjoittelet mallia käyttämällä 1500 jaksoa ja tulostat häviön joka 150. iteraatio. Kun malli on koulutettu, arvioit mallin testijoukossa ja luot objektin, joka sisältää ennusteet alla olevan Toistuvan hermoverkon esimerkin mukaisesti.

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

Viimeinkin tässä RNN Deep Learning -opetusohjelmassa voit piirtää sarjan todellisen arvon ennustetulla arvolla. Jos malliasi korjataan, ennustetut arvot tulee laittaa todellisten arvojen päälle.

Kuten näette, mallissa on parantamisen varaa. Sinun tehtäväsi on muuttaa hyperparametrejä, kuten ikkunoita, toistuvien hermosolujen lukumäärän eräkokoa.

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()
Ennuste vs todellinen

Ennuste vs todellinen

Yhteenveto

Toistuva neuroverkko on vankka arkkitehtuuri, joka käsittelee aikasarjoja tai tekstianalyysiä. Edellisen tilan tulos on palaute verkon muistin säilyttämiseksi ajan tai sanajonon aikana.

TensorFlow'ssa voit käyttää seuraavia koodeja kouluttaaksesi TensorFlow'n toistuvaa hermoverkkoa aikasarjoille:

Mallin parametrit

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

Määrittele malli

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

Rakenna optimointi

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)                                          

Harjoittele mallia

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