1. Recurrent Neural Network (RNN)
지금까지의 네트워크 구조는 하나의 입력에 대한 하나의 출력을 내보내는 네트워크였다. 그렇기 때문에 CNN에서도 하나의 이미지에 대한 결과를 나타냈었는데 음성 및 문자 등 순차적으로 등장하는 데이터처럼 입력의 길이와 출력의 길이가 가변적인 문제에서는 어떻게 처리해야할까?
이 문제를 해결하기 위해 RNN을 사용한다. RNN이란 시퀀스와 연결된 노드로 구성된 네트워크이다.
2. RNN의 구조도
RNN의 구조는 문제에 따라 다르게 정의될 수 있다. 다음은 그 구조도이고, 각각 대표적으로 어떤 문제에 사용되는지 알아보자.
one to many : 이미지 -> 단어의 연속 (이미지 설명)
many to one : 단어의 연속 -> 문장 (단어 분석)
many to many : 단어의 연속 -> 단어의 연속 (언어 번역 [영어 -> 프랑스어])
many to many(모든 입력에 대한 출력) : 비디오의 프레임 별 분류 (프레임별 즉각적인 해석)
예시로는 이미지를 해석할 때 CNN과 다르게, 연속한 glimpse(이미지의 일부, 포커스)를 학습하여 분류하는 many to one 문제로 표현할 수도 있다.
3. RNN의 연산
이 연산을 매 time step마다 한다. 여기서 눈여겨 볼 점은 사용하는 함수나, 사용하는 파라미터 W는 매 스텝마다 변하지 않는다는 것이고, old state를 이용하여 new state를 만든다는 것 정도가 있다. 이를 이용해서 RNN의 Computational graph를 만들어 보면 다음과 같다.
이 Computational graph는 many to many RNN일 때이다. 각 출력에 대하여 Loss가 있고, 그 Loss를 다 더해서 전체의 Loss를 구하고 그 Loss를 이용해서 gradient를 구하고, W를 업데이트함을 확인할 수 있다. 다른 RNN 경우의 Computatinoal graph는 다음 그림으로 확인해보자
전체적인 구조는 조금 다르지만, 하나의 노드로 나누어 보면 아까 보았던 대로, 입력과 이전 상태를 이용해서 새로운 상태를 만든다는 점은 동일하다.
4. RNN의 예시
입력을 받고, 단어를 예측하여 다음에 올 문자(순서)를 예측하는 모델을 훈련한다고 가정하자.
첫번째 문자 h부터 l까지 문자를 입력하고, hidden state를 이용하여 output을 낸다, 이때 다음으로 나올 문자에 해당하는 부분에 높은 값을 배정하도록 한다. 다른 값이 더 크다면 Loss가 더 클 것이고, 정답이 더 크다면 Loss는 더 작을것이다. 이렇게 계산된 Loss들을 합하고, 미분하여 backpropagation을 통해 parameter를 업데이트 한다. 이렇게 단어 hello을 포함한 단어들에 대해서 모델 RNN이 학습하였다고 가정하자. 이제 hell를 입력하고 다음에 어떤 문자가 와야할지 예측하는 test-time에 어떤 과정을 거치는지 알아보자.
우선 입출력인 h,e,l,o를 one-hot encoding을 이용하여 표현해주자. 그리고 state와 parameter를 이용하여 output을 계산해주고, softmax를 이용하여 이것을 가능도로 표현해주고, 그 가능도에 맞게 샘플을 뽑고, 다음 input으로 넘긴다. 이때 max를 쓰는게 아니라, softmax를 이용한 확률적 샘플링을 쓰는 이유는 교정을 위한 것이다. 만약 max로 그냥 하나를 뽑으면 교정이 어렵지만, 확률이 낮더라도 뽑힌 샘플을 이용하면 교정을 할 수 있기 때문이다. 위 예시에서도 h의 입력에 대한 결과가 사실은 e보다 o의 확률이 더 높지만, softmax를 이용하여 뽑혔음을 확인할 수 있다.
5. RNN의 backpropagation
RNN의 장점이 음성, 문자 등과 같은 데이터를 처리할 때와 같이 입력, 출력의 길이가 가변인 점이라고 하였다. 만약 이 데이터가 매우 길어서 무한에 가깝다면, backpropagtaion시 Loss 계산 (범위든지, 정밀도든지), gradient계산 등에 문제가 생겨 효율적이지 않을것이다. 그렇기 때문에 일정 범위씩 자르고, Loss를 계산하고, parameter를 update하는 방식을 이용한다. 이를 Truncated backpropagation이라고 한다.
이제 범위를 잘라 Loss를 계산하는 것까지 확인했으니, 이 Loss를 이용해서 어떻게 gradient를 바꿀지에 대해서 알아보자. 하나의 hidden state를 자세히 살펴보면 다음과 같다.
Hidden state는 이전 hidden state와 입력과 파라미터 W에 의해서 생성됨을 확인하였다. 여기서 눈여겨 볼 것은 dh_t/dL이 upstream gradient로 들어오면, dh_t-1 / dL을 연산해주어야 하는데, 이 과정에서 h_t-1 * W의 matrix multiplication의 미분이 W의 transpose를 곱해주는 것으로 치환되기 때문에, backpropagtion하면서 매 hidden state마다 W의 일부가 반복적으로 곱해진다. 이렇게 되면 backpropagation시 W의 값의 범위에 따라서 gradient가 0으로 수렴하는 vanishing gradient문제나 gradient가 무한으로 발산하는 exploding gradient 문제가 발생하게 된다.
이를 해결하기 위해서 gradient의 크기가 일정 threshold를 넘어서면 일정 상수의 gradient를 갖게 하는 gradient clipping을 적용하여 이를 방지하긴 하지만 근본적으로 문제를 해결하지 못한다. 그렇기 때문에 RNN의 기본 구조를 유지하면서 Backpropagation중, W의 연속 곱이 되지 않도록 변형한 것이 다음에 서술할 LSTM이다. LSTM의 구조를 알아보기에 앞서 RNN이 어떻게 사용될 수 있는지 확인해보자.
6. 다른 모델과의 병합 예시
서로 다른 네트워크를 병합하여 새로운 문제를 해결할 수 있던것과 같이, RNN도 다른 네트워크들과 함께 사용하는 경우가 존재한다. 다음은 그 예시이다.
1. Image captioning (CNN + RNN)
CNN에서 FC-4096 등을 거치고 FC-1000과 softmax layer를 거쳐서 클래스를 분류한다. 여기서 분류를 위한 FC-1000과 softmax layer를 제거하고, FC-4096까지만 남겨두어 사진에 대한 특징을 벡터로써 출력하는 하나의 네트워크로 설정할 것이다. 그리고 이렇게 나온 이미지의 특징 벡터를 RNN의 가중치로 전달하여 그 이미지에 대한 caption을 리턴한다. 출력의 길이가 가변이므로, end token이 output으로 나올 때 까지 반복한다.
이를 시각적으로 볼 수 있는 방법으로는 image captioning에 attention을 추가하는 것이다. RNN은 각 단어를 생성할 때 다른 특징을 보는데 이를 가시화 하는 것이다.
CNN의 결과로 나온 이미지에 대한 특징 데이터(특징 데이터를 담는 vector가 아닌, 이미지의 공간 데이터를 담는 matrix로)를 이용하여 단어의 분포 뿐만 아니라 location의 분포(attention)를 계산한다. 이 분포와 CNN의 이미지 공간 데이터를 연산하여 attention을 만들어 낸다. 이 attention vector와 summary vector가 다시 네트워크에 입력으로 주어지고, 이 과정이 반복되면서 attention과 captioning을 얻게된다.
2. Viusual Question answering
이미지와 문장 데이터를 받아 문장에 대한 정답을 내는 문제이다. CNN의 출력인 이미지 특징 벡터와 질문을 concat해서 FC에 붙여 LSTM에 전달하고, 이에 대한 문장 데이터와 attention을 통해 정답 및 segmentation을 얻는 것이다.
7. LSTM
여기서 나온 LSTM은 무엇일까?
지금까지 본 RNN은 하나의 recurrent layer만 가졌다. 하지만 일반 네트워크도 레이어가 깊으면 좋듯이, 다중 정보를 내포하고 싶을 때 이는 부족하므로, 여러 개의 hidden state를 포함하고, 전달할 수 있는 모델이 LSTM이다. 이때 layer의 갯수는 깊게 할 순 있지만 2~4개면 충분하다고 한다.
다중 hidden state를 갖기 때문에 이를 계산하는 방식이 조금 달라진다.
가장 중요한 것은 기존 RNN과 다르게 hidden state와 cell state라는 두가지의 State를 이용한다는 것이다. cell state는 4가지의 이전 cell state와 gate를 통해 연산되며 이 gate들은 기존 h_t를 연산할때와 같이 W와 h_t-1과 x_t로 연산된다. 이렇게 구조를 세움으로써 기존 RNN의 backpropagate과정에 나타나던 gradient에 관한 이슈들이 해결할 수 있는것이다.
위 사진은 하나의 hidden state에 대한 계산 식이다. 이것이 forwarding 되면서 기존 RNN보다 복합적인 결과를 도출한다. 이를 전체 네트워크로 확장하면 다음과 같다.
이전 RNN의 문제였던 같은 수 W의 중첩 곱셈 문제가 사라지고 더 방해받지 않는 gradient flow가 완성됨을 볼 수 있다. 실제 어떻게 계산되는지 다음 움짤을 보면서 확인해보자.
upstream gradient가 들어오고, local gradient를 이용하여 4가지 gate에 대한 Loss의 미분값을 구한다. 이 gate에 대한 미분을 합치면 dH / dL을 구할 수 있고, 이를 이용하여 x, w, h에 대한 Loss의 미분을 얻을 수 있다.
// 이에 대한 증명도 한번 직접 해보기
8. Referencce
CS231n Lecture 10
https://ratsgo.github.io/natural%20language%20processing/2017/03/09/rnnlstm/
'ML' 카테고리의 다른 글
CS231n lecture 12 : Visualizing and Understanding (0) | 2021.07.12 |
---|---|
CS231n Lecture 11 : Detection and Segmentation (0) | 2021.07.12 |
CNN 구조 (0) | 2021.07.06 |
인공지능 Learning rate, Regularization, Weight update, Transfer Learning (0) | 2021.07.05 |
다양한 Gradient descent optimization (0) | 2021.07.05 |