반응형
Transformer 구조에 대한 복습을 진행하면서 적은 글입니다.
Go 언어로 Transformer 구현을 위해 간략히 정리해봤습니다!
(관련 링크 : https://github.com/golansformer/golansformer/issues/6)
Transformer 복습
내가 이해한 어텐션 / 인코더는?
- query, key, value가 각각 구성이 사실 같음
- I, go, home → 이런 문장을 인코딩 한다고 해보자
- 각 출력은 임베딩 벡터 h1, h2, h3로 뱉어짐
- q, k, v로 부르면, 시퀀스 당 입력 q가 하나 주어지고(단어 하나), k, v 는 전체로 고정
‘I’ 의 인코딩 벡터를 구해보자
- q는 I의 임베딩 벡터
- k는 I, go, home의 각 임베딩 벡터를 담고 있음
- q와 각 단어를 dot product하면서 유사도 구한 후, softmax
- 그러면 예시를 들면, 0.2, 0.3, 0.5 이렇게 나오겠지?
- v가 여기서 쓰임 → v도 I, go, home의 임베딩 벡터를 담고 있음
- 위의 결과값으로 weighted sum하면, 그게 ‘I’의 인코딩 벡터
- 근데? 보통 softmax 전 square root d(차원)로 나누어줌
결과에서 루트 dk로 나누어 주는 이유
- scaling → 분산을 일정하게 하기 위해
- softmax의 확률분포의 패턴(=분산)이 의도치않게 q, k에 대한 차원 때문에 영향을 받기 때문
- 확률분포 때문 → 통계 쪽 지식
멀티 헤드 어텐션
- 동일한 Q, K, V에 대해 → 동시에, 여러 버전의 어텐션을 병렬적으로 수행함
- 서로 다른 버전의 어텐션의 개수만큼, 서로 다른 인코딩 벡터가 나옴
- 이걸 모두 concat → 해당 Q의 인코딩 벡터를 얻게 됨
- 여러 버전의 어텐션 수행하기 위한 선형 변환 matrix → 각 head라 부름
왜 필요할까?
- 여러 문장 에서의 각 측면이 다르기 때문
- 서로 다른 측면의 정보를 병렬적으로 뽑고, 그 정보를 다 합치는 형태로 구현
드디어 이제 Residual connection이 나온다(내가 구현할 부분)
- Add 부분이 Residual connection, Norm이 레이어 정규화
- 컴퓨터 비전 쪽에서 깊은 레이어의 기울기 소실을 해결하기 위해 탄생
- 그냥, 기존 입력 값을 인코딩 벡터에 더해주는 것!!
- 그래서, f(x) + x 가 나온 것
- 결국, 입력값 대비 만들고자 하는 벡터에 대한 차이값 만을 어텐션 모듈에서 만들어줘야 하는 것
- → 이렇게 해서 기울기 소실 해결 + 학습 안정화
- 주의 : 입력과 출력의 차원을 동일하게 맞춰야 가능함
Norm 설명
- 평균을 0, 분산을 1로 만든 후 원하는 평균과 분산을 주입할 수 있도록 하는
- 선형 변환으로 이루어져 있음
- 평균이 0이 되도록 → 각 모든 값에서 평균 값을 빼줌
- 분산이 1이 되도록 → 각 모든 값에서 표준편차를 나눠줌
그렇게 하나의 트랜스포머 셀프 어텐션 모듈이 완성
- 이걸 거쳤을 때, 최종적으로 나오는 건?
- → 각 단어에 대응되는 인코딩 벡터
Positional Encoding → 트랜스포머의 또 다른 구성요소
- 문장의 시퀀스(순서)를 반영할 수가 없다는 한계가 있어서 등장함
- ex : I go home과 home go I 의 각 단어 인코딩 벡터가 모두 동일하게 나타남!
- → 이 순서를 특정지을 수 있는 유니크한 상수 벡터를 각 순서에 등장하는 워드 입력벡터에 더해주는 것이 Position Encoding
- 더해주는 벡터를 어떻게 결정하는지?
- 위치에 따라 구별할 수 있는 벡터를 주기함수를 사용
- → 그 함수값을 모아서 위치를 나타내는 벡터로 사용
- 인덱스(위치) 별 각 디멘젼에 더해주어야 하는 값을 지정
- → 이런 식으로 나옴
- 위치 별로 서로 다른 벡터를 더해주도록 함으로써, 순서 정보를 반영할 수 있게 됨!
인코더 커버 완
- Nx → N개의 블럭으로 쌓는다는 의미(주로 6, 12, 24)
- 왼쪽이 인코딩, 오른쪽이 디코딩!
- → 디코딩 : 입력 시퀀스를 받아서, 출력 시퀀스를 예측
그러면 디코더를 살펴보자
- 번역하는 경우를 생각해보겠음!
- 상황
- 인코더에 I, go, home이 주어지면? (임베딩 벡터 형태로)
- 디코더 입력에는 <sos>, 나는, 집에 → 시퀀스가 임베딩 벡터로 주어짐
- 그러면? → 디코더는 뭘 뱉어야 하나?
- 나는, 집에, 간다 → 이걸 최종적으로 뱉어야 함
이제 과정
- 일단, 입력 시퀀스를 인코딩 과정에 태움
- 단, 이때 Masked Multi-Head 어텐션 이용 → 일단 지나쳐~(뒤에 설명)
- 그 다음, Multi-Head 어텐션 태우는데
- 이 때 디코더의 hidden state 벡터가 쿼리로 들어감
- 그리고 인코더의 output이 key, value로 들어감
- 그러고 나온 인코딩 벡터를 Linear transformation 태워서, vocab size로 변환해줌
- 예 : 한글 워드는 10만 개
- 이후는 softmax 태워서 예측 수행
마지막 단 → 한글 단어에 대한 확률 분포는?
- ground truth 단어와의 softmax loss를 통해서, back-prop으로 전체 네트워크 학습!
찐막 → Masked Multi-Head 어텐션
- 기본 아이디어 : 디코딩 과정 중 단어 정보 접근의 가능 여부에서 기반함
- 핵심 :
- 학습 당시에는 배치 프로세싱을 위해 입력으로 동시에 주긴 하나
- <SOS>를 쿼리로 사용해서 어텐션 모듈을 수행할 때는?
- 벨류에서 ‘나는’ 과 ‘집에’ 라는 단어는 제외해 주어야 한다~
- 정보를 날리고 나서는? → row 별로 합이 1이 되도록 normalization을 한다~
- 이렇게 어텐션을 변형하는 방식 → masked-self 어텐션
반응형
'AI tech' 카테고리의 다른 글
IF (Kakao AI) 2024 - 모든 연결을 새롭게 (1일차, 컨퍼런스 참여 후기 및 요약) (13) | 2024.10.26 |
---|---|
밑바닥부터 시작하는 딥러닝2 정리 Chapter 2 - 자연어와 단어의 분산 표현 (0) | 2024.04.16 |
모델 학습 시작 또는 종료 시, Slack 알림 가게 하기 (1) | 2024.02.14 |
밑바닥부터 시작하는 딥러닝 정리 Chapter 8 - 딥러닝 (3) | 2024.02.13 |
밑바닥부터 시작하는 딥러닝 정리 Chapter 7 - 합성곱 신경망(CNN) (2) | 2024.02.07 |