Tutorial RNN (rede neural recorrente): exemplo do TensorFlow

Por que precisamos de uma Rede Neural Recorrente (RNN)?

Rede Neural Recorrente (RNN) permite modelar unidades de memรณria para persistir dados e modelar dependรชncias de curto prazo. Tambรฉm รฉ usado na previsรฃo de sรฉries temporais para a identificaรงรฃo de correlaรงรตes e padrรตes de dados. Tambรฉm ajuda a produzir resultados preditivos para dados sequenciais, proporcionando um comportamento semelhante ao do cรฉrebro humano.

A estrutura de uma Rede Neural Artificial รฉ relativamente simples e trata principalmente da multiplicaรงรฃo de matrizes. Durante a primeira etapa, as entradas sรฃo multiplicadas por pesos inicialmente aleatรณrios e o viรฉs รฉ transformado com uma funรงรฃo de ativaรงรฃo e os valores de saรญda sรฃo usados โ€‹โ€‹para fazer uma previsรฃo. Esta etapa dรก uma ideia de quรฃo distante a rede estรก da realidade.

A mรฉtrica aplicada รฉ a perda. Quanto maior a funรงรฃo de perda, mais burro รฉ o modelo. Para melhorar o conhecimento da rede, รฉ necessรกria alguma otimizaรงรฃo ajustando os pesos da rede. A descida gradiente estocรกstica รฉ o mรฉtodo empregado para alterar os valores dos pesos na direรงรฃo direita. Feito o ajuste, a rede pode usar outro lote de dados para testar seu novo conhecimento.

O erro, felizmente, รฉ menor do que antes, mas nรฃo รฉ pequeno o suficiente. A etapa de otimizaรงรฃo รฉ feita iterativamente atรฉ que o erro seja minimizado, ou seja, nenhuma informaรงรฃo mais possa ser extraรญda.

O problema desse tipo de modelo รฉ que ele nรฃo possui memรณria. Isso significa que a entrada e a saรญda sรฃo independentes. Em outras palavras, o modelo nรฃo se importa com o que veio antes. Isso levanta algumas questรตes quando vocรช precisa prever sรฉries temporais ou sentenรงas porque a rede precisa ter informaรงรตes sobre os dados histรณricos ou palavras anteriores.

Para superar esse problema, um novo tipo de arquitetura foi desenvolvido: Rede Neural Recorrente (doravante RNN)

O que รฉ uma rede neural recorrente (RNN)?

A Rede Neural Recorrente (RNN) รฉ uma classe de Rede neural artificial em que a conexรฃo entre diferentes nรณs forma um grรกfico direcionado para fornecer um comportamento dinรขmico temporal. Ajuda a modelar dados sequenciais derivados de redes feedforward. Funciona de forma semelhante ao cรฉrebro humano para fornecer resultados preditivos.

Uma rede neural recorrente รฉ bastante semelhante a uma rede neural tradicional, exceto que um estado de memรณria รฉ adicionado aos neurรดnios. O cรกlculo para incluir uma memรณria รฉ simples.

Imagine um modelo simples com apenas um neurรดnio alimentado por um lote de dados. Em uma rede neural tradicional, o modelo produz a saรญda multiplicando a entrada pelo peso e pela funรงรฃo de ativaรงรฃo. Com um RNN, essa saรญda รฉ enviada de volta para si mesma vรกrias vezes. Nรณs chamamos intervalo de tempo a quantidade de tempo que a saรญda se torna a entrada da prรณxima multiplicaรงรฃo da matriz.

Por exemplo, na imagem abaixo, vocรช pode ver que a rede รฉ composta por um neurรดnio. A rede calcula a multiplicaรงรฃo das matrizes entre a entrada e o peso e adiciona nรฃo linearidade com a funรงรฃo de ativaรงรฃo. Torna-se a saรญda em t-1. Esta saรญda รฉ a entrada da segunda multiplicaรงรฃo da matriz.

Rede Neural Recorrente (RNN)
Rede Neural Recorrente (RNN)

Abaixo, codificamos um RNN simples no TensorFlow para entender a etapa e tambรฉm o formato da saรญda.

A rede รฉ composta por:

  • Quatro entradas
  • Seis neurรดnios
  • Etapas de 2 vezes

