RNN(Recurrent Neural Network)

This entry is part 8 of 9 in the series 딥러닝 핵심 개념

1. 들어가며

이미지 데이터 처리를 위한 딥러닝 모델에는 CNN이 있다면, 시퀀스 데이터 처리를 위한 딥러닝 모델에는 RNN이 있습니다. RNN의 등장 이후로 시퀀스 데이터 처리 네트워크는 발전을 거듭하였습니다. 그 결과 RNN은 현재 많이 사용되고 있는 네트워크는 아닙니다. 하지만 RNN은 시퀀스 데이터를 처리하는 네트워크 철학의 근간을 형성한 중요한 모듈입니다.

이번 글에서는 RNN이 왜 필요했는지, 어떤 방법으로 시퀀스 데이터를 잘 처리하게 되었는지 살펴보겠습니다. 단순히 RNN의 수식을 외워서는 진정한 RNN의 의미를 느낄 수 없습니다. RNN의 필요성과 의미를 느껴야 제대로 이해할 수 있죠.

이를 위해 딥러닝 네트워크를 사용하여 문장을 번역해 보겠습니다. 문장은 여러 개의 단어들로 구성된 대표적인 시퀀스 데이터이죠. 먼저 대표적인 딥러닝 네트워크인 CNN을 사용하여 문장 번역을 시도해 보겠습니다. 이 과정에서 왜 CNN으로는 문장 번역을 할 수 없는지 살펴봅니다. 그리고 어떠한 기능이 추가로 필요한지 생각해 보겠습니다. 이를 해결하는 과정을 통해 자연스럽게 RNN의 필요성과 구성 방법을 살펴보겠습니다.

2. 딥러닝 네트워크로 문장 번역하기

이제 딥러닝 모델을 사용하여 번역기를 만들어야 된다고 가정해 보겠습니다. 이미지 데이터 처리를 위해서는 거의 항상 CNN을 사용하곤 하죠. 그럼 CNN을 사용해서 번역기도 만들 수 있을까요? 예를 들어 영어를 한국어로 번역하는 CNN을 만든다고 상상해 보겠습니다.

CNN 번역기
그림1. CNN 번역기

자, 이제 CNN을 어떻게 구성해 주면 될까요? 먼저 ‘번역’이 무슨 행위인지를 먼저 고민해야겠네요. 번역이란 A 데이터 정보를 B 데이터로 변환하는 과정이라고 생각할 수 있습니다. ‘영어’로 구성된 정보를 ‘한국어’로 변환하는 것처럼요. 생각해 보면 이미지 데이터를 처리할 때도 이런 경우가 많이 있습니다. Image Reconstruction 문제를 생각해 볼까요? 입력으로 ‘이미지’가 들어오면 출력으로 ‘이미지’가 나오죠. 데이터의 형태만 달라졌을 뿐 데이터를 변환해 준다는 점에서 Image Reconstruction과 문장 번역의 본질은 같습니다.

번역을 위한 AutoEncoder
그림2. 번역을 위한 AutoEncoder

Image Reconstruction과 문장 번역이 본질이 같다면, AutoEncoder 형태로 번역기를 만들 수 있을까요?

2-1. AutoEncoder로 문장 번역하기

AutoEncoder를 사용하여 문장 번역기를 만들어보겠습니다. 네트워크 형태는 AutoEncoder로 정해졌으니 이제 입력과 출력 데이터를 정의해 줘야겠네요. 자연어 데이터를 처리하는 방법은 다양하지만, 우리는 간단하게 단어별로 구성해 주겠습니다.

문자를 벡터로 표현하기
그림3. 문자를 벡터로 표현하기

단어별로 동일하게 10의 크기를 갖는 벡터로 구성해 줬습니다. 영어는 (I, study, deeplearning)이라는 3개의 단어 벡터가 만들어졌네요. 한국어로는 (나, 는, 딥러닝, 을, 공부, 한다) 총 6개의 단어 벡터가 만들어졌습니다. 이제 문장을 순서에 맞춰 단어별로 네트워크에 넣어보겠습니다.

CNN을 사용했을때의 문제점
그림4. CNN을 사용했을때의 문제점

