다시 이음

딥러닝(8) - RNN(Recurrent Neural Network, 순환 신경망) 본문

AI 일별 공부 정리

딥러닝(8) - RNN(Recurrent Neural Network, 순환 신경망)

Taeho(Damon) 2021. 10. 27. 20:16

 

안녕하세요.

 

오늘은 연속된 데이터를 처리하기 위한 새로운 신경망 구조인 RNN에 대해서 알아보려고 합니다.

 

 

언어 모델 (Language Model)

 

언어 모델이란?

 

언어 모델은 단어 시퀀스(문장)에 각 단어의 확률을 할당(assign),계산하는 모델입니다. 

 

가장 보편적으로 사용하는 방법은  앞 단어들이 등장했을 때, 다음 단어를 예측하도록 하는 것이며 이것은 특정 단어가 등장할 확률을 조건부 확률로 구하게 됩니다.

 

언어 모델을 만드는 방법은 크게는 통계를 이용한 방법과 인공 신경망을 이용한 방법으로 구분할 수 있습니다.

 

 

통계적 언어 모델 (Statistical Language Model, SLM)

 

단어의 등장 횟수를 바탕으로 조건부 확률을 계산합니다.

 

전체 말뭉치 안에서 첫번째 단어가 나오는 확률을 구하고 그 확률안에서 그 다음 단어가 나올 확률을, 이런 식으로 계속해서 반복.

 

 

- 통계적 언어 모델의 한계점

 

희소성(Sparsity) 문제 : 실제로 사용되는 표현임에도 말뭉치에 등장하지 않았다는 이유로 많은 문장이 등장하지 못하게 되는 문제를 희소 문제라고 합니다.

 

❄️ 희소성 문제를 해결하기 위해 사용되는 N-gram, Back-off, Smoothing 에 대해서 검색해보면 좋습니다.

 

 

신경망 언어 모델 (Neural Langauge Model)

 

신경망 언어 모델에서는 횟수 기반 대신 Word2Vec이나 fastText 등의 출력값인 임베딩 벡터를 사용합니다.

 

위의 방법을 채택하였기 때문에 말뭉치에 등장하지 않더라도 의미적, 문법적으로 유사한 단어라면 선택될 수 있습니다.

 

 

1) 순환 신경망 (RNN, Recurrent Neural Network)

 

RNN은 연속형 데이터를 처리하기 위해 고안된 신경망 구조입니다.

 

연속형 데이터(sequential data)란, 앞,뒤에 어떤 단어가 오느냐에 따라서 뒤따라오는 데이터의 의미도 변화하는 데이터를 일컫습니다.

 

이미지와 같은 데이터는 앞,뒤로 순서가 바뀌어도 이미지에 있는 값은 고정되어있어서 불연속형 데이터라고 말합니다.

 

 

- RNN의 구조

 

다른 신경망과 구조적으로 다른 부분이 한가지가 있습니다.

 

지금까지 우리가 알았던 신경망은 입력값(벡터)가 신경망으로 들어가면 은닉층을 통해 가중치 연산을 하고 출력층(벡터)으로 전달되었습니다.

 

그러나 RNN은 이 과정에서 hidden state vector라는 벡터는 다시 은닉층으로 돌아가 새롭게 나오는 입력값(벡터)와 다시 연산을 하게 됩니다.

 

이러한 과정이 계속됨으로써 hidden state vector는 과정이 계속될수록 앞단어의 정보를 어느정도 함유하게 됩니다. 

 

이러한 특징(Sequential 데이터의 순서 정보를 모두 기억) 때문에 Sequential 데이터를 다룰 때 RNN을 많이 사용합니다.

 

 

- RNN의 형태

 

