Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Tags
more
Archives
Today
Total
관리 메뉴

Zorba blog

트랜스포머(Transformer) 모델 / 인코더, 포지션-와이즈 피드 포워드 신경망, 잔차 연결, 정규화 본문

자연어처리

트랜스포머(Transformer) 모델 / 인코더, 포지션-와이즈 피드 포워드 신경망, 잔차 연결, 정규화

Zorba blog 2022. 6. 3. 19:05

6. 인코더(Encoder)

- 트랜스포머는 num_layers 개수의 인코더 층을 쌓음.

- 인코더를 하나의 층이라고 생각한다면, 하나의 인코더 층은 총 2개의 서브층으로 나뉘어짐.

  1) 셀프 어텐션 2) 피드 포워드 신경망


7. 인코더의 셀프 어텐션

1) 셀프 어텐션의 의미와 이점

- 어텐션 함수는 주어진 '쿼리(Query)' 에 대해서 모든 '키(Key)' 와의 유사도를 각각 구함.

- 구해낸 이 유사도를 가중치로 하여 키와 맵핑되어있는 각각의 '값(Value)'에 반영.

- 그리고 유사도가 반영된 '값(Value)'을 모두 가중합하여 리턴.

- 여기까지는 이전에 학습한 어텐션의 개념. 셀프 어텐션과의 차이는? 셀프 어텐션은 어텐션을 자기 자신에게 수행.

- seq2seq에서 어텐션을 사용할 경우의 Q,K,V의 정의를 다시 보면, 그리고 t시점을 전체 시점으로 일반화하면?

- 이처럼 디코더 셀의 은닉 상태가 Q이고 인코더 셀의 은닉 상태가 K라는 점에서 Q와 K가 서로 다른 값을 가짐.

Q = Query : t 시점의 디코더 셀에서의 은닉 상태 / 모든 시점의 디코더 셀에서의 은닉 상태들
K = Keys : 모든 시점의 인코더 셀의 은닉 상태들 / 모든 시점의 인코더 셀의 은닉 상태들
V = Values : 모든 시점의 인코더 셀의 은닉 상태들 / 모든 시점의 인코더 셀의 은닉 상태들

- But. 셀프 어텐션에서는 Q, K, V가 전부 동일.

Q = 입력 문장의 모든 단어 벡터들
K = 입력 문장의 모든 단어 벡터들
V = 입력 문장의 모든 단어 벡터들

- 위 그림처럼 셀프 어텐션은 입력 문장 내의 단어들끼리 유사도를 구하므로서 그것(it)이 동물(animal)과 연관되었을 확률이 높다는 것을 찾아냄.

- 아래에서부터 셀프 어텐션의 동작 메커니즘.

2) Q, K, V 벡터 얻기

- 셀프 어텐션은 인코더의 초기 입력인 dmodel의 차원을 가지는 단어 벡터들을 사용하여 셀프 어텐션을 수행하는 것이 아니라 우선 각 벡터들로부터 Q, K, V 벡터를 얻는 작업을 거침.

- 이 Q, K, V 벡터들은 초기 입력인 dmodel의 차원을 가지는 단어 벡터들보다 더 작은 차원을 가짐.

- 논문에서는 dmodel=512의 차원을 가졌던 각 단어 벡터들을 64의 차원을 가지는 Q, K, V 벡터로 변환.

- 64라는 값은 트랜스포머의 하이퍼파라미터 num_heads로 인해 결정. dmodel/num_heads 값이 Q,K,V 벡터 차원.

  (논문에서 num_heads의 값은 8, 512/8=64)

- 기존의 단어 벡터에 가중치 행렬을 곱하여 더 작은 벡터 완성.

- 각 가중치 행렬은 dmodel x (dmodel/num_heads)의 크기를 가짐. ( 512 x (512/8) = 512 x 64 행렬 )

- 이 가중치 행렬은 훈련 과정에서 학습.

- 각 단어 벡터에 3개의 서로 다른 가중치 행렬을 곱하고 64의 크기를 가지는 Q, K, V 벡터를 얻음.

- 즉, dmodel 차원을 가졌던 한 토큰의 벡터는 각각의 가중치 행렬을 곱하여 dmodel/num_heads 차원의 벡터로으로 변환

3) 스케일드 닷-프로덕트 어텐션(Scaled dot-product Attention)

- Q, K, V 벡터를 얻었다면 기존에 배운 어텐션 메커니즘과 동일.

- 각 Q벡터는 모든 K벡터에 대해서 어텐션 스코어(Attention Score)를 구하고, 어텐션 분포를 구한 뒤에 이를 사용하여 모든 V벡터를 가중합하여 어텐션 값 또는 Context Vector를 구함.

- 기존에는 내적만을 사용하는 어텐션 함수(score(q,k)=q·k)였지만, 여기에 특정값으로 나눠준 아래의 어텐션 함수를 사용.

함수 입력