영어 문장은 3개의 단어를 순서대로 쌓아서 (3×10) 사이즈의 벡터를 만들어줬습니다. 이때의 출력은 한글 문장인 (6×10) 사이즈의 벡터가 나와야겠네요. 입력과 출력의 사이즈가 다르긴 하지만, 그것 자체로 문제가 되지는 않습니다.

진짜 문제는 이겁니다. 이렇게 만든 번역기는 앞으로 입력으로는 (3×10) 사이즈의 벡터를 받아야 하고, 출력으로는 (6×10) 사이즈의 벡터를 내야 합니다. 이 말은 입력과 출력 데이터의 사이즈가 고정되어야 한다는 의미입니다. 이렇게 되면 번역기의 성능이 좋다고 해도 활용도가 대폭 줄어들게 되죠. 번역할 문장은 항상 3개 단어로만 구성되어야 하고, 번역된 문장은 6개 단어로 구성되어야 하니까요. 각 사이즈별 번역기를 전부 만들어줘야 되기도 하고요. 이렇게 해서는 제대로 된 번역기라고 할 수 없습니다.

그럼 이번에는 이런 아이디어가 떠올랐습니다. 단어를 쌓은 하나의 문장을 입출력으로 사용하지 말고, 단어별로 사용하면 어떨까요?

단어를 순서대로 입력받는 AutoEncoder
그림5. 단어를 순서대로 입력받는 AutoEncoder

단어를 하나씩 순서대로 네트워크에 넣어주는 겁니다. 먼저 입력 단어들을 하나씩 입력받아 줍니다. 네트워크는 이 정보들을 저장하고, decoder에서 번역을 하여 단어 하나씩 순서대로 출력해 주는 거죠. 아이디어 자체는 좋은데요, CNN에서 정보를 받아 저장해 놓는 기능이 있을까요? CNN을 사용하는 encoder를 단순하게 생각해 보면 이렇습니다.

Encoder 연산
그림6. Encoder 연산

입력 X에 대해 내부의 가중치 W와 연산하여 WX+b라는 형태로 출력해주고 있죠.

CNN의 정보 저장 기능
그림7. CNN의 정보 저장 기능

즉 CNN이 저장하고 있는 건 내부 가중치 W일 뿐, 중간 연산 결과를 저장할 수 있는 기능은 없습니다. 이렇게 되면 하나씩 순차적으로 들어온 데이터를 저장할 수 없습니다. 바로바로 출력으로 나가버리기 때문에 번역기로는 구현이 불가능합니다.

2-2. RNN으로 문장 번역하기

2-2-1. RNN의 구성

그럼 이제 결론이 난 것 같습니다. 번역기를 만들기 위한 (시퀀스 데이터를 처리하기 위한) 네트워크는 다음 두 가지 조건을 만족해야 합니다.

첫 번째는 순차적으로 들어오는 입력 정보를 처리할 수 있어야 합니다. 즉 시퀀스 데이터를 한 덩어리로 만들어서 이미지처럼 처리할 수는 없습니다.
두 번째는 순차적으로 들어오는 입력 정보를 저장할 수 있어야 합니다. 그래야 순서대로 받은 데이터의 내용을 압축하여 사용할 수 있으니까요.

위의 두 가지 조건을 만족하려면 새로 만들 모듈은 아래와 같이 구성되겠네요.

새로운 모듈(RNN)의 구성
그림8. 새로운 모듈(RNN)의 구성

먼저 총 3개의 입력이 순차적으로 모듈에 입력되는 모습을 볼 수 있습니다. 첫 번째 조건을 만족했네요.
데이터를 입력받으면 새로운 모듈은 결괏값과 저장된 정보를 출력해 주는 모습을 볼 수 있습니다. 그리고 이 저장 정보는 다시 다음 입력과 함께 새로운 모듈로 입력되는 모습을 볼 수 있습니다. 두 번째 조건도 만족했네요. 이 두 번째 부분이 중요합니다. 저장된 정보가 다음 입력과 함께 다시 새로운 모듈로 들어가는 부분이요. 이렇게 저장 정보를 다시 사용하는 모습 때문에 Recurrent (재사용하는) Neural Network라는 이름이 붙었거든요. 이를 줄여서 RNN이라고 부릅니다.

