새소식

딥러닝/자연어 처리

트랜스포머

  • -

트랜스포머

트랜스포머(Transformer)는 2017년 구글이 발표한 논문인 "Attention is all you need"에서 나온 모델로 기존의 seq2seq의 구조인 인코더-디코더를 따르면서도, 논문의 이름처럼 어텐션(Attention)만으로 구현한 모델이다.

이 모델은 RNN을 사용하지 않고, 인코더-디코더 구조를 설계하였음에도 번역 성능에서도 RNN보다 우수한 성능을 보인다.

 

트랜스포머 시퀀스-투-시퀀스(sequence-to-sequence) 태스크를 수행하기 위한 모델이다.

시퀀스-투-시퀀스는 특정 속성을 지닌 시퀀스를 다른 속성의 시퀀스로 변환하는 작업을 의미한다. 시퀀스-투-시퀀스 태스크의 예시로 기계번역이 있다.

(어떤 언어(source language)의 단어 시퀀스 다른 언어(target language)의 단어 시퀀스)

 

시퀀스-투-시퀀스 태스크를 수행하는 모델은 대게 인코더와 디코더로 구성되어 있다.

 

인코더: 소스 시퀀스의 정보를 압축해 디코더로 전송

디코더: 인코더가 보내준 소스 시퀀스 정보를 받아 타깃 시퀀스를 생성

 

트랜스포머 구조

트랜스포머의 인코더와 디코더 블록의 구조는 본질적으로는 크게 다르지않다.

인코더와 디코더 모두 멀티 헤드 어텐션, 피드포워드 뉴럴 네트워크, 잔차 연결 및 레이어 정규화 와 같이 3가지 구성 요소를 기본으로 한다.

 

 

Inputs → Input Embedding →  Positional Encoding

 

 

인코더 입력은 소스 시퀀스의 입력 임베딩에 위치 정보(Positional Encoding)을 더해서 만든다.

 

Positional Encoding은 마치 bias처럼 embedding 벡터에 특정 값을 더해준다.
Transformer 모델은 여러 단어들을 동시에 고려하도록 되어있지만 sequential한 정보가 포함되어 있지 않기 때문에 [a,b,c]로 이루어진 문장이나 [a,c,b]로 이루어진 문장이나 동일하게 단어 간의 attention만을 측정하기 때문에 순서에는 독립적이다.

 

그러나 실제 문장은 단어의 순서가 중요하기 때문에 positional encoding을 통해 이러한 문제를 해결한다.

 

 


 

멀티 헤드 어텐션

멀티 헤드 어텐션은 셀프 어텐션을 병렬적으로 수행한다. (=여러 헤드가 독자적으로 셀프 어텐션을 계산한다)

여기서 셀프 어텐션이란 트랜스포머의 핵심 구성요소이다. 

 

💬인코더-디코더 어텐션에서는 Query가 디코더의 벡터인 반면에 Key와 Value가 인코더의 벡터이므로 셀프 어텐션이라고 부르지 않는다.

 

∎ 셀프 어텐션은 Query, Key, Value 사이의 문맥적 관계성을 추출하는 과정이다.

1) Query, Key, Value 생성

https://wikidocs.net/31379

입력 벡터 시퀀스에 Query, Key, Value 벡터를 만들어주는 행렬 W를 각각 곱한다.

WQ, WK, WV는 태스크를 잘 수행하는 방향으로 학습과정에서 업데이트된다.Query 생성을 수식으로 표현할 경우 아래와 같다.

 

Student x W^Q = Qstudent

 

2) 셀프 어텐션 값 계산

Query와 Key를 행렬곱한 뒤 해당 행렬의 모든 요소값을 Key 차원수의 제곱근 값으로 나눠주고, 이 행렬을 행(row) 단위로 소프트맥스(softmax)를 취해 스코어 행렬을 만든 뒤 이 스코어 행렬에 Value를 행렬곱해주어 셀프 어텐션 값을 계산한다.

 

위에서 생성한 Query에 모든 Key 벡터의 전치를 행렬 곱을 진행하면 결과값 2의 경우 [1 0 2] 쿼리 벡터와 첫번째 Key 벡터 사이의 문맥적 관계성을 포함하고 있는 결과로 볼 수 있다.