A rede continuarรก conforme ilustrado na imagem abaixo.

Rede Neural Recorrente (RNN)

A rede รฉ chamada de 'recorrente' porque realiza a mesma operaรงรฃo em cada quadrado ativado. A rede calculou os pesos das entradas e da saรญda anterior antes de usar uma funรงรฃo de ativaรงรฃo.

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

Podemos construir a rede com um espaรงo reservado para os dados, o estรกgio recorrente e a saรญda.

  1. Defina o espaรงo reservado para os dados
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

Aqui:

  • Nenhum: Desconhecido e terรก o tamanho do lote
  • n_timesteps: Nรบmero de vezes que a rede enviarรก a saรญda de volta ao neurรดnio
  • n_inputs: Nรบmero de entradas por lote
  1. Defina a rede recorrente

Conforme mencionado na imagem acima, a rede รฉ composta por 6 neurรดnios. A rede calcularรก dois produtos escalares:

  • Dados de entrada com o primeiro conjunto de pesos (ou seja, 6: igual ao nรบmero de neurรดnios)
  • Saรญda anterior com um segundo conjunto de pesos (ou seja, 6: correspondente ao nรบmero de saรญda)

Observe que, durante o primeiro feedforward, os valores da saรญda anterior sรฃo iguais a zero porque nรฃo temos nenhum valor disponรญvel.

O objeto para construir um RNN รฉ tf.contrib.rnn.BasicRNNCell com o argumento num_units para definir o nรบmero de entradas

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

Agora que a rede estรก definida, vocรช pode calcular as saรญdas e estados

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

Este objeto usa um loop interno para multiplicar as matrizes o nรบmero apropriado de vezes.

Observe que o neurรดnio recorrente รฉ uma funรงรฃo de todas as entradas dos intervalos de tempo anteriores. ร‰ assim que a rede constrรณi sua prรณpria memรณria. As informaรงรตes do momento anterior podem se propagar no futuro. Esta รฉ a magia da rede neural recorrente

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

Para fins explicativos, imprima os valores do estado anterior. A saรญda impressa acima mostra a saรญda do รบltimo estado. Agora imprima toda a saรญda, vocรช pode notar que os estados sรฃo a saรญda anterior de cada lote. Ou seja, a saรญda anterior contรฉm as informaรงรตes sobre toda a sequรชncia.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)

Rede Neural Recorrente (RNN)

A saรญda tem o formato de (3, 2, 6):

  • 3: Nรบmero de lotes
  • 2: Nรบmero do intervalo de tempo
  • 6: Nรบmero de neurรดnios

A otimizaรงรฃo de uma rede neural recorrente รฉ idรชntica a uma rede neural tradicional. Vocรช verรก com mais detalhes como codificar a otimizaรงรฃo na prรณxima parte deste tutorial sobre Rede Neural Recorrente.

Aplicaรงรตes de RNN

RNN tem mรบltiplos usos, especialmente quando se trata de prever o futuro. No setor financeiro, o RNN pode ser รบtil na previsรฃo dos preรงos das aรงรตes ou no sinal da direรงรฃo do mercado de aรงรตes (ou seja, positivo ou negativo).

O RNN รฉ รบtil para um carro autรดnomo, pois pode evitar um acidente de carro antecipando a trajetรณria do veรญculo.

RNN รฉ amplamente utilizado em anรกlise de texto, legendagem de imagens, anรกlise de sentimento e traduรงรฃo automรกtica. Por exemplo, pode-se utilizar uma crรญtica de filme para compreender o sentimento que o espectador percebeu apรณs assistir ao filme. Automatizar essa tarefa รฉ muito รบtil quando a produtora cinematogrรกfica nรฃo tem tempo suficiente para revisar, rotular, consolidar e analisar as resenhas. A mรกquina pode fazer o trabalho com maior nรญvel de precisรฃo.

Limitaรงรตes do RNN

Em teoria, o RNN deveria transportar as informaรงรตes atรฉ certo ponto. No entanto, รฉ bastante desafiador propagar todas essas informaรงรตes quando o intervalo de tempo รฉ muito longo. Quando uma rede tem muitas camadas profundas, ela se torna impossรญvel de treinar. Este problema รฉ denominado: problema de gradiente de desaparecimento. Se vocรช se lembra, a rede neural atualiza o peso usando o algoritmo de gradiente descendente. Os gradientes ficam menores quando a rede progride para as camadas inferiores.

