본문 바로가기

머신러닝 & 딥러닝 공부/Tensorflow

[Tensorflow dev 자격증] Recurrent Neural Networks for Time Series

반응형

안녕하세요

27년차 진로탐색꾼 조녁입니다!

 

오늘은 텐서플로우 자격증 과정 네번째 강좌인

'Sequences, Time Series and Prediction 

3주차 강의(Recurrent Neural Networks for Time Series) 및 자료를 공부했습니다.

 

첫번째 영상, Week3- A conversation with Andrew Ng

RNN과 LSTMs 신경망을 시계열 데이터에 접목시켜볼 것이다. 

또한 Lambda layer라는 흥미로운 기능을 배울 것인데, 이것은 데이터를 재전송한다. 

이를 통해 우리는 전처리도 신경망 안으로 끌고 들어올 수 있다.

 

두번째 영상, Conceptual overview

RNN은 recurrent layer를 가지고 있다.  (*recurrent layer란? ) 

그리고 입력값의 형태는 3차원(batch size, time steps, dims)로 이뤄져야 한다. 

그림1. RNN 기본 구조

recurrent layer를 살펴보면, 그림2와 같이 여러개 셀이 있지만 사실상 하나의 셀이며 반복적으로 사용된다. 

그림2. Recurrent layer 구조

 

세번째 영상, Shape of the inputs to the RNN

그림3의 구조가 복잡해보이지만 하나씩 살펴보자.

우선 X는 window_size가 30인 series이다. 즉, 과거 30개의 data로 다음 값을 예측한다. 그렇다보니 X0~X29가 주어진다. 

여기서 batch_size = 4 라서 각 X값들의 크기는 4 이다. 추가로, Mem cell의 unit 갯수가 3이라면 30개의 Y는 4(batch_size) * 3(unit 갯수) 크기만큼의 metrix 형태를 가진다.  일반적인 RNN의 경우 H0 벡터는 Y0와 동일하다.

 

입력 값 X가 time series 라고할때, RNN을 거쳐 Vector가 출력되게 되는 것이다.

이 때, 네가 설정하지 않는다면 자동으로 마지막 벡터만 출력할 것이다. 그러므로 각 셀의 output을 보고 싶다면,

모델을 설정할 때 인자로 return_sequences=True로 설정해줘야 한다.

 

그림3. Recurrent layer 상세 구조

 

네번째 영상, Outputting a sequence

input_shape = [batch size, time steps, dims] -> [None, 1]

즉, 배치 크기 상관없이 가질 수 있고, time steps 가 None이면 모든 길이를 다룰 수있다.

또한 각 레이어에 return_sequences=True 파라미터를 추가하면 아래 그림4와 같이 모든 셀의 값을 출력해준다.

It's fed a batch of sequences and it returns a batch of sequences of the same length.

The dimensionality may not always match. It depends on the number of units in the memory cell.

그림4.모든 값을 출력하는 RNN 코드

아래 신경망은 우리에게 단일 Dense layer를 줄 것이다. 

 

그림5. 1개의 output만 나오는 RNN 코드

 

다섯번째 영상, Lambda layers

Lambda layer는 임의의 기능들 제공한다. 첫줄에 있는 람다 레이어는 dim을 확장해준다. 그래서 input shape에 따로 3번째 값을 지정 안해줘도 된다. 두번째 람다 레이어는 스케일업 해준다. 

 

그림6. Add lambda layers

여섯번째 영상, Adjusting the learning rate dynamically

학습률을 조절해주는 콜백 코드는 이전 주차에서 다뤘던 것과 동일하다.

이번에는 추가로, 후버 손실함수를 사용한다. 후버 손실함수는 이탈점에 대해 덜 민감하다는 장점과, 약간의 노이즈가 있다는 단점이 있지만 한번 써볼만하다. 우선 100에폭으로 학습시켜보자. 

 

그림7. Huber 함수로  100에폭 돌리기

그림7의 코드로 100에폭 돌리고, loss(손실)를 시각화해보면 아래 그림8과 같은 그래프가 나온다. 

여기서 스무스한 부분 중 가장 작은 값은 5*e -5이다. 

그림8. Huber 손실 시각화

 

앞서 발견한 lr(학습률)로 교체해서 다시 아래와 같은 코드를 작성해준다. 에폭은 500에폭으로 늘린다.

결과는 mae = 6.3532376으로 나쁘진 않다.(좋지도 않은듯)

그림9. 학습률 반영한 코드

 

500에폭동안의 손실을 살펴보자. 특별히 첫번쨰 그래프는 살펴보기 용이하진 못하니 범위를 재설정해서 두번째 그래프를 보자.

두번쨰 그래프는 200~500 에폭동안의 손실을 볼 수 있다. 450 에폭이후 손실이 느는 것을 볼 수있다.

그러니 에폭을 400으로 줄여서 다시 돌려보자.

 

400에폭으로 돌려보니 mae = 6.4141674로 약간 상승했다. 하지만 100에폭의 시간을 줄였으니 뭐 할만 했다.

 