그 다음 위 결과에 Key 벡터의 차원수(3)의 제곱근으로 나눈 후 softmax를 취해준다.

 

그리고 마지막으로 소프트맥스 벡터와 Value 벡터를 행렬곱해주면 해당 쿼리의 셀프 어텐션 값을 구할 수 있다.

 

멀티 헤드 어텐션은 개별 헤드의 셀프 어텐션 수행 결과를 이어붙인 행렬에 Wo를 행렬곱을 해준다.

Wo 역시 학습과정에서 태스크를 잘 수행하는 방향으로 업데이트된다.

 

∎ 인코더에서 수행하는 셀프 어텐션

Query, Key, Value가 모두 소스 시퀀스와 관련된 정보
(태스크가 한국어 → 프랑스어 번역이라면 인코더의 Query, Key, Value는 모두 한국어)

 

https://ratsgo.github.io/nlpbook/docs/language_model/transformers/

 

왼쪽 그림처럼 Query가 카페인 경우, 잘 학습된 트랜스포머일 경우 Query, Key로부터 계산한 Softmax 확률 가운데 장소를 지칭하는 대명사 '거기'가 높은 값을 갖을 것이다.

이 확률값들과 Value 벡터를 행렬곱해서 셀프 어텐션 값을 계산한다.

(자세한 계산 방식은 위에 설명한 것을 참고)

 

이렇게 어제, 카페, 갔었어, 거기, 사람, 많더라 Query에 대해서도 셀프 어텐션 값을 계산한다. 

즉, 인코더에서 수행하는 셀프 어텐션은 소스 시퀀스 내의 모든 단어 쌍 사이의 관계를 고려하게 된다.

 

∎ 디코더에서 수행하는 셀프 어텐션

디코더 입력은 1. 인코더 마지막 블록에서 나온 소스 단어 벡터 시퀀스, 2. 이전 디코더 블록의 수행 결과로 도출된 타깃 단어 벡터 시퀀스이다.

 

Masked Multi-Head Attention에서는 타깃 언어의 단어 벡터 시퀀스를 계산 대상으로 한다.

(태스크가 한국어 → 프랑스어 번역이라면 디코더의 Query, Key, Value는 모두 프랑스어)

입력 시퀀스가 타깃 시퀀스로 바뀌었을 뿐 인코더의 셀프 어텐션과 차이점은 없다.

 

Multi-Head Attention에서는 인코더와 디코더의 정보를 모두 활용한다.인코더에서 넘어온 소스 문장의 단어 벡터 시퀀스를 Key로 삼고, 디코더에서 넘어온 타깃 문장의 단어 벡터 시퀀스를 Key로 삼아 어텐션 계산을 수행한다.

 

 

 

 

쿼리 단어가 café 인 경우, Key(소스 언어)로 부터 계산한 softmax 확률 가운데 Query에 대응하는 해당 장소를 지칭하는 단어인 '카페'가 높은 값을 갖는다.

이 확률과 Value 벡터를 행렬곱해 셀프 어텐션 계산을 마친다.

 

 

 

 

 

 

 

그러나 학습 과정에서는 조금 다른 방식으로 진행된다.

디코더 블록의 첫 번째 어텐션을 Masked-Multi-Head Attention이라고 부르는 이유가 여기에 있다.

 

인코더에 어제 카페 갔었어 거기 사람 많더라, 디코더에 <s>가 입력된 상황이라면 트랜스포머 모델은 다음 프랑스어 단어 Je를 맞히도록 학습되어야 한다. 그런데 학습과정에서 모델이 이번에 맞혀야 할 정답을 알려주게 된다면 학습의 의미가 사라진다. 따라서 정답을 포함한 타깃 시퀀스의 미래 정보를 셀프 어텐션 계산에서 마스킹하게 한다. 그렇게 되면 마스킹된 단어 정보들은 계산에서 무시할 수 있다.

트랜스포머 모델은 <s> 벡터를 가지고 Je를 맞히도록 학습한다.

 

