RNN(반복 신경망) 튜토리얼: TensorFlow 예제

순환 신경망(RNN)이 필요한 이유는 무엇입니까?

RNN(Recurrent Neural Network)을 사용하면 메모리 단위를 모델링하여 데이터를 유지하고 단기 종속성을 모델링할 수 있습니다. 또한 데이터 상관관계 및 패턴을 식별하기 위해 시계열 예측에도 사용됩니다. 또한 인간의 뇌와 유사한 행동을 전달하여 순차적 데이터에 대한 예측 결과를 생성하는 데 도움이 됩니다.

인공 신경망의 구조는 비교적 간단하며 주로 행렬 곱셈에 관한 것입니다. 첫 번째 단계에서는 입력에 초기 무작위 가중치와 편향을 곱하고 활성화 함수로 변환하고 출력 값을 사용하여 예측을 수행합니다. 이 단계는 네트워크가 현실과 얼마나 멀리 떨어져 있는지에 대한 아이디어를 제공합니다.

적용된 메트릭은 손실입니다. 손실 함수가 높을수록 모델은 더 멍청해집니다. 네트워크의 지식을 개선하려면 네트워크의 가중치를 조정하여 일부 최적화가 필요합니다. 확률적 경사 하강법은 가중치 값을 올바른 방향으로 변경하는 데 사용되는 방법입니다. 조정이 완료되면 네트워크는 다른 데이터 배치를 사용하여 새로운 지식을 테스트할 수 있습니다.

다행스럽게도 오류는 이전보다 낮지만 충분히 작지는 않습니다. 최적화 단계는 오류가 최소화될 때까지, 즉 더 이상 정보를 추출할 수 없을 때까지 반복적으로 수행됩니다.

이러한 유형의 모델의 문제점은 메모리가 없다는 것입니다. 이는 입력과 출력이 독립적이라는 것을 의미합니다. 즉, 모델은 이전에 나온 내용에 신경 쓰지 않습니다. 네트워크에는 과거 데이터나 과거 단어에 대한 정보가 필요하기 때문에 시계열이나 문장을 예측해야 할 때 몇 가지 의문이 제기됩니다.

이 문제를 극복하기 위해 새로운 유형의 아키텍처가 개발되었습니다. 즉, 순환 신경망(RNN)입니다.

순환 신경망(RNN)이란 무엇입니까?

A 반복 신경망 (RNN) 의 클래스입니다 인공 신경망 서로 다른 노드 간의 연결이 방향성 그래프를 형성하여 시간적 동적 동작을 제공합니다. 피드포워드 네트워크에서 파생된 순차 데이터를 모델링하는 데 도움이 됩니다. 예측 결과를 제공하기 위해 인간의 두뇌와 유사하게 작동합니다.

순환 신경망은 뉴런에 메모리 상태가 추가된다는 점을 제외하면 기존 신경망과 매우 유사해 보입니다. 메모리를 포함하는 계산은 간단합니다.

일련의 데이터를 하나의 뉴런으로만 공급하는 간단한 모델을 상상해 보십시오. 전통적인 신경망에서 모델은 입력에 가중치와 활성화 함수를 곱하여 출력을 생성합니다. RNN을 사용하면 이 출력이 여러 번 자체로 다시 전송됩니다. 우리는 전화한다 타임 스텝 출력이 다음 행렬 곱셈의 입력이 되는 시간입니다.

예를 들어, 아래 그림에서는 네트워크가 하나의 뉴런으로 구성되어 있음을 볼 수 있습니다. 네트워크는 입력과 가중치 사이의 행렬 곱셈을 계산하고 활성화 함수를 사용하여 비선형성을 추가합니다. t-1의 출력이 됩니다. 이 출력은 두 번째 행렬 곱셈의 입력입니다.

반복 신경망 (RNN)
반복 신경망 (RNN)

아래에서는 TensorFlow에서 간단한 RNN을 코딩하여 출력의 단계와 모양을 이해합니다.

네트워크는 다음으로 구성됩니다:

  • XNUMX개의 입력
  • XNUMX개의 뉴런
  • 2단계

