Transfomer

Page content

Transformer

트랜스포머는 기존 인코더 디코더를 발전시킨 딥러닝 모델
가장 큰 차이점은 rnn을 사용하지 않는다는 것
트랜스포머는 기존 rnn기반 인코더 디코더보다 학습이 빠르고 성능이 좋음
트랜스포머를 한단어로 표현하면 병렬화이다. 즉 일을 한번에 처리함
Rnn은 순차적으로 입력된 단어를 인코딩하는 반면 트랜스포머는 한번에 과정을 처리
전통적인 rnn기반 인코더 디코더일 경우 입력값을 순차적으로 계산한다.
인코더에서의 최종적인 상태값을 context vector이라고 하며 context vector를 이용하여 번역을 한다.
고정된 크기의 문맥 벡터를 사용하지 않고 대신 단어를 하나씩 번역할 때마다 동적으로 인코더 출력값에 어텐션 메커니즘을 사용하여 효율적으로 변환 이 모델을 고정된 문맥 벡터를 사용하지않고 인코더의 모든 상태를 활용한다는  특징 때문에 이전 인코더 디코더 모델보다 향상됨 어텐션 메커니즘은 기존 인코더 디코더의 성능을 상당히 강화시킴 그러나 여전히 rnn 셀을 순차적으로 계산하여 느리다는 단점이 있음
어텐션만으로도 입력 데이터에서 중요한 정보를 찾아내서 단어를 인코딩 할 수 있지 않을까란 가능성 제기
Rnn의 순차적인 계산은 트랜스포머에서 단순히 행렬곱으로 한번에 처리가 됨
트랜스포머는 한번에 연산으로 모든 중요 정보 정보는 각 단에 인코딩하게 됩니다
트랜스 포머 디코드의 연산 과정을 기존의 어탠션 기반 인코더 디코더와 사뭇 닮아 있음을 확인할 수 있다. 트랜스포머에서 가장 큰 특징은 성공적으로 RNN을 인코더 디코더에서 제거했다는 것 디코더의 번역 과정은 기존 인코더 디코더 방법과 동일하게 START 사인을 시작해서 END 사인까지 번역하게 된다. 이 과정에서 트랜스포머는 기존 인코더 디코더 컨셉을 간직하고 있다.
기존 인코더 디코더의 주요 컨셉을 간직하되 RNN을 없애서 학습 시간을 단축했고 어텐션 뿐만 아니라 더 많은 스마트한 기술들을 함께 제공하여 성능도 올렸다.
자연어 처리에서 문장을 처리할 때 실제 단어의 위치 및 순서는 중요하다.
RNN이 자연어 처리에 상당히 많이 활용된 이유도 바로 이 RNN 단어의 위치와 순서 정보를 잘활용하는데 있다.

Rnn이 없는 트랜스포머는 어떻게 단어의 위치 및 순서 정보를 활용할 수 있을까?

그 방법은 ‘Positional encoding’이다. Positional encoding이란 인코더 및 디코더 입력값마다 상대적인 위치 정보를 더해주는 기술이다. 예를 들어 벡터를 작은 연속된 상자로 나타내었을 때
간단한 bit를 사용한 positional encoding방식의 예를 들면 첫번째 단어에 001를 더해주고 두번째 단어에는 010 세번째 단어에는 011 네번째 단어에는 100을 더해줄 수 있다.

똑같은 방식으로 디코더 입력 값에도 포지셔널 인코딩 방식을 적용할 수 있다.
트랜스포머는 비트의 포지셔널 인코딩이 아닌 사인, 코사인을 함수를 활용하는 포지셔널 인코딩 방식을 사용한다. 사인과 코사인을 사용하는 포지셔널 인코딩에는 두 가지의 장점이 있는데
첫번째는 사인 코딩 값은 -1부터 1 사이에 값이 나온다라는 것
두번째로는 모든 상대적인 포지셔널 인코딩의 장점으로서 학습데이터 중 가장 긴 문장보다 더 긴 문장이 실제 운용 중에 들어와도 포지셔널 인코딩이 에러 없이 상대적인 인코딩 값을 줄 수 있음.

