본문 바로가기
AI/딥러닝 기초(Deep learning)

[NLP] Transformer(트랜스포머)_1) Warm up

by Hyen4110 2021. 5. 17.

이 글은 아래 유튜브 영상 2개과 사이트 페이지의 내용을 정리한 글입니다.

저는 특정 딥러닝 모델이 등장한 배경, 당시 제기된 필요성에 대해서 알아가면서 배우는것을 좋아하는데요.

그런 블로그와 유튜브를 찾다 발견한 유튜브가 있어서

기존에 포스팅한 내용을 제외하고 흐름을 따라가는것을 우선으로하여 정리해보았습니다! :)

 

https://www.youtube.com/watch?v=TQQlZhbC5ps 

https://www.youtube.com/watch?v=S27pHKBEp30 

1. Transformer의 등장 배경

1.1 Bag of words

'[시퀀스 모델링의 문제점] 제한된 크기의 벡터로 만들어야함 -> [해결] Bag of Words'

- NLP 분야의 task중 하나인 '문서로 스팸 여부 예측'하는 예시를 들어보겠습니다. 이때 발생하는 문제는 길이가 다양한 문서를 하나의 정해진 크기의 벡터로 표현하는 인코딩 작업을 한다는 것입니다. 이를 해결하기 위해 고전적으로 사용한 방법은 'Bag of words' 였습니다.

 

*Bag of Words

- 단어 집합(vocabuilary)에서 한 단어 당 한 차원을 갖는 방법

- 일반적으로 영어는 10만 개의 단어가 있으므로, 벡터의 차원은 10만.

- 대부분의 값은 0인데, 그 이유는 대부분의 단어가 문서에 존재하지 않기 때문(그 외의 값은 빈도수나 tf-idf로 이루어짐)

 

- Bag of words로 구한 벡터는 대부분의 값이 0인 sparse data이기 때문에 효율적이지 않아서 전체를 저장하지 않고, position과 value값을 가진 튜플의 리스트로 저장합니다. 

- 하지만, 문제가 되는것이 하나있는데, 그것은 순서를 반영하지 못한다는 것입니다. 

 

- 예를 들면, "work to live"와 "live to work"가 있는데 두 문장의 뜻은 완전히 다르지만, 구성하는 단어는 똑같기 때문에 같은 벡터로 표현됩니다. 

- 이러한 문제에 대한 해결 방법으로 제시된 것은 'N-gram' 입니다. 하지만... 영어의 tri-gram의 dimension을 계산할라치면.. 10^15 차원이 됩니다. 어마어마한 숫자이죠(한글 숫자로 치면 1경이네요) 그리하여 나온 해결책은 바로 RNN입니다.

 

1.2 RNN(Recurrent Neural Network)

- RNN은 기존에 f(x1, x2 .... xn)을 계산하던 문제를 재귀적으로 출력값을 참조하는 루프를 만들어서 아래와 같이 간단한 식으로 대체하였습니다. 

- RNN에 대한 자세한 설명은 블로그 글을 참고하세요! > 2021.05.07 - [자연어처리(NLP)] - [딥러닝][NLP] RNN(Recurrent Neural Network)

 

 

- 하지만 RNN의 큰 한계점은 Vanishing gradient 문제가 발생한다는 것입니다. 시퀀스의 길이가 길어지면 길어질수록, 아래와 같이 A 값은 길이만큼 곱해지게 됩니다.

- 같은 수를 많이 곱해봤자 얼마나 되겠냐구요? 아래 슬라이드를 한번 보시죠.

 

- 숫자로 보니까 너무 확 와닿습니다. 0.9를 100번만 곱했을 뿐인데 0.00026이되고, 1.1을 100번만 곱했는데도 13780이 넘습니다.

 

- 이 문제는 누가 해결을 해줄까요? 바로 LSTM(Long-Short Term Memory)입니다!

 

 

 

1.2 LSTM: Awesome, but not good enough

- LSTM 모델에 대한 자세한 설명은 아래 글을 참고하시면 되겠습니다.

2021.05.07 - [자연어처리(NLP)] - [딥러닝][NLP] LSTM(Long Short Term Memory Networks)

- LSTM의 구조는 단순히 재귀적인 구조가 아니라, 2개의 hidden state를 조절하는 gate가 존재함으로써, Vanishing Exploding gradient 문제를 해결할 수 있게 되었습니다. 

 

"LSTM의 한계점"