아래 그림과 같이 네트워크가 진행됩니다.

반복 신경망 (RNN)

이 네트워크는 각 활성화 사각형에서 동일한 작업을 수행하기 때문에 '순환'이라고 불립니다. 이 네트워크는 활성화 함수를 사용하기 전에 입력과 이전 출력의 가중치를 계산했습니다.

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

데이터, 반복 단계 및 출력에 대한 자리 표시자를 사용하여 네트워크를 구축할 수 있습니다.

  1. 데이터의 자리 표시자 정의
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

이리:

  • 없음: 알 수 없으며 배치 크기를 사용합니다.
  • n_timesteps: 네트워크가 출력을 뉴런으로 다시 보내는 횟수
  • n_inputs: 배치당 입력 수
  1. 순환 네트워크 정의

위 그림에서 언급한 것처럼 네트워크는 6개의 뉴런으로 구성됩니다. 네트워크는 두 개의 내적을 계산합니다.

  • 첫 번째 가중치 세트가 있는 입력 데이터(예: 6: 뉴런 수와 동일)
  • 두 번째 가중치 세트를 사용한 이전 출력(예: 6: 출력 수에 해당)

첫 번째 피드포워드 동안 사용 가능한 값이 없기 때문에 이전 출력 값은 XNUMX과 같습니다.

RNN을 구축하는 객체는 tf.contrib.rnn.BasicRNNCell이며 입력 수를 정의하는 인수 num_units가 있습니다.

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

이제 네트워크가 정의되었으므로 출력과 상태를 계산할 수 있습니다.

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

이 객체는 내부 루프를 사용하여 행렬에 적절한 횟수를 곱합니다.

순환 뉴런은 이전 시간 단계의 모든 입력에 대한 함수입니다. 이것이 네트워크가 자체 메모리를 구축하는 방법입니다. 이전 시간의 정보는 미래 시간에도 전파될 수 있습니다. 이것이 순환 신경망의 마법입니다

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

설명을 위해 이전 상태의 값을 인쇄합니다. 위에 인쇄된 출력은 마지막 상태의 출력을 보여줍니다. 이제 모든 출력을 인쇄하면 상태가 각 배치의 이전 출력임을 알 수 있습니다. 즉, 이전 출력에는 전체 시퀀스에 대한 정보가 포함됩니다.

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)

반복 신경망 (RNN)

출력은 (3, 2, 6) 형태입니다:

  • 3: 배치 수
  • 2: 시간 단계 수
  • 6: 뉴런의 수

순환 신경망의 최적화는 기존 신경망과 동일합니다. 이 순환 신경망 튜토리얼의 다음 부분에서 코드 최적화 방법을 더 자세히 살펴보겠습니다.

RNN의 응용

RNN은 특히 미래 예측과 관련하여 다양한 용도로 사용됩니다. 금융 산업에서 RNN은 주가나 주식 시장 방향의 신호(예: 긍정적 또는 부정적)를 예측하는 데 도움이 될 수 있습니다.

RNN은 차량의 궤적을 예측해 교통사고를 피할 수 있어 자율주행차에 유용하다.

RNN은 텍스트 분석, 이미지 캡션, 감정 분석 및 기계 번역에 널리 사용됩니다. 예를 들어, 영화 리뷰를 사용하여 관객이 영화를 본 후 인지한 감정을 이해할 수 있습니다. 이 작업을 자동화하는 것은 영화 회사가 리뷰를 검토, 레이블 지정, 통합 및 분석할 시간이 충분하지 않은 경우 매우 유용합니다. 기계는 더 높은 수준의 정확도로 작업을 수행할 수 있습니다.

RNN의 한계

이론적으로 RNN은 정보를 여러 번 전달해야 합니다. 그러나 시간 단계가 너무 길면 이 모든 정보를 전파하는 것이 매우 어렵습니다. 네트워크에 심층 계층이 너무 많으면 훈련할 수 없게 됩니다. 이 문제는 다음과 같습니다. 사라지는 그라디언트 문제. 기억하신다면 신경망은 경사하강법 알고리즘을 사용하여 가중치를 업데이트합니다. 네트워크가 하위 계층으로 진행될수록 기울기는 더 작아집니다.

