Coursera의 Deep Learning Specialization - Week 5의 강의를 수강하면서 필기한 내용을 바탕으로 정리한 글입니다.
5주차는 시퀀스 모델에 대해 배웁니다.
Sequence Model
시퀀스 모델이란, 입력 데이터가 순서를 가지고 있는 것을 말합니다. 음성 오디오의 경우가 대표적입니다.
시퀀스 모델의 입력 X는 하나의 원소가 하나의 단어를 의미합니다. i번째 예제에서 t번째 원소를 표현할 때 X(i)<t>처럼 표기합니다. 출력 Y는 입력 X가 의미하는 단어를 라벨링한 값이 됩니다.
시퀀스 길이는 Tx, Ty로 표기하고 본 예시의 경우, Tx와 Ty는 X의 길이인 9와 같습니다.
그렇다면 X<1>은 실제 모델에서 어떤 형태로 입력될까요?
사용자는 자신들의 단어 사전 Vocab을 미리 만들어 둡니다. a = 1, and = 367, ..., harry = 4075, ... , zulu = 10000처럼 말입니다. 모르는 단어의 경우, unknown을 토큰화한 <UNK>로 저장합니다.
그리고 각 단어의 라벨에 해당하는 단어에는 1을 할당하고, 이외에는 0을 할당합니다. 이렇게 하나만 1, 나머지는 0으로 할당하여 표현하는 벡터를 "원샷 벡터"라고 합니다.
라벨 y 또한 같은 방식으로 라벨링하여 모델은 X에서 Y로의 매핑을 수행하게 됩니다.
RNN(Recurrent Neural Network)
기존의 네트워크는 다른 위치에서 학습된 특징맵을 공유하지 않았습니다. 한 번에 입력된 원소들은 주어진 레이어만을 통과할 뿐이었죠. 그렇지만 시퀀스 모델은 X<1>이 X<2>, X<3>, ...에도 영향을 줄 수 있음을 직관적으로 알 수 있습니다.
그래서 반복된다는 뜻의 "Recurrent"를 붙인 RNN 모델이 사용됩니다. 입력의 첫 번째 원소 X<1>을 넣고, 그에 대한 활성값 a<1>과 X<2>를 함께 모델에 넣습니다. 그에 대한 활성값 a<2>와 X<3>를 다시 모델에 넣습니다.
모델의 형태는 아래 그림을 참고해 주세요. 아래의 경우 입력의 원소마다 y를 예측하므로 Tx = Ty이고, 오른쪽처럼 원형 화살표에 검은 박스를 올려 RNN을 암시할 수도 있습니다.
RNN의 경우 시간의 흐름에 따라 이전 입력에 대한 정보를 알 수 있다는 것이 장점이지만, 이후 입력에 대한 정보는 여전히 알 수 없습니다. 이를 개선하여 양방향(Bidirectional) RNN인 BRNN이 등장하게 됩니다. 이후에 자세히 서술하겠습니다.
아래는 STEP별로 활성값, 라벨값을 구하는 수식입니다.
Waa는 a<t>에서 a<t+1>로의 가중치, Wax는 x<t>에서 a<t>로의 가중치, Way는 a<t>에서 y<t>로의 가중치입니다.
따라서 a<t>는 이전 입력의 활성값 a<t-1>과 현재 입력 x<t>에 각 가중치를 곱한 값에 bias를 더하고, 활성 함수를 통과시킨 값입니다. 오른쪽 아래 그림처럼, Waa와 Wax를 합쳐 하나의 가중치 Wa로 표현하고 a<t-1>와 X<t>를 합치기도 합니다.
그리고 y-hat<t>는 활성값 a<t>에 가중치를 곱한 값에 bias를 더하고, 활성 함수를 통과시킨 값입니다.
Backpropagation through time
RNN의 역전파는 순전파의 반대로 진행됩니다.
아래 그림의 검은 선대로 순전파를 진행하여 각 STEP별 Loss인 L<t>를 구하고, 이를 합쳐 총 Loss L을 구합니다.
Loss function은 실제 라벨값과 예측값을 비교하는데, 아래 그림 식을 참고해 주세요.
그리고 빨간 선대로 역전파를 진행하여 매개변수 Wy, Wa를 업데이트합니다.
시간을 거스른다고 하여 "시간을 거스르는 역전파"라고 합니다.
Types of RNN
RNN의 여러 종류를 알아 봅시다.
1) One-to-One
RNN 중 하나의 스텝만을 진행하는 모델입니다. RNN이기는 하지만, 너무 간단한 형태이고 시퀀스를 직관적으로 확인할 수 없기 때문에 RNN을 굳이 사용하지 않습니다.
2) One-to-Many
하나의 입력에서 순서대로 여러 라벨을 예측하는 모델입니다. 여러 입력으로 나누기 어려운 음악 검색이나 오디오 인식 등이 있습니다.
3) Many-to-One
여러 원소를 가진 입력에서 하나의 라벨만을 예측하는 모델입니다. 대표적으로는 리뷰 글을 분석하여 Good or Bad를 판별하는 영화 리뷰 모델이나 문장을 보고 Happy or Sad를 분류하는 감정 분류 모델이 있습니다.
4) Many-to-Many
입력과 출력의 길이가 다양한 모델입니다.
Tx=Ty일 때, 주어진 문장에서 이름을 찾는 이름 인식 모델이 대표적입니다.
한편 Tx!=Ty일 때는, 다른 언어로 문장을 번역하는 기계 번역 모델이 대표적입니다.
모델의 간단한 모습은 아래 그림을 참고해 주세요.
Language Model
음성 인식 모델에서 예측한 y의 값은, 해당 단어가 맞을 확률을 의미합니다.
음성이 들어왔을 때, 'Cats average 15 hours of sleep a day'라고 인식했다고 가정합니다. 모델은 맨 앞에서부터 예측한 단어가 맞을 확률을 계산합니다. y-hat<1>의 경우, 'cats'가 맞을 확률입니다.
그 다음으로 y-hat<2>는 앞의 단어가 cats일 때, 'average'가 맞을 확률입니다.
그 다음으로 y-hat<3>은 앞의 단어가 cats average일 때, '15'가 맞을 확률입니다.
이렇게 앞에서부터 추정된 단어들의 확률을 각각 곱해서 계산하게 됩니다.
언어를 원핫벡터로 만들 때, 앞에서 말한 것처럼 '단어'마다 토큰화할 수도 있지만 알파벳 LEVEL로 내려와 각 문자마다 토큰화를 하기도 합니다. 이러한 방법의 장점은 모르는 단어에 대해 "UNKNOWN"으로 토큰화할 필요가 없다는 것입니다. 하지만 데이터의 크기가 그만큼 늘어나고, 따라서 학습 비용도 커지게 됩니다.
Vanishing Gradient of RNN
RNN의 가장 큰 문제는 기울기 소실입니다.
RNN은 이전의 정보를 얻을 수 있다는 것이 큰 특징이지만, 이러한 정보 또한 많은 레이어를 거치게 되면 그 정보가 계속 감소하여 거리가 떨어져 있을 수록 정보의 영향을 받기 어렵습니다. 이를 '장거리 의존성'이라고도 합니다.
이를 가장 잘 보여주는 예시는 영문장 중에서 중간에 큰 형용사구가 있는 문장입니다. "The cat, which ... , ____ full." 에서 Blank를 예측하려면 맨 처음에 단어가 "The cat"인지, 아니면 "The cats"인지를 확인하면 됩니다. 하지만 형용사구가 엄청 길어지면 "cat"인지, "cats"인지에 대한 정보가 많이 줄어들게 되고, RNN의 특징이 퇴색됩니다.
이러한 RNN의 기울기 소실 문제를 [GRU] 모델을 사용해 해결합니다. 이 후에 서술합니다.
기울기 폭발도 발생합니다. 이 경우는 매개변수가 오버플로우하는 것을 확인함으로써 쉽게 방지할 수 있는데, Gradient Clipping을 통해 특정 매개변수가 threshold를 넘으면 값을 다시 조정하도록 하여 기울기 폭발을 막을 수 있습니다.
GRU(Gated Recurrent Unit)
RNN의 기울기 소실을 해결하기 위해 등장한 모델입니다.
이전 정보가 담겨진 메모리 셀 c<t>가 추가됩니다. 이는 활성값 a<t>와 비슷하지만, 이전 정보가 추가된 데이터라고 생각하면 됩니다. 추가적으로 후보값 ~c(t)를 계산해야 합니다. 후보값이란 현재 입력에서 정보를 추출한 값을 의미합니다.
업데이트 게이트와 리셋 게이트 두 가지가 있습니다.
- Reset gate: 이전 정보 c<t-1>이 다음 게이트에 얼마나 적합한지를 계산하여, 이전 정보를 얼마나 잊을 것인지를 결정합니다. 축약된 GRU에서는 이 값이 사용되지 않으나, 완전한 GRU에서는 이 값을 계산하여 후보값 ~c<t>를 계산할 때 사용합니다.
- Update gate : 이전 정보 c<t-1>를 얼마나 유지시킬 것인지를 결정합니다.
이전 c<t-1>과 현재 입력 x<t>가 매개 변수로 이용되어 tanh를 통과합니다.
따라서 최종 c<t>는 ~c<t>에 Update Gate 값을 곱하여 갱신할 값을 고려하고, ~c<t-1>에 ( 1 - Update Gate ) 값을 곱하여 이전 정보에서 제거할 값을 고려한 뒤 두 값을 더하여 결정하게 됩니다.
LSTM(Long-short Term Memory)
GRU보다 먼저 등장한 LSTM이라는 모델이 있습니다. LSTM도 GRU와 비슷하게, RNN의 기울기 소실을 해결하고자 만들어진 모델입니다.
GRU와 다르게 Cell state를 제어하는 데 총 3가지 게이트가 사용됩니다.
- Forget Gate : 이전 정보를 얼마나 잊을 것인지 결정하는 게이트
이전 활성값 a<t-1>와 현재 입력 x<t>를 받아 c<t-1>에 보냅니다. - Update Gate : 현재 정보를 얼마나 갱신할 것인지 결정하는 게이트
이전 활성값 a<t-1>와 현재 입력 x<t>를 받아 Sigmoid를 통과하여 계산합니다.
반면, 똑같은 매개변수를 tanh에 통과하여 후보값 ~c(t)를 계산한 뒤
두 값을 곱하여 c<t-1>에 내보냅니다. - Output Gate : 최종 정보를 계산하는 게이트
이전 활성값 a<t-1>와 현재 입력 x<t>를 받아 Sigmoid를 통과시킨 뒤,
위의 Forget, Update Gate를 통해 계산한 c<t>를 tanh에 통과시킨 값을 곱하여 a<t>를 계산합니다.
트레이닝을 반복하면서 Gate는 어떤 정보를 버리고 어떤 정보를 기억할 것인지를 학습하게 됩니다.
모든 게이트에서 Sigmoid 함수를 이용하고 있습니다. 0에서 1 사이의 값으로, 언제나 정보를 "버리거나 유지"하는 것을 알 수 있습니다.
LSTM의 구조는 아래와 같습니다.
a<t-1>는 x<t>와 함께 모든 Gate의 입력으로 사용되고 있으며,
cell state인 c<t-1>은 Forget Gate의 계산값을 곱하여 이전 정보를 제거하고,
Update Gate의 계산값 = 후보값 * Update Parameter를 더하여 현재 입력에 대한 정보를 갱신하여 c<t>를 구합니다.
이후, c<t>를 tanh에 통과시킨 후 Output Gate 계산값을 곱하여 최종 활성값 a<t>를 계산합니다.
각 과정이 GRU에 비하여 세분화되어 있지만, 매개 변수가 많아 데이터 양이 많을 때 GRU 대신 고려할 만한 모델입니다.
BRNN - Bidirectional RNN
위에서 이후 입력에 대한 정보를 알 수 없는 단점을 개선하기 위해, 양방향 RNN인 BRNN이 도입되었습니다.
보라색 선을 따라서 a_left를 순서대로 구한 뒤에, 마지막 입력에서부터 초록색 선을 따라서 거꾸로 a_right를 계산합니다.
각 입력 별로 예측하는 y-hat을 계산할 때에는 앞에서부터 계산한 a_left<t>와, 뒤에서부터 계산한 a_right<t>가 모두 반영되어 양방향에서의 정보를 모두 고려한다는 점에서 큰 장점이 있습니다.
Deep RNN
깊게 구현한 RNN 구조입니다.
오른쪽처럼, 수평으로 순환 layer가 쌓인 형태를 가지게 됩니다.
'Deep Learning Specialization' 카테고리의 다른 글
Sequence to Sequence [Deep Learning Specialization #14] (0) | 2022.08.20 |
---|---|
Word Embeddings [Deep Learning Specialization #13] (0) | 2022.08.18 |
Face Recognition [Deep Learning Specialization #11] (0) | 2022.07.28 |
Detection [Deep Learning Specialization #10] (0) | 2022.07.27 |
CNN Case Studies [Deep Learning Specialization #10] (0) | 2022.07.26 |
댓글