4-1. Vanilla RNN 모델 만들기

이번 실습에서는 RNN 모델의 가장 간단한 형태인 Vanilla RNN 모델을 직접 만들어보도록 하겠습니다.

img

Tensorflow에서는 이러한 Vanilla RNN이 SimpleRNN 이라는 이름으로 구현되어 있습니다. 따라서 앞선 CNN 모델에서 사용했던 Conv2D Layer 처럼 사용할 수 있습니다.

이번 실습은 이 SimpleRNN Layer를 활용하여 자연어 데이터를 임베딩 하는 상황을 가정하여 모델을 구성하도록 할 것입니다. 따라서 실제로 데이터를 준비하여 모델에 적용하는 것은 아닙니다.

실습을 통해 SimpleRNN Layer를 어떻게 활용하면 되는지 알아보세요.

지시사항

자연어 데이터를 딥러닝 모델에 적용할 수 있는 형태로 바꾸기 위해서는 임베딩을 활용하여 벡터로 바꾸어야 했습니다.

Tensorflow에서는 이 임베딩을 해주는 Layer로 Embedding이라 불리는 것이 있습니다. 해당 Layer는 데이터셋 내의 전체 단어 개수와 각 단어를 몇개의 원소를 가지는 벡터로 만들지를 설정해주면 알아서 각 단어별로 적절한 벡터를 만들어주게 됩니다.

지시사항을 통해 두 개의 SimpleRNN 기반 모델을 만들어보세요.

  1. 첫번째 모델을 만드는 함수

    build_model1
    

    을 완성하세요. 모델 구성은 다음과 같습니다.

    • layers.Embedding
      
      • 전체 단어 개수: 10개
      • 벡터 길이: 5
    • layers.SimpleRNN
      
      • hidden state의 크기: 3
  2. 두번째 모델을 만드는 함수

    build_model2
    

    를 완성하세요. 모델 구성은 다음과 같습니다.

    • layers.Embedding
      
      • 전체 단어 개수: 256개
      • 벡터 길이: 100
    • layers.SimpleRNN
      
      • hidden state의 크기: 20
    • layers.Dense
      
      • 노드 개수: 10
      • 활성화 함수: softmax

4-2. Vanilla RNN으로 IMDb 데이터 학습하기

IMDb(Interet Movie Database)는 영화 정보를 데이터베이스화 해서 제공하는 인터넷 사이트입니다.

img

이 사이트에는 각 영화의 기본적인 정보 뿐 아니라 사용자들의 리뷰도 포함되어 있습니다. 사용자 리뷰는 별점 기반으로 10개 만점인데, 스탠포드 대학에서 이 리뷰들이 긍정적인지 부정적인지를 분석하여 클래스가 두개인 데이터셋으로 구성하였습니다.

따라서 많은 자연어 처리 예제에서 감성 분석(Sentimental Analysis) 을 위한 데이터셋으로 많이 활용하고 있습니다. 이번 실습에서도 이 데이터셋을 활용하여 SimpleRNN 모델을 직접 만들어 학습하는 과정을 알아보도록 하겠습니다.

지시사항

Tensorflow는 유명한 데이터셋의 일부를 라이브러리에서 바로 활용할 수 있는 API를 제공하고 있습니다. 이 데이터셋들은tensorflow.keras.datasets이라는 모듈에서 찾아볼 수 있습니다. IMDb 데이터셋 또한 이 모듈에서 제공하고 있기 때문에 여기서는 이를 활용하여 데이터셋을 불러오도록 하겠습니다.

앞서 언급했듯 이 데이터셋은 긍정과 부정 두가지의 클래스를 가지고 있으니 이진 분류(Binary Classification)을 할 수 있는 모델을 구성하도록 하겠습니다.

