홍우진의 개발 일기장
[논문리뷰] Attention Is All You Need / Transformer 쉬운 요약 본문
서론
위 자료는 Transformer의 아키텍쳐다.
매우 복잡해 보이는데 복잡한 거 맞다.
이해하기 쉽도록 풀어주겠다.
이 글은 간단 이해를 목적으로 제작된 문서이기 때문에 "아 이런거구나~" 개념 정도로만 정리하였다.
자세한 내용을 원하신다면 다른 자료를 찾아보길...
(틀린 정보가 있다면 댓글로 알려주시면 감사하겠습니다!)
Attention Is All You Need
등장 배경
기존 Encoder – Decoder 모델은 순차적으로 계산하기 때문에 속도가 매우 느리다.
또한 긴 sequence 데이터를 처리해야 할 때
제한된 크기의 Context vector로 모든 정보를 담아내야 하기 때문에 정보의 손실이 커지고
이에 따라 성능의 병목현상이 일어난다.
그러므로 번역 결과가 엉터리가 되는 경우가 많다.
그 이유 때문에 어텐션 매커니즘을 사용한 Seq2Seq with Attention 모델이 탄생하였다.
특징은 다음과 같다.
- 고정된 크기의 Context vector를 사용하지 않음
- Encoder의 모든 상태 값을 사용함
- 단어 하나를 번역할 때 마다 Encoder 출력 값에 어텐션 매커니즘을 사용하여 효율적으로 번역을 진행.
동적으로 Encoder, Decoder를 사용하기 때문에 기존 모델보다 문장 번역 성능이 좋다.
하지만 여전히 RNN셀을 순차적으로 계산하기 때문에 느리다.
사람들은 고민에 빠졌다.
그러다 결국 세상에 나오게 된 논문이 바로 Attention Is All You Need!
딥러닝의 판도를 바꾼 논문이라고 해도 과언이 아니다.
순차적인 RNN 계산을 과감하게 삭제하고 바로 행렬 곱으로 한 번에 해결하는 방법을 제안했다.
Input Embedding
일단 제일 첫 부분인 Input Embedding부터 시작하겠다.
Input Embedding은 Input에 입력된 데이터를 컴퓨터가 이해할 수 있도록 행렬 값으로 바꾸어 주는 작업이다.
본 논문에서 각 단어들은 크기가 512인 벡터 하나로 임베딩된다.
입력 문장의 단어들을 embedding 한 후에, 각 단어에 해당하는 벡터들은 Positional Encoding으로 들어가게 된다.
Positional Encoding
앞서 등장 배경에서 "Attention Is All You Need는 순차적인 RNN 계산을 과감하게 삭제하고
바로 행렬 곱으로 한 번에 해결하는 방법을 제안했다" 라고 했었다.
하지만 RNN이 없어도 되는걸까?
우리는 RNN이 주로 쓰인 이유를 알아야 한다.
RNN은 단어의 위치와 순서 정도 즉 '어순'을 잘 활용하여 문장 번역에 큰 도움이 되었다.
자연어는 어순이 매우 중요하다.
예를 들어보면, ‘홍우진은 똥을 싼다’, ‘똥은 홍우진을 싼다’
뭔가 이상하다. 전혀 뜻이 다르고 말이 되지 않는다. 단어의 순서가 중요함을 알 수 있다.
하지만 Transformer는 병렬연산이라 단어를 한 번에 받기 때문에 순서를 알 방법이 없다.
그렇다면 Transformer는 이 문제를 어떻게 해결하였을까?
바로 Positional Encoding이다.
Positional Encoding은 Encoder와 Decoder의 입력 값 마다 상대적인 위치 정보를 더해주는 기술이다.
Embedding된 벡터에 Positional Encoding(위치정보) 벡터를 합해주면 위치와 의미를 내포하는 벡터를 생성할 수 있다.
Positional Encoding은 삼각함수로 처리할 수 있다.
사인과 코사인을 활용한 Positional Encoding을 하는 이유는
값이 항상 -1에서 1 사이의 값이 나온다는 점과, 큰 수가 들어와도 무리 없이 상대적인 Encoding 값을 줄 수 있다는 점 때문이다.
Multi-Head Attention
Multi-Head Attention에 들어가기에 앞서 우리는 먼저 Self Attention에 대하여 알아봐야한다.
자, Attention이 무엇이냐?
인공지능은 살짝 모자라서 글의 문맥 이해를 못한다.
그러므로 어텐션은 각 단어의 관계를 다 계산하여
각각 단어의 서로 연관성을 구해주는것이다.
우선 입력 시퀀스의 각 단어를 Query, Key, Value 벡터로 변환한다.
쉽게 설명하자면
- Query: 현재의 단어
- Key: 어떤 단어와 쿼리의 상관관계를 구할 때 그 단어
- Value: 실제 word representation(실제 값)
- Score: 쿼리와 키의 곱
Attention 의 수식은 다음과 같다.
로 스케일링을 한 이유는 다음과 같다.
Softmax 함수는 0근처에서 gradient가 높게 형성되는 것에 비해 오른쪽이나 왼쪽으로 이동하게 되면
기울기 값이 크게 줄어드는 문제(gradient vanishing)가 일어날 수 있다.
따라서 곱한 값을 그냥 넣어주면 값이 커져 Softmax 함수의 기울기가 작은 곳으로 가게 되는데 이것을 방지하기 위해
Softmax를 적용해주면 키와 쿼리의 연관성을 퍼센트로 확인할 수 있다.
결과적으로 나온 최종 벡터는 단순한 단어가 아닌 문장 속에서 그 단어가 지닌 의미를 내포하고 있는 벡터이다(사진 속 제일 오른쪽)
Transformer는 여러개의 Attention 레이어를 병렬로 동시에 실행한다.
이것을 Multi-Head Attention이라고 칭한다.
병렬처리의 이점
"The animal didn't cross the street because it was too tired" 이 문장에서 It이 뜻하는 게 뭘까?
위의 자료에는 두가지의 Attention이 있다.
첫번째 Attention은 animal에 집중, 두번째는 tire에 집중을 했다.
한 개의 Attention으로는 모호한 정보를 충분히 인코딩하기 어렵기 때문이다.
멀티헤드어텐션을 이용하여 다른 관점에서 정보를 수집하여 이 점을 보완할 수 있다.
아까 앞에서 위치 정보의 기억을 위하여 Positional Encoding을 더했었다.
딥러닝 중에는 역전파 때문에 Positional Encoding이 손실될 수 있다.
때문에 Residual connection으로 입력된 값을 다시 한번 더해준다.
그 후 Layer Normalization으로 학습의 효율을 증진시켜준다.
위 사진이 인코더 레이어의 모습이다.
입력벡터와 출력벡터의 차원의 크기가 같다는 것 을 알 수 있다.
이 말은 인코더 레이어를 여러 개 붙여서 연속적으로 활용이 가능하다는 뜻이다.
Transformer의 인코더는 실제로 6개를 연속적으로 붙여서 활용한다.
중요한점은 각각의 인코더 레이어는 서로의 모델 파라미터(가중치)를 공유하지 않는다는것이다. 개별적으로 학습을 진행한다.
Transformer 인코더의 최종 출력값은 6번째 인코더 레이어의 최종 출력값이 된다.
Decoder
인코더와 상당히 유사하다.
6개의 레이어를 가지고 있다.
순차적으로 출력하며 Attention 병렬처리를 활용한다.
현재까지 출력된값에서 Attention을 적용하고 또한 Encoder 출력값에서도 Attention을 적용한다.
첫번째 Attention은 Masked Multi head Attention이다.
Masked Multi head Attention
Masked??
이름에서 알 수 있듯이 지금까지 출력된 값들에만 Attention을 적용하기 위해 Masking을 진행하는 활동이다.
Decoding시에 아직까지 출력되지 않은 미래의 단어에 Attention이 적용되면 안된다.
Ex) ‘나는 사과를 먹는다’ 를 출력하려고 한다.
‘나는’ 이라는 문장을 출력할 때 ‘먹는다’ 라는 단어를 알면 ‘사과를’ 이라는 단어를 쉽게 도출해 낼 수 있기 때문이다.
Multi head Attention 레이어는 Encoder처럼 Key, Value, Query로 연산을 진행한다.
Encoder와 가장 큰 차이는
Decoder는 현재 Decoder의 입력값을 Query로 사용하고 Encoder의 최종 출력값을 Key와 Value로 사용한다.
쉽게 말하자면 Decoder의 현재 상태를 Query로 Encoder에 넣는 것이다.
Encoder 출력값에서 중요한 정보를 Key와 Value로 획득해서 Decoder의 다음 단어의 가장 적합한 단어를 출력하는 과정이다.
마지막으로 Feed Forward 레이어를 이용하여 최종값을 벡터로 출력한다.
그렇다면 이 벡터를 어떻게 출력값으로 활용할까?
최종 출력
Linear 레이어와 Softmax 레이어다.
Linear 레이어와 Softmax 레이어로 들어갈 logit을 생성한다.
Softmax 레이어는 모델이 알고 있는 모든 단어들에 대한 확률값을 출력하게 되고
가장 높은 확률을 가진 단어가 바로 다음 단어가 된다.
Label Smoothing
Label Smoothing이란?
최종 단계에서 정답이 0이나 1이 아닌 0에 가까운값, 1에 가까운값으로 출력하는 기술이다.
너무 학습데이터에 치중하게 학습하지 못하도록 도움을 준다.
특히 Label이 노이지한경우 큰 도움이 된다.
같은 입력값인데 다른 출력값이 데이터에 많은 경우
Ex) 영어로 'Eat' / 첫번째 레이블은 '먹어', 두번째 레이블은 '드세요'.
뜻이 같지만 두 Vector는 완전히 다른 값이 되고 Eat의 학습은 두 Label이 상이하므로 원활하지 않게 된다.
이럴 경우 Label Smoothing을 적용하면 One-Hot Encoding보단 조금 더 가까워진 Vector가 되고
Softmax 출력값과 Label의 차이 역시 조금은 줄어들어 효율적인 학습을 기대가 가능하다.
정리 소감
정리 어렵네요....
참고문헌
https://arxiv.org/abs/1706.03762
https://jalammar.github.io/illustrated-transformer/
https://towardsdatascience.com/illustrated-guide-to-transformer-cf6969ffa067
https://www.youtube.com/watch?v=AA621UofTUA&ab_channel=%EB%8F%99%EB%B9%88%EB%82%98
https://www.youtube.com/watch?v=mxGCEWOxfe8&t=509s&ab_channel=MinsukHeo%ED%97%88%EB%AF%BC%EC%84%9D