글 작성자: 만렙개발자

RNN

  RNN은 현재의 입력 뿐만 아니라, 이전에 인식했던 내용을 함께 수용합니다. 즉, 이전의 값을 다시 입력으로 받는 Reccurent Connection이 존재합니다. 이런 재귀성 때문에 RNN이라고 부릅니다. 이런 구조는 연속적인 정보에 효과적입니다. 예를들어, 문자의 경우 '소녀시대'라는 단어가 있을 때, ['소', '녀', '시', '대']를 각각 독립적으로 보기보다는, '녀'가 '소' 뒤에 왔을 때, '소녀'에서의 '녀'를 볼 수 있도록 하는 것이 좋습니다. ['대', '소', '시', '녀']와 같이 된다면 의미가 달라지는 것 처럼, 문장 혹은 문서에서의 이러한 연속성은 매우 중요합니다. 간단한 예로 음절 단위의 분할을 하였지만, 다른 경우도 마찬가지입니다. 또한 직전 하나의 출력만 보는 것이 아니라, 여러 출력을 본다면 어느정도 상태가 유지되고 저장되는 느낌을 만들 수도 있습니다. 그래서 메모리를 갖고 있다고도 하고, 이러한 특성을 발전시켜 메모리 네트워크라는 것도 설계됩니다.

 

  RNN은 'statefulness'라는 특징을 갖고 있습니다. RNN layer를 'stateful'하게 설정할 수 있습니다. 'stateful'하다는 것은 한 batch의 samples를 계산한 states가 다음 batch의 samples을 위한 초기 상태(initial states)로 재사용된다는 것입니다. 이러한 'statefulness'를 활성화하려면stateful=True로 설정하면 됩니다. 그리고batch_input_shape = n혹은batch_shape = n으로 고정된 batch size를 명시해줍니다. 마지막으로 fit() 함수를 호출 할 때shuffle=False로 설정합니다. 모델의 states를 재설정하려면 특정 레이어 혹은 전체 모델에서.reset_states()함수를 호출하면 됩니다.

 

  RNN이 적용되는 대표적인 분야는 자연어처리(NLP; Natural Language Processing)이고, 대표적인 예로는 기계 번역(Machine Translation), 이미지 캡션 생성, 주가 예측 등이 있습니다.

 

  RNN도 vanashing gradient 문제를 갖고 있엇습니다. 신경망을 통해 흐르는 정보가 여러 단계의 곱셈을 통과하기 때문에 발생하는 문제입니다. '복리'적 문제라고 볼 수 있는데요, 예를들어 10개의 timestpes를 가진 RNN을 생각해봅시다. (즉, 이전 결과를 10개까지 참조하는 형태입니다.) 그 RNN의 순환구조에서 사용되는 값은 10개의 tiemsteps에서 공유합니다.(vanishing gradient 문제를 설명하기 위한 가장 전통적인 방법의 경우입니다.) weight가 0.97 이라고 한다면, 10번의 곱을 통해 최종적으로는 0.74정도의 값으로 줄어든 영향력을 나타내게 됩니다. 이정도로는 vanishing할 정도라기에는 아직 크지만 더 작은 weight값, 더 큰 timestep이라고 한다면 지수적으로 vanishing할 것입니다. 이러할 경우, 여러번의 timestep을 거친 입력값은 얼만큼 반영해야하는지에 대해 모호해지기 시작합니다. 특히, sigmoid 함수를 생각해보았을 때, 여러번의 sigmoid를 계산하면 기울기가 점점 줄어들어 아래의 그래프와 같이 평평해 집니다. 즉, 입력값에 따라 구분하는 '활성화(activation)'를 제대로 못하게 되는 것이죠. 이러한 문제를 해결하기 위해 제안된 것이 바로 LSTM입니다.

ref: skymind (https://skymind.ai/wiki/lstm)

케라스에 구현된 RNN

  • 기본 구성요소
    • call(input_at_t, states_at_t) 함수
    • state_size
      • recurrent state (= cell의 output 크기)
    • output_size
  • 입력과 출력
    • Input shape
      • 3D tensor with shape (batch_size, timesteps, input_dim)
    • Output shape
      • return_state
        • tensor의 리스트가 return
          • 첫번째 tensor가 output
          • 나머지 tensor들은 (batch_size, units) shape의 마지막 states
            • 예) RNN과 GROU의 state tensor의 수는 1, LSTM은 2
      • return_sequences
        • 3D tensor (batch_size, timesteps, units)
        • 2D tensor (batch_size, units)

Simple RNN Layer

keras.layers.SimpleRNN(units)

  • Fully-connected RNN
  • cell
    keras.layers.SimpleRNNCell(units)

GRU (Gated Recurrent Unit)

keras.layers.GRU(units)

  • 두개의 타입
    • 1406.1078v3: 행렬곱을 하기전에 hidden state에 적용된 gate를 reset (default)
    • CuDNNGRU: 분리된 biases가 존재. 학습은 GPU에서만 가능, 추론은 CPU에서도 가능
      • reset_after=True로, recurrent_activation='sigmoid'로 설정해주어야 한다.
  • ref: Kyunghyun Cho et al., Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation, EMNLP, 2014.
  • cell
    keras.layers.GRUCell(units)
  • CuDNNGRU
    keras.layers.CuDNNGRU(units)
    • CuDNN 벡엔드로 빠른 GRU
    • TensorFlow 벡엔드로, GPU에서만 동작 가능

LSTM (Long Short-Term Memory)

keras.layers.LSTM(units)

  • ref: Sepp Hochreiter et al., LONG SHORT-TERM MEMORY, Neural Computation, 1997.
  • cell
    keras.layers.LSTMCell(units)
  • CuDNN LSTM
    keras.layers.CuDNNLSTM(units)
    • CuDNN 벡엔드로 빠른 LSTM
    • TensorFlow 벡엔드로, GPU에서만 동작 가능

ConvLSTM2D

keras.layers.ConvLSTM2D(filters, kernel_size)

  • Convolustional LSTM 이라니...
  • 적용: 강수량 예측
  • input transformations and recurrent transformations 모두 convolutional
  • 논문과 다르게 현재 keras의 ConvLSTM2D는 cell의 output에서 feedback loop을 포함하지 않는다.
  • input shape
    • data_format='channels_first'이면, 5D tensor (samples, time, channels, rows, cols) 를 입력으로 받음
    • data_format='channels_last'이면, 5D tensor with shape: (samples, time, rows, cols, channels)를 입력으로 받음
  • output shape
    • return_state
      • data_format='channels_first'이면, 4D tensor with shape: (samples, filters, output_row, output_col)를 출력
      • data_format='channels_last'이면, 4D tensor with shape: (samples, output_row, output_col, filters)를 출력
    • return_squences
      • data_format='channels_first'이면, 5D tensor with shape: (samples, time, filters, output_row, output_col)를 출력
      • data_format='channels_last'이면, 5D tensor with shape: (samples, time, output_row, output_col, filters)를 출력
        (o_rowo_col은 filter와 padding의 shape에 의존)
  • ref: Xingjian Shi et al., Convolutional LSTM Network: A Machine Learning Approach for Precipitation Nowcasting, CVPR, 2015.
  • cell
    keras.layers.ConvLSTM2DCell(filters, kernel_size)

References

  1. https://keras.io/layers/recurrent/#rnn
  2. https://skymind.ai/wiki/lstm
  3. https://skymind.ai/kr/wiki/lstm 한글 페이지가 있는지 먼저 알았으면 좋았을 텐데