Concluindo, os gradientes permanecem constantes, o que significa que nรฃo hรก espaรงo para melhorias. O modelo aprende com uma mudanรงa no gradiente; esta mudanรงa afeta a saรญda da rede. Porรฉm, se a diferenรงa no gradiente for muito pequena (ou seja, os pesos mudam um pouco), a rede nรฃo consegue aprender nada e, portanto, a saรญda. Portanto, uma rede que enfrenta um problema de gradiente evanescente nรฃo pode convergir para uma boa soluรงรฃo.

Melhoria LSTM

Para superar o problema potencial de desaparecimento do gradiente enfrentado pelo RNN, trรชs pesquisadores, Hochreiter, Schmidhuber e Bengio melhoraram o RNN com uma arquitetura chamada Long Short-Term Memory (LSTM). Em resumo, o LSMT fornece ร  rede informaรงรตes passadas relevantes para tempos mais recentes. A mรกquina usa uma arquitetura melhor para selecionar e transportar informaรงรตes posteriormente.

A arquitetura LSTM estรก disponรญvel no TensorFlow, tf.contrib.rnn.LSTMCell. LSTM estรก fora do escopo do tutorial. Vocรช pode consultar o oficial documentaรงรฃo para mais informaรงรตes

RNN em sรฉrie temporal

Neste tutorial do TensorFlow RNN, vocรช usarรก um RNN com dados de sรฉrie temporal. As sรฉries temporais dependem do tempo anterior, o que significa que os valores passados โ€‹โ€‹incluem informaรงรตes relevantes com as quais a rede pode aprender. A ideia por trรกs da previsรฃo de sรฉries temporais รฉ estimar o valor futuro de uma sรฉrie, digamos, preรงo das aรงรตes, temperatura, PIB e assim por diante.

A preparaรงรฃo de dados para Keras RNN e sรฉries temporais pode ser um pouco complicada. Em primeiro lugar, o objetivo รฉ prever o prรณximo valor da sรฉrie, ou seja, vocรช usarรก as informaรงรตes anteriores para estimar o valor em t + 1. O rรณtulo รฉ igual ร  sequรชncia de entrada e deslocado um perรญodo ร  frente. Em segundo lugar, o nรบmero de entradas รฉ definido como 1, ou seja, uma observaรงรฃo por vez. Por รบltimo, o intervalo de tempo รฉ igual ร  sequรชncia do valor numรฉrico. Por exemplo, se vocรช definir o intervalo de tempo como 10, a sequรชncia de entrada retornarรก dez vezes consecutivas.

Observe o grรกfico abaixo, representamos os dados da sรฉrie temporal ร  esquerda e uma sequรชncia de entrada fictรญcia ร  direita. Vocรช cria uma funรงรฃo para retornar um conjunto de dados com valor aleatรณrio para cada dia de janeiro de 2001 a dezembro de 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)

saรญda

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 em sรฉries temporais

A parte direita do grรกfico mostra todas as sรฉries. Comeรงou em 2001 e termina em 2019. Nรฃo faz sentido alimentar todos os dados da rede, em vez disso, รฉ necessรกrio criar um lote de dados com comprimento igual ao intervalo de tempo. Este lote serรก a variรกvel X. A variรกvel Y รฉ igual a X, mas deslocada em um perรญodo (ou seja, vocรช deseja prever t+1).

Ambos os vetores tรชm o mesmo comprimento. Vocรช pode ver isso na parte direita do grรกfico acima. A linha representa os dez valores da entrada X, enquanto os pontos vermelhos sรฃo os dez valores do rรณtulo, Y. Observe que o rรณtulo comeรงa um perรญodo antes de X e termina um perรญodo depois.

Crie um RNN para prever sรฉries temporais no TensorFlow

Agora neste treinamento RNN, รฉ hora de construir seu primeiro RNN para prever a sรฉrie acima. Vocรช precisa especificar alguns hiperparรขmetros (os parรขmetros do modelo, ou seja, nรบmero de neurรดnios, etc.) para o modelo:

  • Nรบmero de entrada: 1
  • Intervalo de tempo (janelas em sรฉrie temporal): 10
  • Nรบmero de neurรดnios: 120
  • Nรบmero de saรญda: 1