각 단어의 워드 임베딩에 포지셔널 인코딩을 더해준 후에 그 다음에 해야할 것은 셀프 어텐션 연산이다. 인코더에서 이루어지는 어텐션 연산을 셀프 어텐션이라고 한다.
쿼리 키 밸류는 더블유큐 더블유케이 더블유브이 행렬에 의해 각각 생성되고 이 행렬들은 단순히 웨이트 매트릭스로 딥러닝 모델 학습과정으로 인해 최적화된다.

워드 임베딩은 벡터이고 실제 한 문장을 행렬이라고 말할 수가 있다 행렬은 행렬과 곱할 수 있으므로 각 문장에 있는 쿼리 키 밸류는 행렬곱을 통해서 한번에 구할 수 있다.
쿼리 키 밸류만 있으면 셀프 어텐션을 수행할 수가 있다. 쿼리 키 밸류는 벡터의 형태라는 것을 기억할 것
어떤 단어와의 상관관계를 구할 때 이 쿼리를 어떤 단어의 키 값에 곱해준다. 이 쿼리와 키를 곱한 값을 어텐션 스코어라고 한다.
쿼리와 키 둘다 벡터이므로 둘 닷 프로덕트로 곱할 경우에는 그 결과는 숫자로 나오게 된다. 이 숫자가 높을수록 단어의 연관성이 높고 낮을수록 연관성이 낮다라고 생각할 수 있다.
어텐션 스코어를 0부터 1까지의 확률 개념으로 바꾸기 위해서 소프트맥스를 적용한다.
소프트맥스를 적용하기 전에 스코어를 키 벡터 차원의 루트 값으로 나누어줬는데
키 벡터의 차원이 늘어날수록 닷 프로젝트 계산시 값이 증대되는 문제를 보완하기 위해서 이런 조치를 취함.
소프트맥스의 결과값은 키 값에 해당하는 단어가 현재 단어의 어느 정도 연관성이 있는지를 나타낸다. 각 퍼센테이지를 각 키에 해당하는 밸류에 곱한다.
소프트맥스 결과값과 밸류를 곱해준 결과 연관성이 별로 없는 밸류는 희미해진다.
최종적으로 어텐션이 적용되어 희미해진 밸류들을 모두 더해준다 최종 벡터는 단순한 단어가 아닌 문장속에서의 전체적인 의미를 지닌 벡터가 된다.
단어 임베딩은 벡터이므로 입력 문장 전체는 행렬로 표시가 가능하다 키 밸류 쿼리도 모두 행렬로 저장되어있으므로 모든 단어에 대한 어텐션 연산은 행렬 곱으로 한번에 연산이 가능하다.
Rnn을 사용했다면 처음부터 끝까지 순차적으로 계산 했었어야 했지만 어텐션을 통한다면 병렬처리가 가능

Multi Head Attention

사실 트랜스포머는 보다 더 많이 병렬처리를 적극 활용한다.
트랜스포머는 어텐션 레이어 8개를 병렬로 동시에 수행한다.
여러 개의 어텐션 레이어를 병렬처리함으로써 얻는 이점은 무엇일까?
병렬처리된 어텐션 레이어를 멀티 헤드 어텐션이라고 부른다.
무엇이 it일까? 문장이 상당히 모호할 경우 it과 문장이 상당히 모호할 경우 두개의 다른 병렬화된 어텐션이 서로 다르지만 it하고 연관성이 높은 단어에 포커스 하는 모습을 볼 수 있다.
첫번째 어텐션은 애니멀이 포커스를 맞췄고 두번째는 스트리트에 어텐션 포커스를 맞췄다
사람의 문장은 모호할때가 상당히 많고 1개의 어텐션 이 모호한 정보를 충분히 인코딩하기 어렵기 때문에 멀티 헤드 어텐션을 사용해서 되도록 연관된 정보를 다른 관점에서 수집해서 이점을 보완할 수 있다.
이게 바로 멀티해드 어텐션이다 바로 이모습이 인코더의 전반적인 구조입니다.
보다시피 단어를 워드 임베딩으로 전환한 다음에 포지셔널 인코딩을 적용한다.
그리고 멀티 헤드 어텐션에 입력한다. 멀티 헤드 어텐션을 통해서 출력된 여러 개의 결과 값들을 모두 이어 붙여서 또다른 행렬과 곱해져 결국 최초 워드 임베딩과 동일한 차원으로 가는 벡터로 출력하게 되어있다.
각각의 벡터는 따로따로 풀리 커넥티드 레이어로 들어가서 입력과 동일한 사이즈의 벡터가 또다시 출력이 되고 무엇보다 여기 중요한 것은 이 출력벡터의 차원의 크기가 입력 벡터와 동일하다는 것에 있다. 