RNN은 입력과 출력의 길이를 다르게 설계 할 수 있으므로 다양한 용도로 사용할 수 있습니다.

  1. one-to-many : 1개의 벡터를 받아 Sequential한 벡터를 반환합니다. 이미지를 입력받아 이를 설명하는 문장을 만들어내는 이미지 캡셔닝(Image captioning)에 사용됩니다.
  2. many-to-one : Sequential 벡터를 받아 1개의 벡터를 반환합니다. 문장이 긍정인지 부정인지를 판단하는 감성 분석(Sentiment analysis)에 사용됩니다.
  3. many-to-many(1) : Sequential 벡터를 모두 입력받은 뒤 Sequential 벡터를 출력합니다. 시퀀스-투-시퀀스(Sequence-to-Sequence, Seq2Seq) 구조라고도 부릅니다. 번역할 문장을 입력받아 번역된 문장을 내놓는 기계 번역(Machine translation)에 사용됩니다.
  4. many-to-many(2) : Sequential 벡터를 입력받는 즉시 Sequential 벡터를 출력합니다. 비디오를 프레임별로 분류(Video classification per frame)하는 곳에 사용됩니다.

 

- RNN의 장점과 단점

 

1. 장점 : RNN은 모델이 간단하고 (이론적으로는) 어떤 길이의 sequential 데이터라도 처리할 수 있습니다.

2. 단점 : 병렬화(Parallelization) 불가능 , 기울기 폭발(Exploding Gradient), 기울기 소실(Vanishing Gradient)

 

  • RNN 기반(벡터가 순차적으로 입력)의 모델은 GPU의 장점인 병렬화가 불가능하여 연산을 하였을 때 이점이 거의 없습니다.
  • RNN의 역전파 과정에서 기울기 폭발과 기울기 소실이 일어납니다. 하나하나 차근차근 말하면, 신경망 알고리즘에서 역전파를 진행할 때 가중치의 기울기를 업데이트하는 거라고 배웠습니다. 사실 RNN의 연산과정을 보면 역전파 시에 tanh활성화함수를 지난 행렬과 가중치의 행렬이 행렬곱(내적)연산을 거치게 됩니다. 이러한 연산을 순환 횟수에 따라 진행을 하여야 하니 기울기 값에 따라 (순환횟수)제곱만큼 역전파가 진행이 됩니다.
  • 결국 여기서 기울기값이 1미만인 경우는 제곱을 거치면서 수치가 점점 작아지며 결국 문장(시퀀스)의 앞부분의 단어들에게는 기울기 업데이트가 이루어지지 못할 정도가 되곤합니다. 이러한 경우를 기울기 소실이라고 합니다.
  • 반대로 기울기값이 1이상인 경우 제곱을 거치면서 수치가 과도하게 커지며 문장(시퀀스)의 앞부분의 단어들에게 가중치가 과하게 입력됩니다. 이러한 경우를 기울기 폭발이라고 합니다.

❄️ RNN에서는 활성화 함수로 tanh을 주로 사용하는 이유가 있습니다.

미분값을 비교해보면 되는데요. tanh의 미분값의 경우보다 다른 활성화 함수에서 미분값들은 제곱될수록 값들이 너무나도 급격하게 팽창하게 됩니다. 원래는 sigmoid를 사용했지만 너무나도 수치의 변화가 작게되어 그보다 분포가 큰 tanh으로 현재는 사용하는 것 같습니다.

 

 

위의 기울기 문제의 원인은 기울기의 크기를 제대로 통제하지 못했기 때문입니다.

 

그렇기 때문에 RNN의 문제점을 개선하기 위해 장단기 기억망(Long-Short Term Memory, LSTM)가 고안되었습니다.

 

 

 

2) LSTM (Long Term Short Memory, 장단기기억망)

 

RNN에 기울기 정보 크기를 조절하기 위한 Gate를 추가한 모델을 LSTM이라고 합니다.

 

RNN과 다른점?

 

  • hidden-state 말고도 활성화 함수를 직접 거치지 않는 상태인 cell-state 가 추가되었습니다.
  • cell-state는 역전파 과정에서 활성화 함수를 거치지 않아 정보 손실이 없기 때문에 뒷쪽 시퀀스의 정보에 비중을 결정할 수 있으면서 동시에 앞쪽 시퀀스의 정보를 완전히 잃지 않을 수 있습니다.

 

 

3) GRU (Gated Recurrent Unit)

 

LSTM의 간소한 버전이라고 할 수 있습니다.

 

 