- 하지만 LSTM도 역시나 한계점이 존재합니다. 첫째는 학습하기가 매우 어렵고 느리다는 것입니다. RNN도 학습에 오래걸렸는데 LSTM은 사실 더 오래 걸립니다.

둘째는, gradient path가 길다는것인데, 100 단어가있는 한 문장에서 LSTM은 100 레이어 네트워크와 같은 수의 gradient를 같습니다.

셋째는 transfer learning이 전혀 적용되지 않는다는 것입니다. 예를들어 CNN에서 수백만개의 이미지를 학습했다면, 새로운 문제에 파인 튜닝을 하여 사용할 수 있습니다. 하지만 LSTM에서는 모든 task마다 새롭게 레이블링된 데이터 셋이 필요합니다. 매우 비용이 드는 일이죠. (*transfer learning: 기존의 만들어진 모델을 사용하여 새로운 모델을 만들시 학습을 빠르게 하며, 예측을 더 높이는 방법).

넷째로, LSTM을 포함한 RNN 계열의 모델 모두 이전 time step의 state를 가지고 현재 time step의 state를 계산합니다. 데이터가 순서대로 즉, 이전을 계산할 수 있어야 다음을 계산할 수 있습니다. 하지만 이는 병렬 연산 처리를 하는 GPU에서는 잘 맞지 않습니다. 

 

  그렇다면, 어떻게 시퀀스 데이터를 병렬화할 수 있을까요? Transformer로 가능합니다. 

 

1.3 Transformer: How & Why?

1. Transformer의 특징_Encoder

 

1) 입력 시퀀스가 병렬적으로 Encoder를 통과

: RNN에서는 한 번에 하나의 토큰씩 시퀀셜하게 embedding vector를 만들었지만, Transformer에서는 동시에 모든 단어의 embeddin vector가 생성됩니다. 

 

2) [Positional Encoder] 문장 내 단어의 위치를 임베딩 벡터에 반영

: Transformer는 RNN 계열 모델이 아니기 때문에 순서에 대한 정보를 갖고 있지 않습니다. 하지만 'Positional Encoder' 를 통해서 이러한 위치 정보를 추가하고 있습니다. 즉, 같은 단어에 같은 벡터를 부여하지 않고, 문장 내에서 단어의 위치를 근거해서 context를 부여하는 벡터를 생성하는것이 'Positional Encoder'의 역할입니다.

: 아래 두개의 문장에서 같은 단어 'dog'가 등장하였지만 위치가 다르고 따라서 의미도 달라집니다. 이렇게 위치에 의미를 부여하는것이 Positional Encoder의 역할입니다. 

 

: 따라서 단어의 임베딩 벡터에 Positional Encodieng을 통해 추출한 위치를 기반으로한 의미를 가진 벡터를 더하여 단어의 최조 임베딩 벡터(문맥의 정보가 포함된)를 생성합니다. 

 

3) [Multi-Head Attention] attention의 사용 

: attention은 요약하자면, 문장의 어떤 부분에 초점을 두어야하는가에 대한 개념입니다. 

: transformer의 encoder에 쓰이는 attention은 self-attention으로 각 단어가 서로에 대해서 연관성을 얼마나 가지고 있는 지를 구하기 위여 사용됩니다. 문맥에 대해서 더 잘 학습하기 위해서 쓰입니다. 

 

4) [Feed Forwad]

: Feed Forward 파트가 하는 일은 모든 단어의 attention vector가 다음 Encoder와 Decoder block에서 처리되기 쉽도록 하도록 학습한다.

 

2. Transformer의 장점

1. 병렬 처리가 가능하다

 - 계산 복잡도가 N^2이지만, 병렬처리 방식 하에서는 매우 빠르게 처리할 수 있다.

 -  RNN 계열의 모델은 이전 time step을 계산하기 전까지 다음 step을 계산할 수 없다. 

 

2. sigmoid나 tanh와 같은 활성화함수를 쓰지 않아도 된다. 

 - sigmoid나 tanh에서는 극단에 staurated되는 구간이 존재한다(3~10까지 값이 거의 출력값이 동일)

*RELU가 좋은 이유

 - Hinton: allows neuron to express a strong opinion

 - random initialization에 덜 민감

 - 낮은 precision 하드웨어에서 잘 작동

 - 계산이 아주 쉽다(기울기가 0 또는 1 중 하나)

 

*RELU의 단점

 - 음수에서는 항상 0의 값을 출력 -> leaky ReLU로 보완

 - 원점에서 불연속적이다 -> GELU로 보완(BERT에서 사용)

댓글