딥러닝 모델을 학습하다 보면 역전파에 의해서 포지셔널 인코딩이 많이 손실될 수가 있다. 이를 보완하기 위해서 residual connection으로 입력된 값을 다시 한 번 더해주는 것도 눈 여겨봐야 할 점이다. Residual connection 뒤에는 layer normalization을 사용해서 학습의 효율을 증진시킨다.
여기까지가 바로 인코더 레이어이다. 하지만 한 가지 더 인코더 레이어 입력 벡터와 출력 벡터의 차원이 크다는 것을 기억하고 있을 것이다 이 말인 즉슨 인코더 레이어를 여러 개 붙여서 사용할 수 있다는 말이다.

트랜스포머 인코더는 실제 이 인코더 레이어를 6개 연속적으로 붙인 구조이다.
중요한 점은 각각 인코더 레이어는 서로의 모델 파라미터 즉 가중치를 공유하지 않고 따로 학습시킨다. 트랜스포머 인코더의 최종 출력 값은 6번째 인코더의 출력값이다.

디코더는 인코더와 상당히 유사하다. 인코더 같이 6개의 동일한 레이어로 구성되었다.

디코더는 기존 인코더 디코더의 작동 방식과 같이 최초 단어부터 끝 단어까지 순차적으로 단어를 출력한다.
디코드 역시 어텐션 병렬처리를 적극 활용한다.
디코드에서는 현재까지 출력된 값들에 어텐션을 적용하고 또한 인코더 최종 출력값에도 어텐션이 적용된다.
디코더를 통해 어떻게 영어를 한글로 번역하는지 그림을 통해 알아볼 수 있다.

Encoder layrer는 Multi head Attention, Feed Forward, residual, connection이 있음

Masked Multi head Attention layer -> Masked라고 붙여진 이유는 단순히 디코더 레이어에서 지금까지 출력된 값들에만 어텐션을 적용하기 위해서 붙여진 이름이다.
디코더 시에 아직 출력되지 않은 미래의 값에 어텐션을 적용하면 안되기 때문이다.
Multi head Attention -> encoder 처럼 key, value query로 연산을 하는데 encoder multi head attention 과의 차이점은 현재 decoder의 입력값을 쿼리를 사용하고 인코더의 최종 출력값을 key와 value로 사용한다는점에 있다.
쉽게 설명하면 디코더의 현재 상태를 쿼리로 인코더에 질문하고 인코더 출력값에서 중요한 정보를 키와 밸류로 획득해서 디코더의 다음 단어에 가장 적합한 단어를 출력하는 과정
인코더와 마찬가지로 feed forward layer를 통해서 최종값을 벡터로 출력하게됨.

이 벡터를 어떻게 실제 단어로 출력할 수 있을까? 실제 단어로 출력하기 위해서 디코더 최종단에는 리니어 레이어와 소프트맥스 레이어가 존재한다.
리니어 레이어는 소프트 맥스에 입력값에 들어갈 logit을 생성하고 softmax는 모델이 알고있는 모든 단어들에 대한 확률 값을 출력하게 되고 가장 높은 확률을 지닌값이 다음 값이 된다. 트랜스포머는 최종단계에 label smoothing이라는 기술을 사용해서 모델의 퍼포먼스를 향상시킨다.
보통 딥러닝 모델을 소프트맥스로 학습할 경우에는 레이블을 원핫인코딩으로 전환해주는데 트랜스포머는 1에는 가깝지만 0에는 가깝지만 0이 아닌아닌 것 표현되는 것을 볼 수 있다. Lable smoothing 정답은 1에 가까운값 오답은 0에 가까운 값,
모델의 학습시에 모델이 너무 학습데이터에 치중하여 학습하는 것을 막기위한 기술.
레이블이 노이지한 경우 즉 같은 입력값인데 다른 출력값들이 학습 데이터에  많을 경우 도움이 됨
학습이라는 것은 소프트맥스의 출력값과 벡터로 전환된 레이블의 차이를 줄이는 것인데 같은 데이터에 서로 상이한 정답들이 원핫 인코딩으로 존재한다면 모델 파라미터가 크게 커졌다가 작아지는 것을 반복함으로써 학습이 원할 하지 않음