2-2-2. RNN을 사용한 문장 번역

자, 이제 다시 번역기 문제로 돌아가 볼까요? 그럼 우리가 만들고자 했던 번역기는 다음과 같은 형태로 만들어지겠네요.

새로운 모듈(RNN)을 사용한 번역기 구성
그림9. 새로운 모듈(RNN)을 사용한 번역기 구성

먼저 영어 문장이 단어별로 나뉘어 순차적으로 새로운 모듈에 들어갑니다. 이때 입력을 받을 때마다 업데이트된 저장 정보도 다음 입력과 함께 다시 새로운 모듈로 들어가죠. 영어 단어들이 전부 입력되면 최종적으로 저장된 정보가 나올 겁니다. 이 저장된 정보는 이번에는 한글 번역을 위한 입력으로 사용됩니다. 한국어 출력을 위한 새로운 모듈에는 최종 저장 정보와 이 전 모듈에서 나온 저장 정보가 들어가게 되죠.

이건 이렇게 생각해 볼 수 있습니다. 최종 저장 정보는 말 그대로 ‘I study deeplearning’이라는 문장 정보 전체가 압축돼 있다고 생각할 수 있습니다. 그럼 출력 모듈에서의 저장 정보는 왜 필요할까요? 어디까지 번역이 완료되었는지도 알아야 하니까요. 즉 첫 번째 출력 저장 정보에는 ‘나’까지 번역했다는 정보가 있을 겁니다. 두 번째 출력 저장 정보에는 ‘는’까지 번역했다는 정보가 있겠죠. 이렇게 ‘I study deeplearning’이라는 정보와 어디까지 번역되었는지 정보를 받아 순차적으로 번역을 하게 됩니다.

2-2-3. RNN의 수식

이번에는 수식으로 위의 스토리를 어떻게 구현했는지 살펴보겠습니다.

첫 번째로 정보를 저장하는 기능 부분의 수식을 살펴보죠. 먼저 생각해 볼게요. 무슨 정보를 저장해야 할까요? 새로 입력된 정보에 대한 내 생각과 이전까지 기억에 대한 내 생각을 종합하여 만들어줘야겠죠? 이제 수식을 보겠습니다.

RNN의 hidden state 연산
그림10. RNN의 hidden state 연산

정확하게 그렇게 구성되어 있는 모습이죠? 보통 저장 정보는 hidden state라고 하여 h로 표현합니다. 위 수식의 초록색 부분은 새로운 입력값에 대한 연산을 의미합니다. 주황색 부분은 이전 기억에 대한 연산을 의미하죠. 입력값과 이전까지의 저장 정보에 대해 W를 곱해 적절한 변형을 줍니다. 최종적으로 이 둘 정보에 비선형성을 추가하여 새로운 저장 정보를 만들어주는 모습입니다.

두 번째로 출력 정보에 대한 수식을 살펴보죠. 위의 스토리에서는 굳이 출력 정보 얘기는 다루지 않았습니다. 하지만 구현해야 하는 기능에 따라 정보 저장뿐만 아니라 정보 출력까지도 같이 해줘야 하는 경우도 있죠. 출력 정보는 새로 만들어진 기억 정보에 적절한 변형을 더해 만들어줍니다.

RNN의 output 연산
그림11. RNN의 output 연산

보통 결괏값은 y로 표현해 줍니다.

3. 마무리

지금까지 문장을 번역하는 딥러닝 네트워크를 구성해 봤습니다. 이러한 방식으로 구성된 네트워크를 RNN이라고 합니다. RNN은 순환 신경망이라고 번역됩니다. 순차적으로 입력되는 정보에 대한 저장 정보를 계속해서 재사용하기 때문이죠. RNN은 많은 개선 버전이 나와 현재는 사용되지 않습니다. 하지만 후속 연구들의 근본 철학을 형성한 중요한 네트워크입니다.

Series Navigation<< 1×1 Convolution – 작지만 알찬 ConvolutionSelf Attention 설명 : 최소한의 수식과 관련 논문으로 쉽게 이해하기 >>
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
Scroll to Top