41. NN의 꽃 RNN 이야기 (lec 12)


Neural Network의 꽃이라고 불리는 RNN(Recurrent Neural Network)에 대해서 소개하는 동영상이다.


RNN은 sequence data를 처리하는 모델이다. sequence는 순서대로 처리해야 하는 것을 뜻하고, 이런 데이터에는 음성인식, 자연어처리 등이 포함된다. 자연어의 경우 단어 하나만 안다고 해서 처리될 수 없고, 앞뒤 문맥을 함께 이해해야 해석이 가능하다.

얼마나 배웠는지는 모르지만, 지금까지 열심히 공부한 neural network이나 convolutional neural network으로는 할 수 없다고 하신다.


순차적으로 들어오는 입력을 그림으로 표현하면 위와 같이 된다. 똑같은 모양이 오른쪽으로 무한하게 반복된다. 이걸 간단하게 표현하려고 하니까, 그림 왼쪽과 같은 형태가 된다. A에서 나온 화살표가 다시 A로 들어간다. 프로그래밍에서는 이런 걸 재진입(re-enterence) 또는 재귀(recursion)라고 부른다. 이쪽 세계에서는 recurrent라는 용어를 쓰고, "다시 현재"라는 뜻이고 정확하게는 "되풀이"라고 해석한다.

RNN에서 가장 중요한 것은 상태(state)를 갖는다는 것이고, 여기서는 ht로 표현하고 있다. 반면 매번 들어오는 입력은 Xt라고 표현한다. h는 상태를 가리키지만, 동시에 hidden layer를 가리키는 뜻도 있기 때문에 약자로 h를 사용한다.


RNN(Recurrent Neural Network)은 일반적으로 step을 거칠 때마다 어떤 결과를 예측하게 된다. 그리고, 이런 예측 값을 앞에서 배웠던 것처럼 y라고 부른다. y = Wx + b라고 생각하면 된다. 이 그림에서는 예측 값인 y를 표현하는 대신 상태를 의미하는 h는 표시하지 않고 있다. 뒤쪽에 가면 y와 h가 함께 표시된 그림을 볼 수 있다.


공식으로 표현하면 위와 같이 된다. 이전 단계에서의 상태 값과 입력 벡터(x)로 계산하면 새로운 상태 값이 만들어진다. 코드로 표현하면 아래와 같이 된다. 여기서 노드 갯수는 layer에 포함된 노드(그림에서는 초록색으로 표시된 RNN) 갯수를 말한다.

  for _ in range(노드 갯수):
      현재 상태 = W에 대한 함수(이전 상태, 입력 벡터)


바닐라(vanilla)는 아무 것도 첨가하지 않은 처음 상태의 아이스크림을 의미한다. 여기에 초코나 딸기 시럽을 얹고 땅콩 가루를 뿌리는 등의 옵션을 추가하면 맛이 더 좋아진다. 바닐라는 아무 것도 가공하지 않은 처음 형태로, 바닐라 RNN은 가장 단순한 형태의 RNN 모델을 뜻한다.

t는 sequence data에 대한 특정 시점의 데이터를 가리키고, 여기서는 t에 대해 두 가지를 계산한다. 첫 번째 줄의 공식은 W의 이전 상태와 입력을 갖고 fw에 해당하는 tanh 함수를 호출하는 것이다.

ht는 현재 상태를 의미하고 h의 t-1번째는 이전(old) 상태와 입력 값(x)을 사용해서 계산한다. yt는 예측 값을 의미하고, W와 현재 상태(ht)를 곱해서 계산한다.


같은 함수에 대해 같은 입력이 매번 똑같이 사용되고 있다고 강조한다. step마다 다른 값이 적용되는 것이 아니다.


글자를 다루는 RNN을 문자 기반의 언어 모델(Character-level Language Model)이라고 부른다. 일반적으로 language model은 출력 결과로 단어와 같은 글자를 예측하는 모델이라고 얘기한다. 여기서는 4가지 종류의 글자 h, e, l, o가 있고, 연속된 sequence인 "hello"에 대해 이후에 나올 값을 예측하려고 한다.