지시사항에 따라 코드를 완성하세요.

  1. SimpleRNN 기반 모델을 완성하는 함수

    build_rnn_model
    

    을 완성하세요. 모델의 Layer 구성은 다음과 같습니다.

    • layers.Embedding
      
      • 전체 단어 개수: num_words
      • 벡터 길이: embedding_len
    • layers.SimpleRNN
      
      • hidden state 크기: 16
    • layers.Dense
      
      • 노드 개수: 1개
      • 활성화 함수: Sigmoid
  2. main
    

    함수에서 모델 학습을 위한 Optimizer, 손실 함수, 평가 지표(Metrics)을 설정하세요.

    • Optimizer:

      Adam
      
      • Learning rate: 0.001
    • 손실 함수: binary_crossentropy

    • 평가 지표: accuracy

  3. 모델 학습을 위한 hyperparameter를 설정하세요.
    • epochs=epochs
    • batch_size=100
    • validation_split=0.2
    • shuffle=True
    • verbose=2

4-3. Vanilla RNN을 통한 항공 승객 수 분석

이번 실습에서는 항공 승객 수 데이터셋을 통해 월별로 항공기를 이용하는 승객 수가 어떻게 변화하는지 확인하고 예측하는 모델을 만들어보도록 하겠습니다.

사용할 데이터셋은 시계열 데이터 분석을 위한 예제 데이터로, 1949년 1월부터 1960년 12월까지 항공기 이용 승객 수를 월별로 기록한 데이터셋입니다.

img

이 데이터에서 앞쪽 데이터의 80%를 모델 학습을 위한 데이터로 사용하고, 나머지 20%를 모델이 예측하도록 하겠습니다.

지시사항

데이터셋을 불러와 학습 데이터와 테스트 데이터로 나누는 부분은 load_data 함수에 구현되어 있습니다.

시계열 데이터를 사용하여 RNN 기반 모델을 학습할 때는 window size라는 개념을 사용합니다.

이는 모델을 한번 학습할 때 사용할 데이터의 개수를 의미하는 것으로, 아래 그림처럼 총 10개의 데이터에서 4개의 데이터를 한번 학습에 사용한다면 window size는 4가 됩니다.

img

이 실습에서는 데이터셋을 구성할 때 각 입력 데이터의 window size가 4가 되도록 설정하였습니다.

지시사항에 따라 코드를 완성하세요.

  1. SimpleRNN 기반 모델을 만드는 함수

    build_rnn_model
    

    을 완성하세요. Layer 구성은 아래와 같습니다.

    • layers.SimpleRNN
      
      • hidden state의 크기: 4
      • input_shape=(window_size, 1)
    • layers.Dense
      
      • 노드 개수: 1개
  2. main
    

    함수 내에서 모델 학습을 위한 optimizer, loss 함수, 평가 지표(metrics)를 설정하세요.

    • Optimizer: Adam
    • Learning Rate: 0.001
    • Loss 함수: Mean Squared Error(MSE)
  3. 모델 학습을 위한 hyperparameter를 설정하세요.
    • batch_size=8
    • epochs=epochs
    • shuffle=True
    • verbose=2

이번 실습에서는 예측한 값이 실제 값이 어떻게 나타나는지 마지막에 그래프로 그립니다. 그래프를 보고 값이 잘 예측되고 있는지 확인해보세요.

4-4. 심층 Vanilla RNN 모델

이전 실습까지 만든 Vanilla RNN 모델은 모두 SimpleRNN Layer가 하나로만 이루어진 모델이었습니다. 하지만 이 SimpleRNN 또한 Convolutional Layer 처럼 하나의 Layer 라고 볼 수 있기 때문에 여러 층으로 쌓는 것이 가능합니다.

이렇게 여러 SimpleRNN 층으로 이루어진 모델을 심층 RNN(Deep RNN) 모델이라고 부릅니다. 이번 실습에서는 SimpleRNN이 하나로 이루어진 모델과 두개로 이루어진 모델을 각각 만들어보고 성능을 비교해보도록 하겠습니다.

