딥러닝_RNN_순환신경망_1. RNN과 LSTM, RNN 고급사용

주지윤·2022년 12월 14일
0

딥러닝

목록 보기
20/21
post-custom-banner

Recurrent Neural Network


🔸 순환신경망(Recurrent Neural Network): 유닛간의 연결이 순환적 구조

  • 스스로를 반복하면서 이전 단계에서 얻은 정보가 지속(재귀적 활동)

  • 셀(cell): 은닉층에서 활성화 함수를 통해 결과를 내보내는 역할을 하는 노드

    • 이전의 값을 기억하려고 하는 일종의 메모리 역할을 수행
  • 셀 = 상태(state): 은닉층의 메모리 셀에서 나온 값을 자신의 입력으로 사용하기 위해 저장한 것

🔸 참고_순방향 신경망(feedforwaard network): 노드 간의 연결이 순환을 형성하지 "않는" 인공 신경망

  • ex: 5일간의 데이터를 펼쳐서 하나의 큰 벡터로 만들어 처리

🔸 참고_Feed Forward Network VS Recurrent Network

  • Feed Forward Net

    • 일반적인 구조의 신경망
    • 입력층 → 은닉층 → 출력층으로 이어지는 단방향 구조
    • 이전 스텝의 출력이 영향을 받지 않음
  • Recurrent Net

    • 이전 층(Layer), 또는 스텝의 출력이 다시 입력으로 연결되는 신경망 구조
    • 각 스텝마다 이전 상태를 기억 시스템(Memory System)
    • 현재 상태가 이전 상태에 종속

RNN 처리 방식

  1. 초기 상태(initial state) = 0
  2. (timesteps,input_features) 2차원 텐서로 인코딩된 시퀀스를 입력
  3. 처음 출력된 값 = 타입스텝t1
  4. 현재상태와 입력을 연결하여(타입스텝t1) 출력 계산
  5. 출력값은 다시 타입스텝t2로 저장

🔸 현재 시점 t

  • 은닉 상태값 = hth_t
  • 은닉층의 메모리 셀은 hth_t를 계산하기 위해 총 두 개의 가중치를 가짐
    • 입력층을 위한 가중치: WxW_x
    • 이전 시점(t-1)의 은닉 상태값인 ht1h_{t-1}을 위한 가중치: WhW_h


RNN 모델의 활용

이전값을 저장하여 내부적으로 순환되는 구조를 이용하기 때문에 순서(sequence)가 있는 데이터를 처리하는데 강점을 가짐

  • 문장이나 음성같은 연속적 데이터: 문장에서 단어가 놓여진 위치에 따라 의미가 달라질 수 있음
  • 시계열 데이터: 온도 예측, 주가 예측

케라스로 RNN 구현: SimpleRNN

  • 입력: (batch_size, timesteps, input_features) 크기의 3D 텐서를 입력

  • 출력: 사용자의 설정에 따라 두 가지 모드로 실행 가능

    • return_sequences 매개변수 활용
      - =True: 각 시점의 은닉 상태값을 모아 전체 시퀀스 (batch_size, timesteps, output_features) 3D 텐서 반환
      - 순환층을 차례대로 쌓으려면 모든 중간층은 전체 시퀀스를 출력해야한다.
      - False: 최종 시점의 은닉 상태만 반환(batch_size, output_features)2D 텐서

SimpleRNN(hidden_units, input_shape=(timesteps, input_features))

  • hidden_units = 은닉 상태의 크기를 정의. 메모리 셀이 다음 시점의 메모리 셀과 출력층으로 보내는 값의 크기(output_features)와도 동일. RNN의 용량(capacity)을 늘린다고 보면 되며, 중소형 모델의 경우 보통 128, 256, 512, 1024 등의 값을 가진다.
  • timesteps = 입력 시퀀스의 길이(input_length)라고 표현하기도 함. 시점의 수.
  • input_features = 입력의 크기.


🔸 Sequential( ) 사용

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import SimpleRNN

model = Sequential()
model.add(SimpleRNN(3, input_shape=(2,10)))
# model.add(SimpleRNN(3, input_length=2, input_dim=10))와 동일함.

🔸 함수형API 사용

import keras
from keras import layers

# 마지막 timestep만 출력

num_features = 14
steps = 120

inputs = keras.Input(shape=(steps,num_features))
outputs = layers.SimpleRNN(16, return_sequences=False)(inputs)
model = keras.Model(inputs=inputs,outputs=outputs)

model.summary()

# 전체 timestep(상태 시퀀스) 출력

inputs = keras.Input(shape=(steps,num_features))
outputs = layers.SimpleRNN(16, return_sequences=True)(inputs)
model = keras.Model(inputs=inputs,outputs=outputs)
model.summary()


SimpleRNN의 한계

  • 너무 단순한 구조
  • 장기 의존성 문제(the problem of Long-Term Dependencies): 그레이디언트 소실과 비슷한 문제 때문에 긴 시간에 걸친 의존성은 학습하기 힘들다.
    • 시점(time step)이 길어질 수록 앞의 정보가 뒤로 충분히 전달되지 못하는 현상이 발생

장단기 메모리 LSTM(Long Short-Term Memory)

  • RNN단점 극복
  • 긴 의존 기간을 필요로 하는 학습을 수행할 능력
  • Cell state는 컨베이어 벨트와 같아서, 작은 linear interaction만을 적용시키면서 전체 체인을 계속 구동
    • (잔차 연결과 비슷한 방식)
    • 시퀀스의 어느 시점에 대한 정보를 필요한 시점의 타임스텝에 떨굼

LSTM의 핵심 아이디어

  • LSTM은 cell state에 뭔가를 더하거나 없앨 수 있는 능력을 가짐
    • Gate라고 불리는 구조에 의해서 제어
    • Gate는 정보가 전달될 수 있는 추가적인 방법, (sigmoid layer * pointwise)
    • LSTM은 3개의 gate를 가짐

🔸 1단계 "forget gate layer"

  • cell state로부터 어떤 정보를 버릴 것인지를 정함
  • sigmoid layer: 1이면 "모든 정보를 보존해라"가 되고, 0이면 "죄다 갖다버려라"

🔸 2단계 "input gate layer"

  • sigmoid layer: 어떤 값을 업데이트할 지 정함
  • tahn layer: 새로운 후보값 vector를 만들고 cell state에 더할 준비

🔸 3단계 "output gate layer"

  • sigmoid layer: input데이터를 가지고 cell state의 어느 부분을 output으로 내보낼지 결정
  • tanh layer: cell state를 -1과 1사이의 값으로 받아 sigmoid layer에서 계산한 output과 곱하여 최종 output으로 내보냄



RNN 고급 사용법

  • 순환 드롭아웃(recurrent dropout): 순환층에서 과대적합을 방지하기 위해 드롭아웃(매개변수) 사용

    • recurrent_dropout = ...

  • 스태킹 순환(stacking recurrent layer): 순환층을 여러개 쌓는 것으로, 모델의 표현능력 향상 / 계산 비용 ↑

    • 스태킹 순환층 사용시 모든 중간층에서는 전체 시퀀스(타임스텝)을 출력하여야 한다
      - return_sequences = True

  • 양방향 순환(bidirectional recurrent layer): 순환 네트워크에 같은 정보를 다른 방향으로 주입.

    • 정확도를 높이고 기억을 오래 유지
    • 단방향 RNN이 놓치기 쉬운 패턴을 감지
post-custom-banner

0개의 댓글