0. 등장배경
Transformer: 트랜스포머는 2017년 구글이 발표한 "Attention in all you need"에서 발표된 모델로, Seq2Seq의 구조인 인코더 디코더 형태를 따르면서도 Attention으로만 구현된 모델이다. 이 모델은 RNN구조를 사용하지 않았음에도 번역 성능에서도 RNN보다 우수한 성능을 보여줬으며 지금까지도 다양한 분야에서 사용된다.
RNN, LSTM, Seq2Seq 등의 언어모델들은 연속적인 입력에 대한 모델링을 개선하여 자연어처리 분야에서 많은 성과를 가져왔으며, Seq2Seq 등의 모델들은 시간에 의존적인 입력시퀀스에 따라 hidden state를 생성하여 입력을 처리하는 구조이며, 가변적인 입/출력을 처리하는데 효과적이었다.
그러나 고정된 크기의 context vector에 모든 정보를 압축하다보니 정보손실이 발생하였으며, RNN 구조들의 전형적인 Gradient vanishing 문제가 발생하였다.
이러한 단점을 해결하기 위해서 attention 구조가 결합되었고 이를 통해서 정보손실을 보완하였다. 그러나 입력을 순차적으로 처리하기 때문에 병렬화는 불가능하였다. 즉 모든 데이터를 한꺼번에 처리하는 것이 아니라 입력 시퀀스를 순서대로 넣고 hidden state가 나오면 다음 입력에 넣는 방식을 사용하여 긴 길이의 시퀀스에서는 메모리와 계산에 많은 부담이 있었다.
이때, attention만을 생각해 보면 시퀀스 내 단어들을 벡터가 포함된 행렬 간 계산만을 통해서 병렬화가 가능하였다.
이에 아이디어를 얻어서 transformer은 input과 output 간 gloabl dependency를 추출하기 위해 recurrence 구조 대신 어텐션 메커니즘을 사용하였다.
1. Transformer: 트랜스포머
seq2seq모델 구조에서는 인코더와 디코더 각각이 하나의 RNN 모델처럼 작동했다면 트랜스포머에서는 인코더와 디코더라는 단위가 N개로 확장되는 구조이다.
1-1. Positional Encoding
RNN계열의 모델들은 단어의 위치, 순서에 따라 단어를 입력받고 처리하기 때문에 hidden state에 각 단어의 위치정보가 자연스럽게 반영되는 구조였다. 그러나 트랜스포머는 RNN구조를 사용하지 않기 때문에 단어의 위치에 대한 정보가 있어야 했다.
이러한 포지셔널 인코딩된 값들은 벡터형태로 나타내야 이후 임베딩 벡터와 결합할 수 있기 때문에, 아래의 식을 이용하여 벡터형태로 만든다.
$$ PE_{(pos,\ 2i)}=sin(pos/10000^{2i/d_{model}}) $$ $$ PE_{(pos,\ 2i+1)}=cos(pos/10000^{2i/d_{model}}) $$
이렇게 만든 positional encoding 값과 임베딩 벡터와 결합하게 된다.
1-2. Attention 구조
트랜스포머에는 총 3가지의 어텐션이 사용된다.
`Encoder Self-Attention`은 인코더에서 사용되며, `Maksed Decoder Self-Attention`과 `Encoder-Decoder Attention`은 디코더에서 사용된다.
1-3. 트랜스포머 인코더
트랜스포머는 `num_layers` 만큼의 인코더 층을 쌓는데, 논문에서는 6개의 인코더 층을 사용하였으며 각 인코더층은 총 2개의 sublayer로 나눠진다. 하나는 앞에서 설명한 `Multi head Self-Attention layer`이고 나머지는 `Position-wise FFNN(Feed Forward Neural Network)`이다.
1-3-1. Multi-head self attention
self-attention이란, 어텐션을 스스로에게 수행한다는 의미이다.
기존의 seq2seq에서는 디코더가 생성하는 특정 시점의 hidden state와 입력 문장들의 관계를 계산하기 위해 attention을 사용했는데, 여기서는 한 문장에서 수행하는 것이다.
attention을 구하는 과정 자체는 이전과 동일한데 이때 이전에는 dot-product attention을 사용했다면 여기서는 scaled-dot production이라는 계산을 사용한다. 추가적으로 이 과정을 각 단어 벡터별로 나눠서 계산할 것이 아니라, 행렬 계산으로 계산하면 더 빠르다는 것이 핵심이며, 위 과정을 한 번에 행렬로 계산하게 되면 한 문장에서 각 단어 벡터끼리의 attention value값을 구할 수 있게 된다.
또한 이 전체 벡터를 논문 기준으로는 512벡터를 사용하였는데 이를 한 번에 계산하는 것이 아니라, `num_head`라는 파라미터 논문에서는 64로 설정하여 총 512/64=8, 8번의 어텐션을 계산하는 병렬적인 방법을 사용하였다. 이때 나눠진 8개의 어텐션 값 행렬을 `어텐션 헤드`라고 부르며 어텐션 헤드마다 사용되는 가중치 행렬의 값은 모두 다르게 적용되어 모두 다른 특징들을 보게 된다.
각 벡터들이 Multi-head self attention 층을 통과한후 일반적인 neural network의 feed forward 신경망을 나타내는 FFNN layer을 거쳐 나온 출력이 다음 인코더로 들어가게 된다.
이러한 인코더간의 연산과정에는 `잔차 연결`과 `레이어 정규화` 기법이 사용되는데
잔차 연결은 sublayer의 출력에 입력값을 다시 더해주는 것을 의미하며 이를 통해 출력표현에 입력표현의 정보가 남아있도록 하는 과정이다. 다음으로 레이어 정규화는 데이터 샘플 간의 평균과 표준편차를 이용하는 데이터 정규화 과정이다.
이렇게 진행된 후 마지막 층의 인코더의 출력을 디코더에게 전달하고 디코더 또한 num_layers만큼의 연산을 하게된다.
1-4. 트랜스포머 디코더
디코더도 인코더와 동일하게 임베딩 층과 포지셔녈 인코딩을 거친 후 문장 행렬이 입력되는데, Teacher Forcing 기법을 사용하여 훈련되기 때문에 학습과정에서 디코더는 정답문장에 해당되는 문장 행렬을 한 번에 입력한다. 이때 seq2seq에서는 단어를 하나씩 넣어주기 때문에 상관이 없었는데 트랜스포머에서는 문장 전체를 한 번에 입력해 주기 때문에 이후의 단어들에 대한 정답값도 들어가게 된다.
이를 방지하기 위해 `look-ahead mask`를 진행하여 디코더의 첫번째 sublayer에서 이뤄져서 이후의 정답 문장들을 마스킹한다.
다음으로 두번째 sublayer에서는 encoder decoder attention이 적용되는데, 이는 인코더에서 수행한 self attention처럼 자신 문장끼리의 attention을 계산하는 것이 아니라, 인코더행렬과 디코더 행렬 간의 attention을 계산하는 것이다.
디코더의 마지막 층에서는 다중 클래스 분류 문제를 풀도록 vocab_size만큼의 크기를 가지는 Dense layer가 존재한다.
이러한 Transformer은 자연어처리가 아닌 분야들에서까지 SOTA 모델로 자리잡았으며, 사용성과 성능을 모두 잡은 범용적인 델이다. 또한 모델 구조가 커져도 내부 파라미터를 효과적으로 사용할 수 있어 좋은 모델로 평가받는다.
'ML & DL > NLP' 카테고리의 다른 글
[패캠/NLP] BERT (0) | 2023.12.28 |
---|---|
[패캠/NLP] GPT (0) | 2023.12.27 |
[패캠/NLP] 문장 임베딩 ELMo (1) | 2023.12.22 |
[패캠/NLP] 문장 임베딩 (1) | 2023.12.22 |
[패캠/NLP] Word2Vec 워드 임베딩 실습 (1) | 2023.12.20 |