Sua rede aprenderรก com uma sequรชncia de 10 dias e conterรก 120 neurรดnios recorrentes. Vocรช alimenta o modelo com uma entrada, ou seja, um dia. Sinta-se ร  vontade para alterar os valores para ver se o modelo melhorou.

Antes de construir o modelo, vocรช precisa dividir o conjunto de dados em um conjunto de treinamento e um conjunto de teste. O conjunto de dados completo possui 222 pontos de dados; vocรช usarรก os primeiros 201 pontos para treinar o modelo e os รบltimos 21 pontos para testar seu modelo.

Depois de definir um conjunto de treinamento e teste, vocรช precisa criar um objeto contendo os lotes. Nestes lotes, vocรช tem valores X e valores Y. Lembre-se de que os valores de X estรฃo defasados โ€‹โ€‹em um perรญodo. Portanto, vocรช usa as primeiras 200 observaรงรตes e o intervalo de tempo รฉ igual a 10. O objeto X_batches deve conter 20 lotes de tamanho 10*1. O y_batches tem o mesmo formato do objeto X_batches, mas com um ponto ร  frente.

Passo 1) Crie o trem e teste

Primeiro de tudo, vocรช converte a sรฉrie em um numpy variedade; em seguida, vocรช define as janelas (ou seja, o nรบmero de tempo com o qual a rede aprenderรก), o nรบmero de entradas, saรญdas e o tamanho do conjunto de trens, conforme mostrado no exemplo do TensorFlow RNN abaixo.

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

Depois disso, basta dividir o array em dois conjuntos de dados.

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

Passo 2) Crie a funรงรฃo para retornar X_batches e y_batches

Para facilitar, vocรช pode criar uma funรงรฃo que retorne dois arrays diferentes, um para X_batches e outro para y_batches.

Vamos escrever uma funรงรฃo RNN TensorFlow para construir os lotes.

Observe que os lotes X estรฃo defasados โ€‹โ€‹โ€‹โ€‹de um perรญodo (assumimos o valor t-1). A saรญda da funรงรฃo deve ter trรชs dimensรตes. As primeiras dimensรตes equivalem ao nรบmero de lotes, a segunda ao tamanho das janelas e a รบltima ao nรบmero de entradas.

A parte complicada รฉ selecionar os pontos de dados corretamente. Para os pontos de dados X, vocรช escolhe as observaรงรตes de t = 1 a t = 200, enquanto para o ponto de dados Y, vocรช retorna as observaรงรตes de t = 2 a 201. Depois de ter os pontos de dados corretos, รฉ simples remodelar as sรฉries.

Para construir o objeto com os lotes, vocรช precisa dividir o conjunto de dados em dez lotes de igual comprimento (ou seja, 20). Vocรช pode usar o mรฉtodo reshape e passar -1 para que a sรฉrie seja semelhante ao tamanho do lote. O valor 20 รฉ o nรบmero de observaรงรตes por lote e 1 รฉ o nรบmero de entradas.

Vocรช precisa fazer o mesmo passo, mas para o rรณtulo.

Observe que vocรช precisa mudar os dados para o nรบmero de vezes que deseja prever. Por exemplo, se vocรช quiser prever um tempo de antecedรชncia, mude a sรฉrie em 1. Se quiser prever dois dias, mude os dados em 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

Agora que a funรงรฃo estรก definida, vocรช pode chamรก-la para criar os lotes conforme mostrado no exemplo RNN abaixo.

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

Vocรช pode imprimir a forma para ter certeza de que as dimensรตes estรฃo corretas.

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

Vocรช precisa criar o conjunto de testes com apenas um lote de dados e 20 observaรงรตes.

Observe que, se vocรช prevรช dias apรณs dias, isso significa que o segundo valor previsto serรก baseado no valor verdadeiro do primeiro dia (t+1) do conjunto de dados de teste. Na verdade, o verdadeiro valor serรก conhecido.

Se vocรช deseja prever t+2 (ou seja, dois dias antes), vocรช precisa usar o valor previsto t+1; se vocรช pretende prever t+3 (trรชs dias ร  frente), precisarรก usar o valor previsto t+1 e t+2. Faz sentido que seja difรญcil prever com precisรฃo t+n dias ร  frente.

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)