- 기존 닷-프로덕트 어텐션(dot-product attention)에서 값을 스케일링하는 것을 추가하였다고 하여 스케일드 닷-프로덕트 어텐션(Scaled dot-product Attention) 이라고 함.

- 논문에서 dk의 값은 dmodel/num_heads라는 식에 따라 64의 값을 가지므로 분모는 8의 값을 가지게 됨.

- 이제 이전처럼 소프트맥스 함수를 사용하여 어텐션 분포(Attention Distribution)을 구하고,

  각 V벡터와 가중합하여 어텐션 값(Attention Value)을 구함.

- 이는 단어 I에 대한 어텐션 값 or 컨텍스트 벡터(Context Vector)라고도 할 수 있음.

- 이 과정을 am, a, student에 대해서도 동일하게 반복해야 하는데, 행렬 연산으로 일괄 처리할 수 있음.

4) 행렬 연산으로 일괄 처리하기

- 각 단어에 대해 Q, K, V 벡터를 구하고 스케일드 닷-프로덕트 어텐션을 수행하였던 위 과정들을 행렬 연산으로 처리 가능.

- 각 단어 벡터마다 일일히 가중치 행렬을 곱하는 것이 아니라 문장 행렬에 가중치 행렬을 곱하여 Q, K, V 행렬을 구함.

- I am a student 는 4 x 512 행렬을 가지고, 가중치 행렬 W는 512 x 64, Q,K,V 행렬은 4 x 64 shape을 가짐.

  (dmodel=512, num_heads=8)

- 이를 통해 각 토큰의 Q, K, V 벡터값을 가지는 행렬을 구할 수 있음

어텐션 스코어 행렬

- 이제 Q와 K의 스케일드 닷-프로덕트를 수행하기 위해 Q행렬에 전치한 K행렬을 곱하고, 전체적으로 root(dk) 로 나눔.

- 각 행과 열은 어텐션 스코어를 가지는 행렬이 됨.

- 이제 남은 것은 어텐션 분포(Attention Distribution)을 구하고, 소프트맥스 함수를 사용한 뒤, V행렬을 곱하는 것.

- 어텐션 스코어 행렬에 행 단위로 소프트맥스 함수를 적용하고, V행렬에 곱하면 어테션 값 행렬이 결과로 나옴.

어텐션 값 행렬

- 행렬의 크기 정리. 입력 문자의 길이를 seq_len. 문장 행렬의 크기는(seq_len, dmodel)

- Q벡터와 K벡터의 차원을 dk라 하고, V벡터의 차원을 dv라고 해보자.

- Q행렬과 K행렬의 크기는 (seq_len, dk) 이며, V행렬의 크기는 (seq_len, dv).

- Wq, Wv는 (dmodel, dk)의 크기를 가지며, Wv는 (dmodel, dv)의 크기를 가짐.

  (단 논문에서는 dk, dv의 차원은 dmodel/num_heads와 같음)

- 결과적으로 어텐션 값 행렬의 크기는 (seq_len, dmodel/num_heads)이 됨.

5) 멀티 헤드 어텐션(Multi-head Attention)

- 지금까지 dmodel의 차원을 가진 단어 벡터를 num_heads로 나눈 차원을 가지는 Q,K,V 벡터로 바꾸고 어텐션을 수행.

- num_heads의 의미와 왜 dmodel의 차원을 가진 단어 벡터를 차원을 축소시킨 벡터로 어텐션을 수행하였는지 확인.

- 트랜스포머 연구진은 한 번의 어텐션 보다 여러번의 어텐션을 병렬로 수행하는 것이 더 효과적이라고 판단.

- 그래서 dmodel의 차원을 num_heads개로 나누어 dmodel/num_heads의 차원을 가지는 Q,K,V에 대해서 num_heads개의 병렬 어텐션 수행.

- 이때 가중치 행렬 Wq,Wk,Wv의 값은 8개의 어텐션 헤드마다 전부 다름.

- 어텐션을 병렬로 수행함으로써 다른 시각으로 정보들을 수집.

- 병렬 어텐션을 모두 수행하였다면 모든 어텐션 헤드를 연결(concatenate).

- 모두 연결된 어텐션 헤드 행렬의 크기는(seq_len, dmodel)가 됨. (4 x 64 *8) = (4 x 512)

- 멀티-헤드 어텐션의 최종 결과물은 concatenaed matrix 와 또 다른 가중치 행렬 W를 곱한 것.

- 이때 결과물은 인코더의 입력이었던 (seq, dmodel) 크기와 동일. (4 x 512)

- 인코더의 첫번째 서브층인 멀티-헤드 어텐션 단계를 끝마쳤을 때, 인코더의 입력으로 들어왔던 행렬의 크기가 유지.

- 두번째 서브층인 포지션 와이즈 피드 포워드 신경망을 지나도 행렬의 크기를 계속 유지.