LSTM과 다른점?

  • LSTM에서 있었던 cell-state가 사라졌습니다.
    cell-state 벡터 𝑐𝑡 ​와 hidden-state 벡터 ℎ𝑡​가 하나의 벡터 ℎ𝑡​로 통일되었습니다.
  • 하나의 Gate 𝑧𝑡가 forget, input gate를 모두 제어합니다.
    𝑧𝑡가 1이면 forget 게이트가 열리고, input 게이트가 닫히게 되는 것과 같은 효과를 나타냅니다.
    반대로 𝑧𝑡가 0이면 input 게이트만 열리는 것과 같은 효과를 나타냅니다.
  • GRU 셀에서는 output 게이트가 없어졌습니다.
    대신에 전체 상태 벡터 ℎ𝑡 가 각 time-step에서 출력되며, 이전 상태의 ℎ𝑡−1 의 어느 부분이 출력될 지 새롭게 제어하는 Gate인 𝑟𝑡 가 추가되었습니다.

 

4) 기존 RNN 기반(LSTM, GRU) 번역 모델의 단점

 

RNN이 가진 가장 큰 단점 중 하나는 기울기 소실로부터 나타나는 장기 의존성(Long-term dependency) 문제입니다.

 

이러한 문제를 해결하기 위해 LSTM,GRU가 고안되었다고 배웠습니다.

 

그러나 아무리 개선이 되어도 40개가 넘는 단어들의 집합(문장)에 적용하게 되면 똑같이 문제가 생깁니다.

 

그 이유는 hidden state vector의 길이가 고정되어있고 그 안에 일정 데이터 크기 이상부터는 담기가 어렵기 때문입니다.

 

이러한 점을 고치기 위해 Attention이라는 방법이 고안되었습니다.

 

 

5) RNN 기반 모델의 구조와 Attention의 적용

 

RNN기반 모델의 구조는 크게 Encoder(검색할 값을 분석하여 컨텍스트 벡터로 변환하는 부분)Decoder(컨텍스트 벡터(문맥벡터)를 활용하여 번역을 수행하는 부분(연관성파악))으로 나뉘어 있습니다.

 

-Encoder에서의

Query : 검색어, 질문, 주체

Key : 인덱스

Value : 값

 

-Decoder에서의

Query : 디코더의 각 step time의 hidden state vector

Key : 인코더의 hidden state vector

Value : 인코더의 hidden state vector

 

Attention이 적용되어 있지 않은 RNN 모델에서는 인코더를 거치면서 연산된 hidden state vector가 계속해서 순환되면서 업데이트가 된다고 앞에서 말씀드렸습니다.

 

그렇게 앞의 정보를 일부 포함한 벡터값이 계속해서 업데이트 되면서 마지막에 컨텍스트 벡터(문맥벡터)가 됩니다.

이 컨텍스트 벡터를 디코더로 넘겨주어 Key값이 되도록 하는 것입니다.

이 Key값을 참고하여 디코더에서는 Value를 도출하여 값을 보여주는 것입니다.

 

여기서 Attention이 적용이 되면 모든 과정은 똑같지만 인코더 연산중에 발생한 hidden state vector의 전체를 디코더에게 전달해주는 것이 다른 점입니다.

 

즉, 인코더를 거치며 생성된 hidden state vector의 값들을 h1,h2,h3,,,,h10까지 연산이 됐다고 할때

 

Attention 적용하지 않음 : h10 컨텍스트 벡터만을 디코더로 전달해줍니다.

Attention 적용됐을 때 : h1~h10에 해당하는 모든 벡터를 디코더로 전달해줍니다.

 

결국 이렇게 함으로써 기울기 소실로 인한 앞의 정보들을 잃지 않고 보존하여 가져올 수 있게 됩니다.

 

 

 