사용할 데이터는 아래 그림처럼 numpy를 이용하여 2개의 sin 함수를 조합한 간단한 시계열 데이터입니다. 앞서 설명한 Window Size는 50으로 두었습니다.

생성한 데이터에서 일부를 테스트로 두어 모델이 얼마나 잘 예측하는지 정도를 Mean Squared Error(MSE) 점수를 통해 확인해보세요.

img

지시사항

  1. 하나의

    SimpleRNN
    

    Layer로 이루어진 모델을 만드는 함수

    build_rnn_model을
    

    완성하세요. Layer 구성은 다음과 같습니다.

    • layers.SimpleRNN
      
      • hidden state 크기: 20
      • input_shape=(window_size, 1)
    • layers.Dense
      
      • 노드 개수: 1개
  2. 두개의

    SimpleRNN
    

    Layer로 이루어진 모델을 만드는 함수

    build_deep_rnn_model을
    

    완성하세요. Layer 구성은 다음과 같습니다.

    • layers.SimpleRNN
      
      • hidden state 크기: 20
      • return_sequences=True
      • input_shape=(window_size, 1)
    • layers.SimpleRNN
      
      • hidden state 크기: 20
    • layers.Dense
      
      • 노드 개수: 1개
  3. run_model
    

    함수 내에서 모델 학습을 위한 optimizer와 loss 함수를 설정하세요.

    • Optimizer: Adam
    • Learning Rate: 0.001
    • Loss 함수: Mean Squared Error(MSE)
  4. run_model
    

    함수 내에서 모델 학습을 위한 hyperparameter를 설정하세요.

    • epochs=epochs
    • batch_size=256
    • shuffle=True
    • verbose=2

참고

4-5. Encoder-Decoder 구조

이번 실습에서는 SimpleRNN을 사용하여 Encoder-Decoder 구조를 가지는 모델을 구현해보도록 하겠습니다.

img

Encoder-Decoder 구조의 가장 큰 특징이라면 Encoder에서 나오는 출력값은 사용하지 않고, Encoder의 hidden state만 가져와서 이를 Decoder의 초기 hidden state로 활용한다는 점입니다.

이를 Tensorflow를 통해 구현하는 방법을 알아보도록 하겠습니다.

지시사항

이번 실습에서는 Encoder-Decoder 구조의 모델을 EncoderDecoder라는 이름의 클래스로 구현할 것입니다.

해당 클래스에 추가해야 할 Layer에 더해 이번에는 실제 입력값이 주어졌을 때 모델의 연산을 수행하는 메소드인 call 메소드도 완성할 것입니다.

지시사항에 따라 모델을 완성하세요.

  1. SimpleRNN
    

    하나로 구성된 Encoder를 만드세요.

    SimpleRNN
    

    사용해야 하는 파라미터는 아래와 같습니다.

    • hidden state의 크기: hidden_dim
    • return_state=True
    • input_shape=encoder_input_shape
  2. SimpleRNN
    

    하나로 구성된 Decoder를 만드세요.

    SimpleRNN
    

    사용해야 하는 파라미터는 아래와 같습니다.

    • hidden state의 크기: hidden_dim
    • return_sequences=True
    • input_shape=decoder_input_shape
  3. call
    

    메소드에서 Encoder에 입력값을 넣었을 때 나오는 hidden state를 구하도록 하세요.

    • Encoder를 return_state=True를 통해 만들었기 때문에 입력값이 encoder를 통과하면 출력값과 최종 hidden state가 나오게 됩니다.
    • 둘 중 우리에게 필요한 것은 최종 hidden state 뿐입니다.
  4. call
    

    메소드에서 Decoder에 입력값을 넣고, 초기 hidden state는 encoder의 최종 hidden state로 설정하세요.

    • initial_state라는 파라미터에 앞서 구한 encoder의 hidden state를 리스트로 감싸서 전달해야 합니다.