- 인코더에서의 입력의 크기가 출력에서도 동일 크기로 계속 유지되어야만 다음 인코더에서도 다시 입력이 될 수 있음.

6) 패딩 마스크(Padding Mask)

- 스케일드 닷 프로덕트 어텐션 함수 내부를 보면 mask라는 값을 인자로 받아서,

  이 mask에다가 -1e9라는 아주 작은 음수값을 곱한 후 어텐션 스코어 행렬에 더해줌.

- 이 연산의 정체는?

def scaled_dot_product_attention(query, key, value, mask):
... 중략 ...
    logits += (mask * -1e9) # 어텐션 스코어 행렬인 logits에 mask*-1e9 값을 더해주고 있다.
... 중략 ...

- 이는 입력 문장에 <PAD> 토큰이 있을 경우 어텐션에서 사실상 제외하기 위한 연산.

- 아래는 <PAD>가 포함된 입력 문자의 셀프 어텐션의 예제.

- 단어 <PAD>의 경우 실질적인 의미를 가진 단어가 아님.

- 트랜스포먼에서는 Key의 경우에 <PAD> 토큰이 존재한다면 이에 대해서는 유사도를 구하지 않도록 마스킹 추가.

- 어텐션 스코어 행렬에서 행에 해당하는 문장은 Query이고, 열에 해당하는 문장은 Key.

- Key에 <PAD>가 있는 경우 해당 열 전체를 마스킹.

- 마스킹을 하는 방법은 행렬의 마스킹 위치에 매우 작은 음수값을 넣는 것.(-1,000,000,000과 같은 -무한대)

- 아직 어텐션 스코어 함수는 소프트맥스 함수를 지나지 않음.

- 현재 마스킹 위치에 매우 작은 음수 값이 들어가 있으므로 어텐션 스코어 행렬이 소프트맥스 함수를 지난 후에는 해당 위치의 값은 0이 되어 단어 간 유사도를 구하는 일에 <PAD> 토큰 반영 X

- 소프트맥스 함수를 지난 후의 어텐션 스코어 행렬. 단어 <PAD>의 경우에는 0이 되어 어떤 유의미한 값을 가지지 않음.


8. 포지션-와이즈 피드 포워드 신경망(Position-wise FFNN)

- 포지션-와이즈 FFNN은 인코더와 디코더에서 공통적으로 가지고 있는 서브층.

- 여기서 x는 앞서 멀티 헤드 어텐션의 결과로 나온 (seq_len, dmodel)의 크기를 가지는 행렬.

- 가중치 행렬 W1은 (dmodel, dff)의 크기를 가지고, W2는 (dff, dmodel)의 크기를 가짐.

  (논문에서 은닉층의 크기인 dff는 2,048로 설정)

- W1,b1,W2,b2는 하나의 인코더 층 내에서는 다른 문장, 다른 단어들마다 정확하게 동일하게 사용.

- 하지만 인코더 층마다는 다른 값을 가짐.

- 두 번째 층을 지난 인코더의 최종 출력은 여전히 인코더의 입력의 크기였던 (seq_len, dmodel)의 크기가 보존.

9. 잔차 연결(Residual connection) 과 층 정규화(Layer Normalization)

- 트랜스포머에는 이러한 두 개의 서브층을 가진 인코더에 추가적으로 Add & Norm 기법 사용.

- 정확히는 잔차 연결(Residual connection) 과 층 정규화(layer normalization)을 의미.

1) 잔차 연결(Residual connection)

- F(x)가 트랜스포머에서는 서브층에 해당.

- 잔차 연결은 서브층의 입력과 출력을 더하는 것을 의미.

- 트랜스포머에서 서브층의 입력과 출력은 동일한 차우너을 갖고 있으므로, 서브층의 입력과 서브층의 출력은 덧셈 연산을 할 수 있음.

2) 층 정규화(Layer Normalization)

- 잔차 연결을 거친 결과는 이어서 층 정규화 과정을 거치게 됨.

- 잔차 연결의 입력을 x, 잔차 연결과 층 정규화 두 가지 연산을 모두 수행한 후의 결과 행렬을 LN이라고 하면 수식은 아래과 같음.

- 층 정규화는 텐서의 마지막 차원에 대해서 평균, 분산을 구하고 이를 가지고 값을 정규화하여 학습을 도움.

- 여기서 텐서의 마지막 차원이란 것은 트랜스포머에서는 dmodel 차원을 의미.

- 층 정규화를 두 가지 과정으로 나누어서 설명.

- 첫 번째는 평균과 분산을 통한 정규화, 두 번째는 감마와 베타를 도입.

- 우선 평균과 분산을 통해 벡터 xi를 정규화.

- 입실론은 분모가 0이 되는 것을 방지.

- 이제 감마와 베타라는 벡터를 준비. 이들의 초기값은 각각 1과 0.

- 층 정규화의 최종 수식은 다음과 같으며 감마와 베타는 학습 가능한 파라미터.

Comments