해당 포스팅은 네이버 부스트캠프 AI Tech 학습 정리 자료임을 알려드립니다.
1. 강의 정리
임성빈 교수님 - RNN 첫걸음
1) 시퀀스 데이터 이해하기
시퀀스 데이터는 순차적으로 들어오는 데이터를 말하는 데 소리, 문자열, 주가 등이 포함되어 있습니다. 시계열 데이터도 시간 순서에 따라 나열된 데이터로 시퀀스 데이터에 속합니다. 시퀀스 데이터는 독립동등분포($i.i.d$) 가정을 잘 위배하기 때문에 순서를 바꾸거나 과거 정보에 손실이 발생하면 데이터의 확률 분포도 바뀌게 됩니다. 특히, 시계열 데이터에서는 과거 정보나 앞뒤 맥락 없이 미래를 예측하거나 문장을 완성하는 것은 불가능합니다. 이전 시퀀스의 정보를 가지고 앞으로 발생할 데이터의 확률분포를 다루기 위해 조건부 확률을 이용할 수 있습니다.
$$P(X_{1}, ... , X_{t}) = P(X_{t} | X_{1}, ... , X_{t-1})\,P(X_{1}, ... , X_{t-1}) = \prod_{s=1}^{t}P(X_{s}|X_{s-1}, ... , X_{1})$$
$$X_{t} \sim P(X_{t} | X_{t-1}, ... , X_{1})$$
위의 조건부확률은 과거의 모든 정보를 사용하지만 시퀀스 데이터를 분석할 때 모든 과거 정보들이 필요한 것은 아닙니다. 필요성에 따라 과거의 정보를 활용해야 합니다. 시퀀스 데이터를 다루기 위해서는 길이가 가변적인 데이터를 다룰 수 있는 모델이 필요합니다. 고정된 길이 $\tau$ 만큼의 시퀀스만 사용하는 경우 AR($\tau$)(Autoregressive Model) 자기회귀모델이라고 부릅니다. $\tau$를 결정하는 것도 굉장히 어려울 때가 있는데 이런 경우에 사용되는 방법이 Latent Autoregressive Model입니다. 이 방법은 바로 이전의 정보를 제외한 나머지 정보들을 $H_{t}$라는 잠재 변수로 인코딩해서 활용합니다. 이렇게 활용하게 되면 이전의 가변적인 데이터로 예측하는 것이 아니라 고정된 데이터로 예측할 수 있습니다. 이렇게 모델링을 하게 되면, 이전의 모든 데이터를 사용할 수 있는 장점이 있습니다. 하지만, 여기서는 잠재 변수를 어떻게 인코딩할 것인지에 대한 문제가 발생합니다. 이 문제를 해결하기 위한 방법이 RNN입니다. $H_{t}$를 신경망을 통해 반복해서 사용하여 시퀀스 데이터의 패턴을 학습하도록 합니다.
2) Recurrent Neural Network 이해하기
가장 기본적인 RNN 모형은 MLP(Multi Layer Perceptron)와 유사한 모양입니다. 아래의 식은 MLP를 활용해서 구현한 수식입니다.
$$O_{t} = H_{t}W^{(2)} + b^{(2)}, \, H_{t} = \sigma(X_{t}W^{(1)} + b^{(1)})$$
위의 식에서 $H_{t}$는 잠재변수이고, $\sigma$는 활성화 함수, $W$는 가중치 행렬, $b$는 bias입니다. 이렇게 RNN모형을 구성하게 되면 이전의 정보를 활용할 수 없습니다. 그래서 이전 순서의 잠재 변수와 현재의 입력을 활용해서 모델링을 하게 됩니다. 아래의 식처럼 표현할 수 있습니다.
$$O_{t} = H_{t}W^{(2)} + b^{(2)}, \, H_{t} = \sigma(X_{t}W_{X}^{(1)} + H_{t-1}W_{H}^{(1)} + b^{(1)})$$
잠재변수인 $H_{t}$를 복제해서 다음 순서의 잠재 변수를 인코딩하는 데 사용해서 이전의 정보를 활용할 수 있도록 했습니다. 여기서 가중치 행렬 $W_{X}^{(1)}$, $W_{H}^{(1)}$, $W^{(2)}$들은 $t$에 의해서 바뀌지 않습니다.
RNN의 역전파(Backpropagation Through Time)는 잠재변수의 연결 그래프에 따라 순차적으로 계산합니다. BPTT를 통해 RNN의 가중치 행렬의 미분을 계산해보면 아래와 같이 미분의 곱으로 이루어진 항이 계산됩니다. 미분의 곱에서 vanishing gradient나 exploding gradient 현상이 발생하게 됩니다. 그래서 시퀀스 길이가 길어지는 경우 BPTT를 통한 역전파 알고리즘의 계산이 불안정(기울기 소실)해지므로 길이를 끊는 것이 필요합니다. 이 방법을 truncated BPTT라고 부릅니다. 특정 블럭에서 $H_{t+1}$에서 $H_{t}$로 그레디언트를 전달하지 않는 방법을 사용합니다. 하지만 이것이 모든 문제들을 해결할 수 있는 방법은 아닙니다. 이러한 문제를 해결하기 위해서 LSTM이나 GRU라는 모델을 활용해서 해결합니다.
최성준 교수님 - RNN
1) Sequential Model
Sequential data는 음성, 비디오 등이 포함되어 있습니다. Sequential data는 입력으로 받아야 되는 길이에 대한 차원을 알 수 없습니다. 그래서 fully connected layer나 CNN을 활용하지 못하는 것입니다. 입력이 가변적이기 때문에 발생하는 문제를 가장 쉽게 해결 방법은 과거의 정보 개수를 한정시키는 것(AR($\tau$))입니다. AR($\tau$)에서 $\tau$를 1로 하는 모델이 Markov model입니다. $\tau$를 1로 하기 때문에 Markov model은 많은 정보를 버리게 됩니다. 많은 정보를 버리지 말고 최대한 활용하기 위해서 나온 것이 Latent autoregressive model입니다.
2) RNN
RNN은 Short-term dependencies는 잘 잡을 수 있지만 Long-term dependencies는 잘 못잡는 성질을 가지고 있습니다. 예를 들어, 어제의 점심메뉴는 기억할 수 있지만 3년 전의 점심메뉴는 기억하지 못하는 것처럼 RNN도 오래된 정보를 유지하기 어렵다는 특징을 가지고 있습니다. RNN을 수식으로 표현하면, 계속 중첩되는 식이 발생하게 되는 데 그 위치에서 Vanishing / exploding gradient가 발생하게 됩니다.
3) LSTM
이러한 문제점을 해결하기 위해 나온 것이 LSTM입니다. LSTM의 구조에는 3개의 forget gate, input gate, output gate를 가지고 있습니다. forget gate는 어떤 정보를 버릴지 정하는 gate입니다. input gate는 cell state에 어떤 정보를 저장할지를 정하는 gate입니다. update cell에서는 forget gate를 통해 나온 값을 이전의 cell state와 곱해주고, input gate를 통해 계산된 값을 더해줘서 cell state를 업데이트해줍니다. 마지막으로, output gate는 업데이트된 cell state를 활용해서 output을 만들어줍니다.
4) GRU
GRU는 reset gate와 update gate 두 개의 gate들을 가지고 있으며, cell state는 존재하지 않고 hidden state만 가지고 있습니다. LSTM에 비해 조금 더 성능이 올라가는 것을 많이 볼 수 있습니다. 최근에는 transformer가 나오면서 GRU, LSTM을 잘 사용 안하게 되었습니다.
최성준 교수님 - Transformer
1) Transformer
Transformer는 일반적으로 sequential data를 다루는 모델입니다. 앞에서 다뤘던 RNN방법에서는 Trimmed sequence, Omitted sequence, Permuted sequence 들을 모델링하기가 어렵습니다. 이런 문제를 해결하고자 나온 것이 Transformer입니다. Transformer는 재귀적인 구조 없이 attention이라는 구조를 활용했습니다. Transformer는 처음에는 기계어 번역에서 사용되었지만 이미지 분류, 이미지 객체 검출, 이미지 생성 등 다양한 분야에서 활용되고 있습니다. transformer가 궁극적으로 하고자 하는 것은 sequence 형태의 언어를 다른 sequence 형태의 언어로 바꿔주는 것입니다. 여기서 입력 sequence와 출력 sequence의 단어의 개수는 다를 수 있습니다. 입력과 출력의 도메인도 다를 수 있습니다. transformer는 3개의 단어가 들어가던지, 100개의 단어가 들어가던지 한 번에 인코딩할 수 있습니다. 물론, 생성할 때는 한 단어씩 생성하게 됩니다. transformer는 동일한 구조를 가지나 네트워크 파라미터가 다르게 학습되는 인코더와 디코더가 쌓여있는 구조입니다.
여기서 우리가 이해해야 하는 내용은 3가지입니다. 첫 번째, n개의 단어가 어떻게 인코더에서 한번에 처리가 되는지 알아야 합니다. 두 번째, 디코더와 인코더 사이에 어떤 정보를 주고받는 지를 이해해야 합니다. 세 번째, 디코더가 어떻게 제너레이션을 할 수 있는 지를 이해해야 합니다.
인코더는 self-attention과 Feed forward neural network로 구성되어 있습니다. self-attention은 인코더와 디코더에 모두 들어있으며 transformer가 잘 작동하는 이유라고 볼 수 있습니다. Feed forward neural network는 MLP와 동일한 구조입니다. 맨 처음에는 단어를 특정 숫자의 벡터로 변경해야 합니다. 변경된 벡터가 self-attention을 통해서 넘어갈 때에는 다른 벡터의 정보를 모두 활용해서 넘어갑니다. 여기서 정보를 활용한다는 것의 의미는 단어와 단어 사이의 관계성을 학습하는 것입니다. self-attention 구조에서는 주어진 단어에 대한 벡터를 통해 3개의 Queries, keys, values라는 벡터들을 새롭게 만들어냅니다. 만들어내는 과정은 각각의 neural network가 있다고 생각하면 됩니다. Score 벡터는 인코딩하고자 하는 단어 A에 대한 query벡터와 key벡터의 내적으로 구할 수 있는데, 해당 단어의 query벡터와 다른 단어의 key벡터와도 곱해줍니다. 이를 통해 단어 A와 다른 단어들과의 연관성을 수치화하게 됩니다. score 벡터는 key벡터의 dimension의 루트 값으로 나눠서 정규화해줍니다. 정규화된 값을 softmax를 통해 attention rate를 구할 수 있습니다. 이 attention rate와 value와 곱해서 weighted sum을 해준 것이 최종적으로 단어 A에 대한 인코딩 된 벡터가 됩니다. 여기서 query와 key벡터는 내적을 해야 하기 때문에 항상 차원이 동일해야 합니다. transformer는 한 번에 모든 단어를 처리해야 하기 때문에 계산 자원이 많이 들어가는 단점이 있습니다.
2) Multi-head attention
multi-head attention은 앞에서 언급한 attention을 여러번 하는 것입니다. 하나의 단어에 대해서 n개의 attention을 하는 것입니다. 이렇게 하게 되면 임베딩 된 차원과 인코딩 된 차원 수를 항상 같은 차원으로 만들어주기 위해 linear map을 추가해서 동일한 차원으로 맞춰줍니다. 하지만, 실제로는 이렇게 구현되어 있지 않습니다.
3) decoder
encoder에서는 decoder로 정보를 보낼 때, Key와 value를 보내게 됩니다. 디코더에 들어가는 단어들로 만들어진 query 벡터와 encoder에서 받은 key 벡터와 value 벡터를 가지고 최종 값을 구하게 됩니다. 출력 값은 앞에서도 언급했듯이 autoregressive 하게 출력됩니다. decoder에서는 masking을 통해서 답을 알지 못하도록 제한합니다. 마지막에는 출력들을 분포로 만들어서 샘플링하듯이 결과를 만듭니다.
2. 피어 세션 정리
데이터셋 만들기(라인 캐릭터 분류), 수업 질문
3. Reference
-
transformer - jalammar.github.io/illustrated-transformer/