-
시계열 데이터 예측 모델 비교, MLP-RNN-LSTM카테고리 없음 2020. 4. 1. 21:56
저번 시간에 생성하였던 ARMA 시계열 데이터를 가지고 다음 날의 값을 예측해볼 것이다.
앞서 create_dataset 함수를 이용하여, X와 Y 데이터를 구분해준다. 이때 몇개의 시차, X값 들을 가지고 다음 값을 예측할 지, Window size로 지정해주면된다. 여기서는 5개의 X으로 다음 값을 예측해볼 것이다. 따라서, 초반에 5개는 이전의 값들이 없기 때문에, 예측을 할 수 없고 오로지 X값으로만 사용된다.
또한, 데이들은 총 3000개에서 10%는 모델을 학습시키기위해 사용되며, 나머지 10% 만들어진 몯르을 가지고 결과와 테스트 값을 비교해볼 것이다.
시퀀셜 모델 객체를 생성한뒤, 여러개의 층과 활성화함수를 설정할 수 있다. 이때, 주의할 점은 층에서는 매개변수의 제한이 없지만, input의 차원에는 x값을 개수가 들어가야하며, output은 원하는 값의 개수를 지정해야한다. 우리는 다음날의 값인 y값 하나를 원하기 때문에, output은 1개이다.
반복수 epochs 결정하며, 반복 수가 작다면 understaffing 제대로 학습 안될 가능성이 있고 크다면, overfitting 해당 데이터만 적합하게된 가능성이 있다. 따라서,적합한 모델을 구성하기 위해서는 다양하고 많은 데이터가 필요
batch_size는 모델을 몇번마다 평가할지 결정를 결정한다. 만약에 데이터 100개에 배치가 10이면 1번 반복마다 10개의 데이터 학습이 진행된다. 즉, '배치n'에 따라 평가를 진행한다.
배치 사이즈와 층의 매개변수가 모델의 정확도를 결정하는데 큰 영향을 주기 때문에, 여러번 시행착오를 통해 최적화된 값을 찾는 것이 중요하다.
RNN은 하나의 network를 계속 복사해서 순서대로 정보를 전달하는 network라 할 수 있다.
하지만, 데이터가 길어질 수록 정보를 얻기 위한 시각 격차t가 길어지는 문제가 발생한다.
LSTM은 RNN의 특별한 한 종류로, 긴 의존 기간을 필요로 하는 학습을 수행할 능력을 갖고 있다. LSTM의 핵심은 Cell state이다. 컨베이어 벨트와 같은 Cell state는 작은 linear interaction만을 적용시키면서 전체 체인을 계속 구동시킨다. 정보가 전혀 바뀌지 않고 그대로 흐르게만 하는 것은 매우 쉽게 할 수 있다.
LSTM은 Cell state에 뭔가를 더하거나 없앨 수 있는 능력이 있는데, 이 능력은 gate라고 불리는 구조에 의해서 조심스럽게 제어된다. 즉, Cell state로 부터 어떤 정보를 버릴지를 결정할 수 있다.예를 들어, 단어를 예측하는 언어 모델 문제가 있을때, Cell state는 현재 주어 정보 혹은 타 품사가 사용되도록 준비하고 있을 수도 있다. 그런데 만약 새로운 주어가 왔을 때, 우리는 기존 주어 정보를 생각하고 싶지 않을 것이다.
이때, LSTM은 Cell state에서 기존의 주어 정보를 버리고 새로운 주어 정보를 Cell state에 더할 것이다.
[LSTM 상태유지 스택 쌓기]
LSTM(output_dim, input_shape = (timestep, feature), stateful=True)
여기서 timestep = windowsize, feature은 앞서 reshape로 구성해준 input의 shape이다.
기본적인 학습상태는 텐서보드와 히스토리 콜백함수로 모니터링이 되지만, 순환(Recurrent) 신경망 RNN의 경우,
fit함수가 여러번 호출되고 에포크마다 히스토리 생성되어 초기화되기 때문에, 에포크 별 추이를 살펴볼 수 없다.따라서, 새롭게 콜백함수를 만들어 학습상태를 모니터링 할 수 있다.
[순환 신경망 모델 코드]
위에서 modile.fit은 다음과 같은 구조로 순환되며 이루어 진다. 다음과정에서 model의 상태를 유지하기위해, fit함수가 여러번 호출되고 에포크마다 히스토리 생성되어 초기화(reset)된다.
for i in range(nb_epoch):
temp_time = time.time()
model.fit(x_train, y_train, epochs=1, batch_size=batch_size, verbose=0, shuffle=False, callbacks=[history])
model.reset_states()
print(str(i + 1) + ' epoch \n걸린 시간(second) : ', time.time() - temp_time)