그림10. 500에폭 동안의 손실 시각화

 

일곱번째 읽기자료, More info on Huber loss

 

en.wikipedia.org/wiki/Huber_loss

 

Huber loss - Wikipedia

In statistics, the Huber loss is a loss function used in robust regression, that is less sensitive to outliers in data than the squared error loss. A variant for classification is also sometimes used. Definition[edit] The Huber loss function describes the

en.wikipedia.org

 

여덟번째 영상, RNN

코드 리뷰함, 아직 mae가 꽤나 높아 부족해 보인다.

 

아홉번째 읽기자료, RNN notebook

gist.github.com/jonhyuk0922/5968637ef5eccfc2a1784e94cb1dee3d#file-s-p-week-3-lesson-2-rnn-ipynb-ipynb

 

S+P Week 3 Lesson 2 - RNN.ipynb의 사본

S+P Week 3 Lesson 2 - RNN.ipynb의 사본. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

열번째 영상, LSTM

RNN에서는 한계가 보였다.

몇가지 하이퍼파라미터를 조정해봤지만 그 마저도 제한적인 효과만 있었다.

RNN에서는 초기 X0 에서 생성된 H0가 시간이 지날수록 점점 왜곡됐다. 

그에 반해, LSTMs는 state를 통해 초기 x부터 출력 직전 x까지 비교적 잘 연결되어 있기 떄문에 더 효과적이다. 양방향 또한 가능하다.

LSTMs 가 텍스트를 대상으로 아주 잘 작동했으므로 한번 실험해볼 가치가 있다.

그림11. LSTMs Cell State

 

 

열한번째 읽기자료, Link to the LSTM lesson * 결제해야 되니까 나중에 몰아서 보자

www.coursera.org/lecture/nlp-sequence-models/long-short-term-memory-lstm-KXoay

 

Long Short Term Memory (LSTM) - Recurrent Neural Networks | Coursera

Video created by deeplearning.ai for the course "Sequence Models". Learn about recurrent neural networks. This type of model has been proven to perform extremely well on temporal data. It has several variants including LSTMs, GRUs and ...

www.coursera.org

 

열두번째 영상, Coding LSTMs

코드를 하나씩 살펴보자. 첫줄의 tf.keras.backend.clear_session() 은 모든 내부 변수를 지워준다. 이후 버전을 고려하지 않고 편하게 실험할 수 있다. 

람다 레이어 후에 따라오는 양방향 LSTM 레이어를 추가해줬다. 뉴런은 32개로 주어졌다. 

 

이번에도 마찬가지로 학습률을 1e-6으로 놓고 100 에폭을 돌려본다. mae = 6.131234로 약간 줄었다. 

 

그림12. 1층 LSTM 신경망

 

다음으로 LSTM을 한 층 더 쌓았다. 첫번째 쌓았던 층에는 return_sequences=True 를 추가해준다.

효과는 뛰어났다. mae = 5.2872233 으로 줄었다.

이후 3층도 쌓아봤는데 효과는 감소했다. 다음 주 강의에는 CNN을 살펴볼 것이다.

 

그림13. 2층 LSTM 신경망

 

열세번째 영상, More on LSTM

코드 리뷰, 100에폭 돌려서 알맞은 학습률을 찾은 후, 반영하여 500에폭을 돌렸다. 

 

열네번째 읽기자료, LSTM notebook

gist.github.com/jonhyuk0922/98580787457dbcd6ef8dc581f1b10e94#file-s-p-week-3-lesson-4-lstm-ipynb-ipynb

 

S+P Week 3 Lesson 4 - LSTM.ipynb의 사본

S+P Week 3 Lesson 4 - LSTM.ipynb의 사본. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

퀴즈에서 배운점

: tf.keras.layers.Lambda(lambda x: tf.expand_dims(x, axis=-1), input_shape=[None]) 는 tensor's shape을 확장할 차원 인덱스를 정해준다. 즉, 아래와 같이 주어진 텐서에 위치를 정해서 차원을 1개 높여준다. 

그림14. tf.expand_dims 사용법

www.tensorflow.org/api_docs/python/tf/expand_dims

 

tf.expand_dims  |  TensorFlow Core v2.4.1

Returns a tensor with a length 1 axis inserted at index axis.

www.tensorflow.org

 

 

: LSTM layer를 사용할 떄, 마지막에 쌓은 층을 제외한 모든 층의 코드는 아래와 같이 리턴 시퀀스 파라미터가 들어가야한다.

그래야지만 모든 셀의 아웃풋이 출력되며, 다음 레이어로 전달될 수 있다.

tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32, return_sequences=True)),

 

3주차 마무리

 

Now that you've built on your DNNs with RNNs and LSTMs, it's time to put it all together using CNNs and some real world data.

Next week you'll do that, exploring prediction of sunspot data from a couple of hundred years worth of measurements!

 

과제 :  lr pick 해서 MAE < 3 만들기

 

반응형