인코더에 어제 카페 갔었어 거기 사람 많더라, 디코더에 <s> Je가 입력되고 셀프 어텐션은 Je 이후의 모든 타깃 단어들을 마스킹한 상태로 수행된다. 디코더 마지막 블록의 Je 벡터에는 소스 문장 <s> Je 사이의 문맥적 관계성이 녹아 있다. 트랜스포머 모델은 Je 벡터를 가지고 Suis를 맞히도록 학습한다.

 

이렇게 진행해나가며 학습을 끝낸 모델은 다음처럼 기계번역을 수행(인퍼런스)한다.

 

1. 소스 언어 문장을 인코더에 입력해 인코더 마지막 블록의 단어 벡터 시퀀스를 추출

2. 인코더에서 넘어온 소스 언어 문장 정보와 타깃 문장 시작을 알리는 스페셜 토큰 <s>를 넣어서, 타깃 언어의 첫번째 토큰을 생성

3. 인코더 쪽에서 넘어온 소스 언어 문장 정보와 이전에 생성된 타깃 언어 토큰 시퀀스를 디코더에 넣어 만든 정보로 타깃 언어의 다음 토큰 생성

4. 생성된 문장 길이가 충분하거나 문장 끝을 알리는 스페셜 토큰 </s>가 나올때까지 앞의 단계를 반복


 

피드포워드 뉴럴 네트워크

멀티헤드 어텐션의 출력인 입력 단어들에 대응하는 벡터 시퀀스를 피드포워드 뉴럴 네트워크에 입력한다.

 

피드포워드 뉴럴 네트워크는 input layer, hidden layer, output layer 3개 계층으로 구성되어 있다.

어텐션의 결과를 취합하여 전달하는 역할을 수행한다.

https://ratsgo.github.io/nlpbook/docs/language_model/tr_technics/


잔차 연결 및 레이어 정규화

Add = Residual Connection

잔차 연결(Residual Connection)이란 어떤 입력의 output인 트랜스포머에서의 서브층인 F(x)에 자기 자신 x를 더해주는 것이다.

 

d/dx를 하게 되면 F'(x) + 1이 되어서 F'(x)이 굉장히 작은 값이 나온다 하더라도 gradient가 최소한 1만큼 흘려주게 되어 정보의 손실과 모델의 학습에 도움을 준다.

 

Norm = Layer Normalization

미니 배치의 인스턴스(x)별로 평균을 뺀 뒤 표준편차로 나누어 정규화(normalization)을 수행하는 기법이다.

레이어 정규화를 수행하면 학습이 안정되고 속도가 빨라지는 효과가 있다.

 

 


이러한 Attention의 성능이 좋은 이유는 무엇일까?

어떠한 이미지를 CNN이나 MLP에 input으로 집어넣으면 input이 fix되어 있으므로 output도 fix되어 있다.

그러나 transformer은 input이 fix되어있다하더라도 encoding하려는 단어와 그 옆에 있는 단어들에 따라서 인코딩된 값이 달라진다. → multi-layer perceptron보다 flexible하다는 것이 장점이다.(훨씬 더 많은 표현이 가능)  단순히 입력된 단어에 따라 출력이 고정되는 것이 아니라, 옆에 주어진 다른 입력들을 모두 고려하므로 output이 변화할 여지가 있기 때문이다.


그러나 n개의 단어가 주어지면 nxn크기의 attention map을 만들어야 한다.
예를들어 RNN은 100개의 sequence가 주어지면 100번 연산하면 되지만 transformer는 100개의 단어를 한번에 처리해야하고 연산량이 100^2이 되기 때문에 연산량이 많다는 것이 단점이다.

728x90

'딥러닝 > 자연어 처리' 카테고리의 다른 글

[CS244n] Transformers & Pretraining  (0) 2022.05.31
[CS244n] Self-Attention & Transformer  (0) 2022.05.29
[CS244n] Machine Translation with Seq2Seq and Attention  (0) 2022.05.27
[CS244n] LSTM  (0) 2022.05.21
[CS244n] RNN  (0) 2022.03.02
Contents