- Attention 적용되고 Decoder에서 어떻게 연산이 되는가?

 

  1. 쿼리(Query, 보라색)로 디코더의 hidden-state 벡터, 키(Key, 주황색)로 인코더에서 넘어온 각각의 hidden-state 벡터를 준비합니다.
  2. 각각의 벡터를 내적(dot)한 값을 구합니다. - 코사인 유사도를 말하는 것으로 단어의 유사도가 높은 값을 확인하는 과정입니다.
  3. 이 값에 소프트맥스(softmax) 함수를 취해줍니다. - 어떤 데이터에 얼마만큼의 유효성을 줄지 결정하는 과정입니다.
  4. 소프트맥스를 취하여 나온 값에 밸류(Value, 주황색)에 해당하는 인코더에서 넘어온 hidden-state 벡터를 곱해줍니다. - 위에서 구한 유효성을 Value에 적용하여 유효한 데이터에 힘을 실어줍니다.
  5. 이 벡터를 모두 더하여 Context 벡터(파란색)를 만들어줍니다.. 이 벡터의 성분 중에는 쿼리-키 연관성이 높은 밸류 벡터의 성분이 더 많이 들어있게 됩니다.
  6. (그림에는 나와있지 않지만) 최종적으로 5에서 생성된 Context 벡터와 디코더의 hidden-state 벡터를 사용하여 출력 단어를 결정하게 됩니다.

 

 

❄️ 제가 이해한 RNN, Attention 쉬운 예로 표현해볼게요.

 

예시는 비디오 가게로 하겠습니다.

 

비디오 점원은 사장님이 시킨 비디오 목록 100개를(Query) 정리해야합니다.

점원은 하나하나 비디오 제목(key)을 보고 찾아가며 위치(value)를 확인합니다.

그렇게 비디오 1번, 2번, 3번을 찾으러 다니다보니 어느정도 규칙이 보입니다. - encoder 진행

이 규칙을 잊지 않기 위해 표에 기입하면서 진행합니다. - hidden state vector 업데이트

이 규칙이 업데이트 될 때마다 점원은 새로운 페이지를 위에 올려서 업데이트했습니다.

마지막 위에 있는 A4용지만 가지고 자리로 돌아갑니다. - 마지막 hidden state vector만 인코더에서 디코더로 전달

 

이제 이 위치 정보가 입력된 목록을 가지고 컴퓨터에 입력하여 점원이 찾고 싶을 때 불러올 수 있게 할 것입니다.

 

컴퓨터를 키고 검색 프로그램(Decoder)에 입력하여 찾을 수 있게 되었습니다.

 

100번째 비디오(Query : decoder의 step time hidden state vector)를 찾을 때는 쉽게 찾을 수 있었습니다.

 

그런데 50번째 비디오를 찾으려고 하는데 A4용지(key:인코더의 hidden state vector)의 공간이 모자라서 1~49번째 비디오 정보(value:인코더의 hidden state vector)를 아주 조그맣게 적어 놨던 것이 기억이 났습니다. 그래도 잘 보면서 찾아봅니다.

- 앞의 정보들이 기울기 소실로 인해 파악이 어려워집니다.

 

그러다가 10번째 비디오를 찾으려고 하는데 A4용지에 적힌 글이 지렁이인지 글자인지 도무지 판단이 되지 않습니다.. - 장기 의존성(Long-term dependency) 문제

 

그런데 점원이 생각이 났습니다.

 

새로 업데이트한 A4용지 밑에 그 전의 정보들도 있었습니다. - Attention 적용

그래서 그 정보들을 다 모아와서 컴퓨터에 입력을 했습니다. - 인코더에서 디코더로 정보 전달

다시 찾아보니 1번 비디오도 잘 찾을 수 있었습니다.

 

 

이렇게 쉽게 예시로 풀어보았는데 대충 컨셉이나 느낌을 알기에는 나쁘지 않은 것 같아서 남겨봅니다.

 

 

 

 

참고 : https://wikidocs.net/21668 

https://yngie-c.github.io/deep%20learning/2020/06/25/dl_rnn/

https://wikidocs.net/22886

https://velog.io/@dscwinterstudy/%EB%B0%91%EB%B0%94%EB%8B%A5%EB%B6%80%ED%84%B0-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-%EB%94%A5%EB%9F%AC%EB%8B%9D2-6%EC%9E%A5