4가지 종류의 글자가 있기 때문에 크기가 4인 벡터(리스트)로 처리한다. multi-nomial classification에서 봤던 것처럼 4가지 중에서 하나를 선택하게 하려고 한다. 몇 번째 값이 켜졌느냐에 따라 순서대로 h, e, l, o가 된다. 이번 그림에는 'o'가 없다.

공식에서 보여주는 것처럼 h의 값과 x의 값을 W와 계산한 다음 tanh 함수에 전달하면 hidden layer에서 보여주는 값이 차례대로 만들어 진다. 매번 계산이 끝날 때마다 새로운 상태를 가리키는 hidden layer의 값이 바뀌는 것을 볼 수 있다.

tanh 함수는 sigmoid 함수 중의 하나로 처음 나왔던 sigmoid를 개량한 버전이다. 기존의 sigmoid가 0에서 1 사이의 값을 반환하는데, tanh 함수는 -1에서 1 사이의 값을 반환하도록 개량했다. 현재 상태를 가리키는 ht는 tanh 함수의 반환값이므로 -1과 1 사이의 값이 된다. 그래서, hidden layer에 있는 값들도 해당 범위에 존재하게 된다.


최종적으로는 모든 단계에서 값을 예측하고 실제 값과 맞는지 비교할 수 있다. "hello"가 들어왔다면, "hell"에 대한 예측은 "ello"가 되어야 하지만, h가 입력된 첫 번째 예측에서는 o가 나왔기 때문에 틀렸다. [1.0, 2.2, -3.0, 4.1]은 네 번째가 가장 크기 때문에 one-hot encoding을 거치면 o가 된다. e를 예측했어야 했다. 나머지는 정확하게 예측을 하고 있다.

마지막으로 정리해 본다. RNN의 핵심은 상태와 예측에 있다. 상태를 가리키는 값은 hidden layer에 있고 매번 바뀐다. 예측을 가리키는 값은 output layer에 있고 매번 예측한다.

위의 그림은 학습 중의 상황을 보여주기 때문에 75%의 정확도를 보여주고 있다. 학습이 종료됐다면, 잘못 예측한 첫 번째 노드까지 정확하게 예측해야 한다.


RNN을 통해서 할 수 있는 것들을 정리해 주셨다.


첫 번째 그림으로 바닐라 RNN을 가리킨다. 가장 단순한 형태로 1대1(one-to-one) 기반의 모델이다.


1대다(one-to-many) 기반의 모델로 이미지에 대해 설명을 붙일 때 사용한다. 한 장의 그림에 대해 "소년이 사과를 고르고 있다"처럼 여러 개의 단어 형태로 표현될 수 있다.


다대1(many-to-one) 형태의 모델로 여러 개의 입력에 대해 하나의 결과를 만들어 준다. 우리가 하는 말을 통해 우리의 심리 상태를 "안정", "불안", "공포" 등의 한 단어로 결과를 예측할 때 사용된다. sentiment는 감정을 의미한다.


다대다(many-to-many) 형태의 모델로 기계 번역에서 사용된다. 여러 개의 단어로 구성된 문장을 입력으로 받아서 여러 개의 단어로 구성된 문장을 반환한다. 구글 번역기 등이 이에 해당한다.


다대다(many-to-many) 모델의 또 다른 형태다. 동영상같은 경우는 여러 개의 이미지 프레임에 대해 여러 개의 설명이나 번역 형태로 결과를 반환하게 된다.


RNN도 여러 개의 layer를 두고 복잡한 형태로 구성할 수 있다. 위의 여러 가지 그림들을 다단계로 배치한 형태라고 보면 된다.


RNN 또한 layer가 많아지면서 복잡해지기 때문에 이를 극복할 수 있는 다양한 방법들이 소개되고 있다. 현재는 RNN이라고 하면 많은 경우 LSTM을 의미한다. 그리고, LSTM처럼 많이 사용되는 방법으로 대한민국의 조교수님께서 만든 GRU도 있다.