결론적으로, 기울기가 일정하게 유지된다는 것은 개선할 여지가 없다는 것을 의미합니다. 모델은 그래디언트의 변화를 통해 학습합니다. 이 변경 사항은 네트워크의 출력에 영향을 미칩니다. 그러나 그래디언트의 차이가 너무 작은 경우(즉, 가중치가 약간 변경되는 경우) 네트워크는 아무것도 학습할 수 없으므로 결과가 출력됩니다. 따라서 Vanishing Gradient 문제에 직면한 네트워크는 좋은 솔루션으로 수렴될 수 없습니다.

LSTM 개선

RNN이 직면한 사라지는 그래디언트 문제를 극복하기 위해 Hochreiter, Schmidhuber, Bengio의 세 연구원은 Long Short-Term Memory(LSTM)라는 아키텍처로 RNN을 개선했습니다. 간단히 말해, LSMT는 네트워크에 최근의 관련 과거 정보를 제공합니다. 이 기계는 더 나은 아키텍처를 사용하여 정보를 선택하고 이후 시간으로 다시 전달합니다.

LSTM 아키텍처는 TensorFlow, tf.contrib.rnn.LSTMCell에서 사용할 수 있습니다. LSTM은 튜토리얼의 범위를 벗어납니다. 공식을 참조할 수 있습니다. 선적 서류 비치 자세한 내용은

시계열의 RNN

이 TensorFlow RNN 튜토리얼에서는 시계열 데이터와 함께 RNN을 사용합니다. 시계열은 이전 시간에 따라 달라집니다. 즉, 과거 값에는 네트워크가 학습할 수 있는 관련 정보가 포함됩니다. 시계열 예측의 기본 개념은 주가, 기온, GDP 등과 같은 계열의 미래 가치를 추정하는 것입니다.

Keras RNN과 시계열에 대한 데이터 준비는 약간 까다로울 수 있습니다. 우선, 목표는 시리즈의 다음 값을 예측하는 것입니다. 즉, 과거 정보를 사용하여 t + 1에서 값을 추정합니다. 레이블은 입력 시퀀스와 동일하고 한 기간 앞으로 이동합니다. 둘째, 입력 수는 1로 설정됩니다. 즉, 시간당 하나의 관찰입니다. 마지막으로, 시간 단계는 숫자 값의 시퀀스와 같습니다. 예를 들어, 시간 단계를 10으로 설정하면 입력 시퀀스는 XNUMX번 연속으로 반환됩니다.

아래 그래프를 보면 왼쪽에는 시계열 데이터가, 오른쪽에는 가상 입력 시퀀스가 ​​표시되어 있습니다. 2001년 2016월부터 XNUMX년 XNUMX월까지 매일 무작위 값이 포함된 데이터세트를 반환하는 함수를 만듭니다.

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

산출

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

그래프의 오른쪽 부분은 모든 시리즈를 보여줍니다. 2001년부터 시작하여 2019년에 끝납니다. 네트워크에 있는 모든 데이터를 공급하는 것은 의미가 없습니다. 대신 시간 단계와 같은 길이의 데이터 배치를 만들어야 합니다. 이 배치는 X 변수가 됩니다. Y 변수는 X와 동일하지만 한 기간만큼 이동합니다(즉, t+1을 예측하려고 합니다).

두 벡터의 길이는 동일합니다. 위 그래프의 오른쪽 부분에서 확인하실 수 있습니다. 선은 X 입력의 XNUMX개 값을 나타내고 빨간색 점은 레이블 Y의 XNUMX개 값을 나타냅니다. 레이블은 X보다 한 기간 앞서 시작하고 한 기간 후에 끝납니다.

TensorFlow에서 시계열을 예측하기 위해 RNN 구축

이제 이 RNN 교육에서는 위의 계열을 예측하기 위해 첫 번째 RNN을 구축할 차례입니다. 모델에 대해 일부 하이퍼파라미터(모델의 매개변수, 즉 뉴런 수 등)를 지정해야 합니다.

  • 입력 수: 1
  • 시간 단계(시간 시리즈의 창): 10
  • 뉴런 수: 120
  • 출력 수: 1

네트워크는 10일간의 시퀀스를 통해 학습하며 120개의 반복 뉴런을 포함합니다. 하나의 입력, 즉 하루만 모델에 입력합니다. 모델이 개선되었는지 확인하려면 값을 자유롭게 변경해 보세요.

모델을 구성하기 전에 데이터 세트를 기차 세트와 테스트 세트로 분할해야 합니다. 전체 데이터 세트에는 222개의 데이터 포인트가 있습니다. 처음 201개 점을 사용하여 모델을 훈련하고 마지막 21개 점을 사용하여 모델을 테스트합니다.

학습 및 테스트 세트를 정의한 후에는 배치가 포함된 객체를 생성해야 합니다. 이 배치에는 X 값과 Y 값이 있습니다. X 값은 한 기간 지연된다는 점을 기억하세요. 따라서 처음 200개의 관측치를 사용하고 시간 단계는 10과 같습니다. X_batches 객체에는 크기가 20*10인 배치 1개가 포함되어야 합니다. y_batches는 X_batches 개체와 모양이 동일하지만 마침표가 한 개 앞에 있습니다.

단계 1) 기차를 만들고 테스트해보세요.

먼저 시리즈를 다음과 같이 변환합니다. numpy 배열; 그런 다음 아래 TensorFlow RNN 예제에서와 같이 윈도우(즉, 네트워크가 학습하는 횟수), 입력 수, 출력 수, 그리고 학습 세트의 크기를 정의합니다.

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

그런 다음 배열을 두 개의 데이터 세트로 분할하기만 하면 됩니다.

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

단계 2) X_batches 및 y_batches를 반환하는 함수를 만듭니다.

더 쉽게 하기 위해 두 개의 서로 다른 배열(X_batches용 배열과 y_batches용 배열)을 반환하는 함수를 만들 수 있습니다.

배치를 구성하기 위해 RNN TensorFlow 함수를 작성해 보겠습니다.

X 배치는 한 주기만큼 지연된다는 점에 유의하세요(t-1 값을 취함). 함수의 출력은 XNUMX차원이어야 합니다. 첫 번째 차원은 배치 수, 두 번째 차원은 윈도우 크기, 마지막 차원은 입력 수와 같습니다.

까다로운 부분은 데이터 포인트를 올바르게 선택하는 것입니다. X 데이터 포인트의 경우 t = 1에서 t =200까지의 관측치를 선택하고 Y 데이터 포인트의 경우 t = 2에서 201까지의 관측치를 반환합니다. 올바른 데이터 포인트가 있으면 모양을 바꾸는 것이 간단합니다. 시리즈.

배치로 객체를 구성하려면 데이터 세트를 동일한 길이의 배치 20개(즉, 1개)로 분할해야 합니다. 계열이 배치 크기와 유사하도록 reshape 방법을 사용하고 -20을 전달할 수 있습니다. 값 1은 배치당 관측치 수이고 XNUMX은 입력 수입니다.

라벨에 대해서도 동일한 단계를 수행해야 합니다.

데이터를 예측하려는 횟수만큼 이동해야 합니다. 예를 들어, 한 번 앞을 예측하려면 시리즈를 1만큼 이동합니다. 이틀을 예측하려면 데이터를 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

이제 함수가 정의되었으므로 이를 호출하여 아래 RNN 예제와 같이 배치를 생성할 수 있습니다.

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

도형을 인쇄하여 치수가 올바른지 확인할 수 있습니다.

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

하나의 데이터 배치와 20개의 관찰만으로 테스트 세트를 만들어야 합니다.

며칠 후에 예측한다는 것은 두 번째 예측 값이 테스트 데이터 세트의 첫 번째 날(t+1)의 실제 값을 기반으로 한다는 것을 의미합니다. 실제로, 진정한 가치가 알려질 것입니다.

t+2(즉, 1일 전)를 예측하려면 예측 값 t+3을 사용해야 합니다. t+1(2일 전)을 예측하려면 예측 값 t+XNUMX 및 t+XNUMX를 사용해야 합니다. t+n일 앞을 정확하게 예측하는 것은 어렵다는 것이 이해가 됩니다.

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)

좋습니다. 배치 크기가 준비되었으니 RNN 아키텍처를 빌드할 수 있습니다. 기억하세요, 120개의 순환 뉴런이 있습니다.

단계 3) 모델 구축

모델을 생성하려면 다음 세 부분을 정의해야 합니다.

  1. 텐서가 있는 변수
  2. RNN
  3. 손실과 최적화

단계 3.1) 변수

적절한 모양으로 X 및 y 변수를 지정해야 합니다. 이 단계는 간단합니다. 텐서는 X_batches 및 y_batches 객체와 동일한 차원을 갖습니다.

예를 들어, 텐서 X는 자리 표시자입니다(소개에 대한 튜토리얼을 확인하세요). 텐서 플로우 변수 선언에 대해 다시 생각해보면)에는 세 가지 차원이 있습니다.

  • 참고: 배치 크기
  • n_windows: 창의 길이. 즉, 모델이 뒤로 바라보는 시간 수
  • n_input: 입력 개수

결과는 다음과 같습니다.

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

단계 3.2) RNN 만들기

이 RNN TensorFlow 예제의 두 번째 부분에서는 네트워크의 아키텍처를 정의해야 합니다. 이전과 마찬가지로 TensorFlow estimator의 BasicRNNCell 객체와 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)   

다음 부분은 조금 더 까다롭지만 더 빠른 계산이 가능합니다. 실행 출력을 조밀한 레이어로 변환한 다음 입력과 동일한 차원을 갖도록 다시 변환해야 합니다.

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.3) 손실 및 최적화 생성

모델 최적화는 수행 중인 작업에 따라 다릅니다. 이전 튜토리얼에서 현지 시간, 귀하의 목표는 이미지를 분류하는 것이었지만, 이 RNN 튜토리얼에서는 목표가 약간 다릅니다. 클래스와 비교하여 연속 변수에 대한 예측을 수행하라는 요청을 받습니다.

이 차이는 최적화 문제를 변경하므로 중요합니다. 연속형 변수의 최적화 문제는 평균 제곱 오차를 최소화하는 것입니다. TF에서 이러한 측정항목을 구성하려면 다음을 사용할 수 있습니다.

  • tf.reduce_sum(tf.square(출력 – y))

RNN 코드의 나머지 부분은 이전과 동일합니다. 손실을 줄이기 위해 Adam 최적화 프로그램을 사용합니다(예: MSE).

  • tf.train.AdamOptimizer(learning_rate=learning_rate)
  • 최적화기.최소화(손실)

그게 전부입니다. 모든 것을 하나로 묶을 수 있으며 모델을 훈련할 준비가 되었습니다.

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

1500개의 Epoch를 사용하여 모델을 훈련하고 150번의 반복마다 손실을 인쇄합니다. 모델이 훈련되면 테스트 세트에서 모델을 평가하고 아래 순환 신경망 예시와 같이 예측이 포함된 객체를 생성합니다.

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

마지막으로 이 RNN Deep Learning 튜토리얼에서는 예측 값을 사용하여 계열의 실제 값을 그릴 수 있습니다. 모델이 수정되면 예측 값이 실제 값 위에 배치되어야 합니다.

보시다시피, 이 모델은 개선의 여지가 있습니다. 윈도우, 배치 크기, 순환 뉴런 수와 같은 하이퍼파라미터를 변경하는 것은 여러분에게 달려 있습니다.

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()
예측과 실제

예측과 실제

제품 개요

순환 신경망은 시계열 또는 텍스트 분석을 처리하는 강력한 아키텍처입니다. 이전 상태의 출력은 시간 또는 단어 시퀀스에 따라 네트워크의 메모리를 보존하기 위한 피드백입니다.

TensorFlow에서는 다음 코드를 사용하여 시계열에 대한 TensorFlow 순환 신경망을 훈련할 수 있습니다.

모델의 매개변수

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

모델 정의

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

최적화 구성

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