1) Transformer
Sequential model이 다루기 힘든 문제들
중간에 시퀀스 데이터가 누락되거나, 순서가 바뀌거나 잘리는 문제들은 Sequential model로 다루기가 쉽지 않다.
또 기존의 RNN 들은 어쨌든 순서대로 진행하기 때문에 어쩔 수 없는 기억력의 한계가 있었다.
Transformer 는 이러한 Long-term-dependency 를 attention 을 통해 해결했다. 순서에 상관없이 모든 관계에 대해 모델링이 가능한 것이다.
또, Transformer 는 Sequential model처럼 재귀적 구조가 아닌 attention 이란 구조를 활용해 한번에 계산 한다. 예를들어 RNN에 3개의 단어가 로 이루어진 문장이 들어간다면 RNN을 3번 돌려서 실행해야하지만 transformer는 한번에 찍어낼 수가 있다.
좀 더 자세히 transformer의 내부를 들여다 보면 각 encoder와 decoder는 6개로 구성되어 있다. 각각의 Encoder와 Decoder들은 독립적인 파라미터를 가지고 있어 서로 다르게 학습을 진행한다. 그렇다면 이제 각 Encoder가 어떻게 구성되어 있는지 보자.
각 encoder는 self-attention 층과 feed Forward Neural Network로 이루어져 있다. feed forward 는 앞에서 보았던 MLP와 동일하다. Decoder 또한 같은 self -attention을 사용한다. Transformer 에서 이 self-Attention이 핵심이라고 할 수 있으니 이제 작동원리를 파혜쳐보자.
먼저 우리는 각 단어들을 embedding vectors로 만들어 줘야 한다. embedding vectors의 길이는 임의로 설정한다.
각 임베딩된 단어 벡터들이 Self-Attention layer에서는 서로 의존적으로 영향을 미치게 된다. 하지만 feed forward layer에서는 각각 독립적으로 계산된다.
Positional Encoding
하지만 위 그림처럼 단어들이 바로 들어가는 것이 아니다. 입력하기 전 Positional Encoding 이라는 것이 필요하다. 왜냐면 Transformer에서는 sequence정보가 고려되지 않기 때문이다. 따라서 Input vector와 같은 크기를 가지는 별도의 encoding 정보를 더해주어야 한다.
밑에서 postional encoding 에 대해 더 자세하게 다뤄보자.
self-attention 연산
먼저 임베딩된 벡터들에 weight 값을 곱해주어 Q,K,V를 구해준다. 이 때 Q 는 Query, K는 Key, V는 Value를 의미한다.
Query는 물어보는 주체를 말하고 Key 는 물어보는 대상을 말한다. 예를 들어 I am a teacher라는 문장이 있을 때 I에 대한 attention 을 구한 다면 I의 query 값이 물어보는 값이 된다. 그리고 I am a teacher 의 각각의 단어의 키가 물어보는 대상이다.
즉, query 값과 key 값을 내적해서 구하면 I와 I,am, a , teacher간의 연관성을 구하는 것이다. 여기서 내적의 의미는 두 벡터 간의 유사도를 구하는 것과 같다. 이렇게 구한 값을 Score 라고 부른다.
그리고 아래는 이러한 self-attention의 계산 수식이다.
위 수식을 보면 d_k라는 값이 나오는데 이것은 key 벡터의 차원수를 말한다. 예를 들어 위의 예시에서 key 벡터의 차원은 3이 된다. Q와 K를 전치한 행렬을 곱해준후 axis = 1 을 기준으로 softmax 를 먹여준다. 그후 Value vector를 곱해주면 Z라는 self-attention 값이 나오게 된다.
여기서 Encoder 의 역할에 대해 생각해볼 수 있다. encoder는 입력된 text들에 대해 서로 간의 context를 더 강화시켜준다. 이를 통해 encoder는 더 강화된 input을 내보내준다고 생각 할 수 있다.
Multi-head-attention
multi-head-attention은 self attention 을 여러번 수행한 것 이다. 여러 head가 독자적으로 self attention을 계산한다. 즉 같은 문서(input)를 여러명(head)이 함께 읽는 구조라고 할 수 있다.
각 임베딩 벡터에 다른 weight를 곱하여 여러개의 query, key, value 벡터를 만듭니다. 그 후 각각의 head마다 self-attention을 수행합니다.
예를 들어 8개의 head가 있다면 8개의 self-attention 이 나오게 됩니다. 그렇다면 이렇게 나온 8개의 집합들을 어떻게 다음 layer로 먹일까에 대한 고민이 들 수 있다. 왜냐하면 다음 encoder의 입력값은 여전히 Z 세트 1개의 input을 가지기 때문이다.
이 때는 위 그림처럼 먼저 8개의 결과들을 concat한다. 그 후 차원에 맞는 weight 값을 행렬곱연산 해준다. 그러면 input vector와 같은 크기의 행렬 결과 값을 얻을 수 있고 다시 다음 Encoder에 집어 넣을 수 있게 된다.
Decoder
이제 decoder 딴에서의 동작을 살펴보자
Decoder에서의 self-attention도 encoder에서의 self-attention과 똑같다. 다만 encoder에서의 결과값의 key, value vector를 사용한다. 위에서 말했듯 query는 연관성을 찾고자 하는 것이고 key는 각각의 대상을 의미하기 때문이다.
다만 Decoder에서는 masking이라는 기법을 따로 사용할 때 도 있다. 이는 optional 인데 예를 들어 input imbedding에 이어서 다음 단어를 예측해야 할 때 Ouput embedding 에는 계속해서 예측한 값이 다시 output 으로 들어가줘야한다. 이같은 구조를 Autogressive model 이라고 한다.
이러한 구조일 때 모델을 추론할 때는 계속해서 넣어줘야 하지만 training 을 할 때는 이미 정답을 알고 있는데 이를 계속 넣어주는 구조는 느릴 수 밖에 없다. 따라서 정답에 masking을 해서 학습을 시켜야 하기 때문에 이 때 masked multi head attention 을 사용한다.
하지만 이와 달리 예를 들어 input 에 지문이 들어가고 output 에 질문(query)가 들어가게 된다면 이러한 mask를 사용할 필요 없이 multi-head attention 을 사용하면 된다.
Postional Enocoding
먼저 sin, cos 함수를 이용한다. 그렇게 해서 -1 ~ 1사이의 값을 가지도록 한다. 그 다음 한개의 sin, cos 함수만 사용하는 것이 아니라 여러개의 함수를 사용한다.
이렇게 sin, cos 여러개를 사용하기 때문에 관계성을 파악하기 쉬워지고 또 만약 train 할 때 10개의 text로 traing 하고 추론할 때 20의 길이의 text가 들어온다해도 대응이 가능해진다는 장점이 있다.
이러한 sin, cos 함수를 직접 지정해주는 방법도 있지만 이를 학습시켜 사용할 수 도 있다. 이를 Learning Positonal Encoding 이라고 한다. 하지만 이같은 경우 추론할 때 대응력이 좀더 떨어질 수 있다는 단점이 있다. 상황에 따라 어떤것을 골라야할지 선택해야 한다.
참고한 사이트
Self Attention
pratical tips for Natural Language Processing
ratsgo.github.io
https://www.youtube.com/watch?v=mxGCEWOxfe8
'AI > Deep Learning' 카테고리의 다른 글
Generative Model (Autoregressive model) (0) | 2023.03.24 |
---|---|
Optimizer (0) | 2023.03.24 |
RNN(Recurrent Neural Networks) (0) | 2023.03.22 |
Neural Network & MLP(Multi Layer Perceptron) (0) | 2023.03.20 |
0. Deep Learning 개요 (0) | 2023.03.20 |