Tudo bem, o tamanho do seu lote estรก pronto, vocรช pode construir a arquitetura RNN. Lembre-se, vocรช tem 120 neurรดnios recorrentes.

Passo 3) Construa o modelo

Para criar o modelo, vocรช precisa definir trรชs partes:

  1. A variรกvel com os tensores
  2. O RNN
  3. A perda e otimizaรงรฃo

Passo 3.1) Variรกveis

Vocรช precisa especificar as variรกveis โ€‹โ€‹Xey com a forma apropriada. Esta etapa รฉ trivial. O tensor tem a mesma dimensรฃo dos objetos X_batches e y_batches.

Por exemplo, o tensor X รฉ um espaรงo reservado (confira o tutorial Introduรงรฃo ao Tensorflow para refrescar sua mente sobre a declaraรงรฃo de variรกveis) tem trรชs dimensรตes:

  • Obs: tamanho do lote
  • n_windows: Comprimento das janelas. ou seja, o nรบmero de vezes que o modelo olha para trรกs
  • n_input: Nรบmero de entrada

O resultado รฉ:

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

Passo 3.2) Crie o RNN

Na segunda parte deste exemplo RNN do TensorFlow, vocรช precisa definir a arquitetura da rede. Como antes, vocรช usa o objeto BasicRNNCell e dynamic_rnn do estimador TensorFlow.

## 2. create the model
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)   
rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)   

A prรณxima parte รฉ um pouco mais complicada, mas permite cรกlculos mais rรกpidos. Vocรช precisa transformar a saรญda da execuรงรฃo em uma camada densa e depois convertรช-la novamente para ter a mesma dimensรฃo da entrada.

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

Passo 3.3) Crie a perda e a otimizaรงรฃo

A otimizaรงรฃo do modelo depende da tarefa que vocรช estรก executando. No tutorial anterior sobre CNN, seu objetivo era classificar imagens, neste tutorial da RNN o objetivo รฉ um pouco diferente. Vocรช รฉ solicitado a fazer uma previsรฃo sobre uma variรกvel contรญnua comparada a uma classe.

Essa diferenรงa รฉ importante porque mudarรก o problema de otimizaรงรฃo. O problema de otimizaรงรฃo para uma variรกvel contรญnua รฉ minimizar o erro quadrรกtico mรฉdio. Para construir essas mรฉtricas no TF, vocรช pode usar:

  • tf.reduce_sum(tf.square(saรญdas โ€“ y))

O restante do cรณdigo RNN รฉ o mesmo de antes; vocรช usa um otimizador Adam para reduzir a perda (ou seja, MSE):

  • tf.train.AdamOptimizer(learning_rate=learning_rate)
  • otimizador.minimize(perda)

ร‰ isso, vocรช pode embalar tudo e seu modelo estรก pronto para treinar.

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

Vocรช treinarรก o modelo usando 1500 รฉpocas e imprimirรก a perda a cada 150 iteraรงรตes. Depois que o modelo for treinado, vocรช avalia o modelo no conjunto de teste e cria um objeto contendo as previsรตes, conforme mostrado no exemplo de rede neural recorrente abaixo.

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

Por fim, neste tutorial RNN Deep Learning, vocรช pode traรงar o valor real da sรฉrie com o valor previsto. Se o seu modelo for corrigido, os valores previstos deverรฃo ser colocados acima dos valores reais.

Como vocรช pode ver, o modelo pode ser melhorado. Cabe a vocรช alterar os hiperparรขmetros como as janelas, o tamanho do lote e o nรบmero de neurรดnios recorrentes.

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()
Previsรฃo versus Real

Previsรฃo versus Real

Resumo

Uma rede neural recorrente รฉ uma arquitetura robusta para lidar com sรฉries temporais ou anรกlise de texto. A saรญda do estado anterior รฉ um feedback para preservar a memรณria da rede ao longo do tempo ou sequรชncia de palavras.

No TensorFlow, vocรช pode usar os seguintes cรณdigos para treinar uma rede neural recorrente do TensorFlow para sรฉries temporais:

Parรขmetros do modelo

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

Defina o modelo

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

Construa a otimizaรงรฃo

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)                                          

Treine o modelo

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

Resuma esta postagem com: