RNN(반복 신경망) 튜토리얼: TensorFlow 예제
⚡ 스마트 요약
순환 신경망(RNN)은 일반 뉴런에 메모리 상태를 추가하여 각 출력을 다음 입력으로 되먹임함으로써 모델이 순서를 학습할 수 있도록 합니다. 이 튜토리얼에서는 TensorFlow를 사용하여 순환 신경망을 구축하고 시계열을 예측합니다.
순환 신경망(RNN)이 필요한 이유는 무엇입니까?
RNN(Recurrent Neural Network)을 사용하면 메모리 단위를 모델링하여 데이터를 유지하고 단기 종속성을 모델링할 수 있습니다. 또한 데이터 상관관계 및 패턴을 식별하기 위해 시계열 예측에도 사용됩니다. 또한 인간의 뇌와 유사한 행동을 전달하여 순차적 데이터에 대한 예측 결과를 생성하는 데 도움이 됩니다.
의 구조 인공 신경망 이 과정은 비교적 간단하며 주로 행렬 곱셈으로 이루어집니다. 첫 번째 단계에서는 입력값에 초기에는 무작위로 설정된 가중치와 편향을 곱하고, 활성화 함수를 통해 변환한 후, 출력값을 사용하여 예측을 수행합니다. 이 단계를 통해 신경망이 실제 결과와 얼마나 차이가 나는지 파악할 수 있습니다.
적용된 메트릭은 손실입니다. 손실 함수가 높을수록 모델은 더 멍청해집니다. 네트워크의 지식을 개선하려면 네트워크의 가중치를 조정하여 일부 최적화가 필요합니다. 확률적 경사 하강법은 가중치 값을 올바른 방향으로 변경하는 데 사용되는 방법입니다. 조정이 완료되면 네트워크는 다른 데이터 배치를 사용하여 새로운 지식을 테스트할 수 있습니다.
다행히 오차는 이전보다 줄었지만, 여전히 충분히 작지는 않습니다. 최적화 단계는 오차가 최소화될 때까지, 즉 더 이상 정보가 손실되지 않을 때까지 반복적으로 수행됩니다.trac테드.
이러한 유형의 모델의 문제점은 메모리가 없다는 것입니다. 이는 입력과 출력이 독립적이라는 것을 의미합니다. 즉, 모델은 이전에 나온 내용에 신경 쓰지 않습니다. 네트워크에는 과거 데이터나 과거 단어에 대한 정보가 필요하기 때문에 시계열이나 문장을 예측해야 할 때 몇 가지 의문이 제기됩니다.
이 문제를 극복하기 위해 새로운 유형의 아키텍처가 개발되었습니다. 즉, 순환 신경망(RNN)입니다.
순환 신경망(RNN)이란 무엇입니까?
순환 신경망(RNN)은 인공 신경망의 한 종류로, 서로 다른 노드 간의 연결이 방향 그래프를 형성하여 시간적 동적 동작을 나타냅니다. 이는 피드포워드 네트워크에서 파생된 순차적 데이터를 모델링하는 데 유용하며, 인간의 두뇌와 유사하게 작동하여 예측 결과를 제공합니다.
순환 신경망은 뉴런에 메모리 상태가 추가된다는 점을 제외하면 기존 신경망과 매우 유사해 보입니다. 메모리를 포함하는 계산은 간단합니다.
하나의 뉴런에 데이터 배치가 입력되는 간단한 모델을 상상해 보세요. 전통적인 신경망에서는 입력에 가중치와 활성화 함수를 곱하여 출력을 생성합니다. RNN에서는 이 출력이 여러 번 자기 자신에게 되돌아갑니다. 이를 순환 신경망(RNN)이라고 합니다. 타임 스텝 출력값이 다음 행렬 곱셈의 입력값이 되는 시간.
예를 들어, 아래 그림에서는 네트워크가 하나의 뉴런으로 구성되어 있음을 볼 수 있습니다. 네트워크는 입력과 가중치 사이의 행렬 곱셈을 계산하고 활성화 함수를 사용하여 비선형성을 추가합니다. t-1의 출력이 됩니다. 이 출력은 두 번째 행렬 곱셈의 입력입니다.
반복 신경망 (RNN)
아래에서는 TensorFlow에서 간단한 RNN을 코딩하여 출력의 단계와 모양을 이해합니다.
네트워크는 다음으로 구성됩니다:
- XNUMX개의 입력
- XNUMX개의 뉴런
- 2단계
아래 그림과 같이 네트워크가 진행됩니다.
이 네트워크는 각 활성화 사각형에서 동일한 작업을 수행하기 때문에 '순환'이라고 불립니다. 이 네트워크는 활성화 함수를 사용하기 전에 입력과 이전 출력의 가중치를 계산했습니다.
버전 참고: 이 튜토리얼의 코드는 TensorFlow 1.x 그래프 API를 대상으로 합니다. TensorFlow 2.x에서도 동일한 스크립트가 실행됩니다. import tensorflow.compat.v1 as tf ...을 더한 tf.disable_v2_behavior()플레이스홀더, 세션 및 rnn_cell 모듈이 이제 아래에 있기 때문입니다. tf.compat.v1. 2.x 버전에서 관용적으로 사용되는 표현은 다음과 같습니다. tf.keras.layers.SimpleRNN.
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 ])
데이터, 반복 단계 및 출력에 대한 자리 표시자를 사용하여 네트워크를 구축할 수 있습니다.
데이터의 자리 표시자 정의
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])
이리:
- 없음: 알 수 없으며 배치 크기를 사용합니다.
- n_timesteps: 네트워크가 출력을 뉴런으로 다시 보내는 횟수
- n_inputs: 배치당 입력 수
순환 네트워크 정의
위 그림에서 언급한 것처럼 네트워크는 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)
아래의 주석이 달린 보기에서는 출력된 텐서를 배치별로 분해하여 보여줍니다.
출력은 (3, 2, 6) 형태입니다:
- 3: 배치 수
- 2: 시간 단계 수
- 6: 뉴런의 수
순환 신경망의 최적화는 기존 신경망과 동일합니다. 이 순환 신경망 튜토리얼의 다음 부분에서 코드 최적화 방법을 더 자세히 살펴보겠습니다.
RNN의 응용
RNN은 특히 미래 예측과 관련하여 다양한 용도로 사용됩니다. 금융 산업에서 RNN은 주가나 주식 시장 방향의 신호(예: 긍정적 또는 부정적)를 예측하는 데 도움이 될 수 있습니다.
RNN은 차량의 궤적을 예측해 교통사고를 피할 수 있어 자율주행차에 유용하다.
RNN은 텍스트 분석, 이미지 캡션, 감정 분석 및 기계 번역에 널리 사용됩니다. 예를 들어, 영화 리뷰를 사용하여 관객이 영화를 본 후 인지한 감정을 이해할 수 있습니다. 이 작업을 자동화하는 것은 영화 회사가 리뷰를 검토, 레이블 지정, 통합 및 분석할 시간이 충분하지 않은 경우 매우 유용합니다. 기계는 더 높은 수준의 정확도로 작업을 수행할 수 있습니다.
RNN의 한계
이론적으로 RNN은 정보를 여러 번 전달해야 합니다. 그러나 시간 단계가 너무 길면 이 모든 정보를 전파하는 것이 매우 어렵습니다. 네트워크에 심층 계층이 너무 많으면 훈련할 수 없게 됩니다. 이 문제는 다음과 같습니다. 사라지는 그라디언트 문제. 기억하신다면 신경망은 경사하강법 알고리즘을 사용하여 가중치를 업데이트합니다. 네트워크가 하위 계층으로 진행될수록 기울기는 더 작아집니다.
결론적으로, 기울기가 일정하게 유지된다는 것은 개선의 여지가 없다는 것을 의미합니다. 모델은 기울기의 변화를 통해 학습하며, 이 변화는 네트워크의 출력에 영향을 미칩니다. 그러나 기울기의 차이가 너무 작으면(즉, 가중치가 약간만 변하면) 네트워크는 아무것도 학습할 수 없으므로 출력도 마찬가지입니다. 따라서 기울기 소실 문제를 겪는 네트워크는 좋은 해로 수렴할 수 없습니다.
LSTM 개선
RNN이 직면할 수 있는 기울기 소실 문제를 극복하기 위해 Hochreiter, Schmidhuber, Bengio 세 연구자는 LSTM(Long Short-Term Memory)이라는 아키텍처를 사용하여 RNN을 개선했습니다. 간단히 말해, LSTM은 네트워크에 관련 있는 과거 정보를 최근 시점으로 가져옵니다. 이를 통해 기계 학습 시스템은 더 나은 아키텍처를 사용하여 정보를 선택하고 나중 시점으로 전달합니다.
LSTM 아키텍처는 TensorFlow의 `tf.contrib.rnn.LSTMCell`에서 사용할 수 있습니다. 하지만 LSTM은 이 튜토리얼의 범위를 벗어나므로, 자세한 내용은 공식 문서를 참조하십시오. 선적 서류 비치 자세한 내용은
TensorFlow 2.x에서는 해당 셀에 다음과 같이 도달합니다. tf.compat.v1.nn.rnn_cell.LSTMCell반면 새 코드는 일반적으로 다음과 같은 방식을 사용합니다. tf.keras.layers.LSTM 또는 라이터 게이트 tf.keras.layers.GRU이는 더 적은 매개변수로 비슷한 정확도를 달성합니다.
시계열의 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()
그래프의 오른쪽 부분은 모든 시계열을 보여줍니다. 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 객체는 크기가 10*1인 배치 20개를 포함해야 합니다. y_batches 객체는 X_batches 객체와 동일한 형태를 가지지만 한 기간만큼 앞서 있습니다.
단계 1) 기차를 만들고 테스트해보세요.
먼저 시리즈를 다음과 같이 변환합니다. 눔 파이 배열; 그런 다음 아래 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) 모델 구축
모델을 생성하려면 다음 세 부분을 정의해야 합니다.
- 텐서가 있는 변수
- RNN
- 손실과 최적화
단계 3.1) 변수
적절한 모양으로 X 및 y 변수를 지정해야 합니다. 이 단계는 간단합니다. 텐서는 X_batches 및 y_batches 객체와 동일한 차원을 갖습니다.
예를 들어, 텐서 X는 자리 표시자입니다. (튜토리얼을 참조하세요) TensorFlow 소개 변수 선언에 대해 다시 생각해보면)에는 세 가지 차원이 있습니다.
- 참고: 배치 크기
- 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()
예측과 실제





