티스토리 뷰

RNN(Recurrent Neural Network)

순차적으로 들어오는 Sequential 데이에 적합하며, 매 시점의 데이터를 누적한 정보를 이용해 모델링하게 됩니다.

 

먼저, RNN을 사용할 수 있는 데이터 예시를 살펴보겠습니다.
아래 표를 보면 어제 주가, 어제 KOSPI, 뉴스 언급량을 사용해 오늘의 주가를 예측하고자 합니다. 이 때 RNN을 사용할 수 있습니다.

 

⬛ RNN의 구조

 

현 시점 t의 정보(hidden)현 시점 t의 input(Wxh xt)과 이전 시점 t-1의 정보(hidden state, ht-1)을 결합한 것으로,

다음 단계의 hidden(ht)으로 넘겨주고 현재 단계의 아웃풋(yt)을 생성하게 됩니다.

 

임의 길이의 연속적인(sequential) 입력 데이터를 처리할 수 있고

매 시점 데이터를 처리할 때마다 동일한 파라미터 (Wxh, Whh, V, b, c)를 공유합니다.

 

RNN 구조

위의 구조에서 y2의 경우에는 'x1'과 'x2'의 의미가 담긴 벡터(representation)라 할 수 있습니다.

마지막 단계인 y4에서는 최종 분석 목적을 수행할 수 있도록 Fully Connected Layer을 연결하게 됩니다.
(예를 들어, 감성분석 분류를 할 경우 Fully Connected Layer + Softmax를 적용하여 예측하게 됩니다.)

 

 ⬛ RNN의 장점

  • 임의의 길이의 Sequential(순차적인) 입력을 처리할 수 있습니다. 다시 말해 입력과 출력의 길이가 유연하기 때문에 다양한 모델을 설계할 수 있습니다
    예를 들어, 문장분류 - many to one, 음성 인식 - many to many, 번역 - many to many(4번째)

  • 전 timestep에 걸쳐 같은 파라미터를 공유할 수 있습니다. 그러므로 긴 입력값이 들어와도 모델 크기가 증가하지 않습니다.
  • 이론적으로는 많은 이전 단계의 정보를 현재의 timestep에 적용할 수 있습니다.

.

⬛ RNN의 단점

  • 이전 timestep이 모두 계산되어야 현재 timestep을 계산할 수 있어 다소 속도가 느립니다.
  • Gradient Vanishing / Exploding 현상
  • 실질적으로 많은 step 이전의 정보를 활용할 수 있는 모델이 아닙니다.(long-term dependency)

 

⬛ RNN의 파라미터 업데이트 방식

Backpropagation Through Time(BPTT)를 이용하여 RNN의 파라미터를 업데이트 합니다.

Wh를 업데이트 하기 위해서는 Gradient를 구해야 합니다.

RNN에서는 timestep마다 weight를 공유하므로 영향을 받은 모든 시간에서의 Loss를 더해주어야 합니다.

이렇게 여러 timestep을 고려하는 과정에서 Gradient가 증폭될 수 있습니다.(Gradient Exploding )

 

그리고 과거의 정보일수록 tanh 미분값을 여러 번 곱하게 되므로 ,

과거의 정보를 반영하는 부분의 gradient가 거의 0에 가까워지게 됩니다. (Gradient Vanishing )

 

또한 현재와 먼 과거의 정보일수록 정보 의존성이 감소되어,

현 시점에서의 결정은 최근 데이터 위주로만 잘 반영이 되게 됩니다.

 

 

RNN의 Gradient Vanishing / Exploding 문제 해결

⬛ Gradient Vanishing 문제

  • LSTM, GRU 등 변형된 Recurrent Unit을 활용
    • 먼 과거의 정보도 잘 잊어버리지 않도록 변형합니다.
  • Attention 메커니즘 활용 
    • 각 timestep의 입력들에 대해 다른 가중치를 적용, 중요한 인풋의 가중치를 높입니다.

 

⬛ Gradient Exploding문제

  • Gradient Clipping 활용
    • Gradient가 너무 커질 경우, 지정된 상한선을 넘지 않도록 유지하여
      파라미터를 너무 큰 폭으로 업데이트하지 않도록 방지합니다.

 

💡경사하강법 (Gradient Decent)

[정의]
경사 하강법은 함수의 기울기(=gradient)를 이용해서 함수의 최솟값일 때의 x값을 찾기 위한 방법입니다.

[배경]
머신러닝에서 보게 되는 함수들은 형태가 복잡하여 미분계수와 그 근을 계산하기 어려운 경우가 많습니다.
미분 계수 과정을 구현하는 것보다 경사하강법을 구현하는 것이 훨씬 쉽습니다.
특히나 데이터의 양이 매우 큰 경우 경사하강법과 같은 순차적인 방법인 계산량 측면에서 훨씬 효율적입니다.

[예시]
기울기가 양수(음수) → x값 증가할수록 함수 값 증가(감소)
기울기(=미분계수) 값이 크다(작다) → 최솟값으로부터 거리가 멀다(가깝다)

Xi+1 = xi - 이동거리 * 기울기의 부호
● 기울기가 양수(음수)이면 음(양)의 방향으로 x를 옮긴다
● 미분계수는 극소값에 가까워질수록 값이 작아지므로, 이동거리에는 미분계수와 비례하는 값을 이용합니다.
     (극소값에서 멀 때(가까울 때)는 많이(조금씩) 이동)



적절한 step Size(=alpha) 선택은 매우 중요합니다. 
 - Step Size가 크면 이동거리가 커지므로 빠르게 수렴할 수 있다는 장점이 있지만 최솟값으로 수렴되지 못하고 함수값이 발산할 수 있습니다.
 - step Size가 너무 작으면 발산하지는 않겠지만, 최솟값을찾는데 너무 오래 걸릴 여지가 있습니다.