구글이 번역기에 적용한 것으로 유명한 인공신경망 트랜스포머(transformer)모델에서 핵심적인 개념은 어텐션(Attention) 이다. 말 그대로 주목이라는 의미를 가지는 이 기법은 입력데이터의 특정 부분에 집중하여 해당 부분이 더 중요하게 반영되도록 하는 방법을 통칭한다.
해당 포스팅은 번역을 어떻게 어텐션 + LTSM 을 통해서 수행하는가를 예제로, 어텐션의 정의에 대해 살펴본다.
1. Seq2Seq
사이토 고키 저자의 밑바닥부터 시작하는 딥러닝 2 도서에서는 seq2seq 모델을 개선하기 위해서 어텐션을 사용한다. 따라서 어텐션에 대해 설명하기 전에 이 seq2seq 에 대해서 간략하게 설명하고 진행하겠다. seq2seq은 번역작업에 많이 사용되었던 모델로서, RNN을 기반으로 한다. seq2seq는 인코더, 디코더라는 두개의 모듈로 작동한다.
위의 예시에서는 간단한 한국어 문장을 영어로 번역하였다. 여기서 인코더와 디코더가 어떻게 동작하는지 파악한다면 쉽게 seq2seq를 이해할 수 있다.
먼저 인코더를 설명하겠다.
그림처럼 인코더는 Embedding & LSTM을 이용하여 문자열 데이터를 벡터($h$)로 변환한다. 그런데 이 벡터는 모든 단어를 '거쳐온' 벡터이다. 다시말해, '나는 고양이 로소 이다' 를 하나의 고정된 길이의 벡터로 치환한다는 의미이다. 여기서 Hash 충돌과 유사한 문제가 발생하게 되는데 '벡터화된 정보가 지나치게 추상화' 되는 문제가 있다. 한번 코드를 살펴보자.
class Encoder:
def __init__(self, vocab_size, wordvec_size, hidden_size):
# 생략
...
...
...
def forward(self, xs):
xs = self.embed.forward(xs)
hs = self.lstm.forward(xs)
self.hs = hs
return hs[:, -1, :]
# dh - LSTM 계층의 마지막 상태에 대한 기울기
def backward(self, dh):
# 생략
...
...
...
위 코드는 인코더의 forward 부분만을 보여주고 있다. [그림 7-6]과 비교해 보면 이해가 쉽다. xs 변수에 Embedding 계층을 지난 벡터를 삽입하고, xs 변수가 LSTM 계층을 지나게 함으로서 $hs$(뒤에서 더 설명)를 추출하고 있다. return 문에서는 각 시퀀스의 마지막 숨겨진 상태만을 반환하고 있다. 정직하게 그림과 일치하는 코드이다.
추가로 Decoder 에 대해서도 아래 이미지를 보며 대략적인 원리를 파악해 보면 좋다. (이 포스팅에서 굳이 고전적인 Decoder 에 대해 자세히 다루지는 않겠다.)
왼쪽이 인코더, 오른쪽이 디코더 형태이다. 즉, 인코더에서 고정 길이 벡터 $h$를 추출한 뒤, 디코더에선 $h$ 를 입력받아 번역을 수행한다. 여기서 전달되는 $h$ 의 는 '문장 전체를 추상화한 벡터' 라는 점만 체크하고 넘어가자.
2. Attention
seq2seq 의 문제점은 '고정 길이 벡터' 이다. 정확히는 '문장 전체를 → 고정 길이 벡터' 로 변환하는 과도한 추상화가 문제이다.
고정된 길이의 벡터로 변환하는 경우 열 단어로 이루어진 간단한 문장부터, 수만 단어로 이루어진 장문의 소설까지 모두 고정길이 벡터로 치환할 수 밖에 없는것이다. 결론적으로 위에서 언급한 '인코더' 에서 근본적인 문제가 발생하는 것이다.
1) Encoder 개선
연구자들은 이 문제를 해결하기 위해 인코더를 개선했다.
개선 전의 인코더는 Embedding 단위로 더해진 고정 길이 벡터중 마지막 벡터 $h$ 만 전달했다면, 개선 후의 인코더는 전체를 얻을 수 있다.
벡터 이름 | 문자열 | 개선전 전송 | 개선후 전송 |
Vector 1 | "나" | X | O |
Vector 2 | "나 는" | X | O |
Vector 3 | "나 는 고양이" | X | O |
Vector 4 | "나 는 고양이 로소" | X | O |
Vector 5 | "나 는 고양이 로소 이다" | O | O |
근본적으로 문제가 되는 인코더를 개선했지만 단순히 인코더만 개선한다고 해서 어텐션을 구현할 수 있는것은 아니다. 어텐션의 핵심은 '디코더' 에서 나온다. 우리는 개선된 인코더를 통해 각 단어별로 고정 길이 벡터를 만들었고 이제는 디코더에서 이 벡터들을 어떻게 해석시키는지가 중요하다.
2) Decoder 개선
디코더가 어떻게 개선되는지 파악하기 위해 개선 전 디코더의 모습을 먼저 살펴보자.
개선전 인코더에서는 은닉 상태 벡터 $hs$중 마지막 벡터(벡터화된 "나는 고양이 로소 이다") 인 $h$만 출력한다. 디코더에서는 $h$를 받아서 처리한다.
위에서 살펴본 인코더 코드의 forward() 와 [그림 8-5] 모두 '마지막' 벡터만 디코더 측으로 반환하는것을 확인할 수 있다.
다음은 개선후 디코더의 모습이다.
개선후 디코더는 LSTM 계층에 전파한 마지막 벡터에 더하여, 전체 벡터 $hs$를 '어떤 계산(Attention)' 으로 입력받는다. 즉, 이 '어떤 계산' 에서 입력된 단어와 대응 관계에 해당하는 단어의 벡터를 골라내겠다는 의미이다. 만약 '고양이' 라는 단어가 입력된다면 'cat' 에 대응하는 벡터를 선택하면 되며, 그역할을 '어떤 계산(Attention)' 에서 수행할 수 있다!
'어떤 계산' 에서는 단어의 중요도(기여도)를 나타내는 '가중치' 를 별도로 계산하도록 한다.
위 그림과 같이 각 단어의 문장내 중요도를 분별하기 위해 가중치($a$)를 구한다. 그런데 가중치를 어떻게 구할 수 있을까? (특정 문장에서 어떤 단어가 얼마나 중요한지 어떻게 파악할 수 있을까?)
[그림 8-7]의 처리순서대로 그린 그래프이다. $hs$와 $a$를 행렬곱하기 위하여 $ar$ 이라는 형태로 변환한다.
어텐션을 이해하는데에는 크게 중요하지 않다고 판단해 설명하지 않겠다.
디코더에서는 인코더로부터 전달받은 문장 전체 벡터(문장 전체 벡터이자, 마지막 벡터이다)를 $hs$ 라고 칭했다. 즉, $h$와 $hs$ 가 얼마나 '비슷한가' 를 파악하려면 '벡터의 내적' 을 통해서 알 수 있다. 어째서 벡터의 내적을 통해 유사도를 판별할 수 있는지는 나도 모른다. 이 원리에 대한 내용은 다른곳에서 확인할 수 있으니 검색으로 확인하기 바란다.
벡터의 내적 공식은 어렵지 않다.
$$ a \cdot b = a_{1}b_{1} + a_{2}b_{2} + \cdot\cdot\cdot + a_{n}b_{n} $$
단순히 개개별 원소를 곱한뒤 더해주면 되는 방식이다.
내적을 행하면 위와 같이 유사도가 도출되고, 해당 유사도를 Softmax 함수를 적용시켜 정규화 한다.
이렇게 Softmax 함수를 거쳐 나온 최종 값이 '문장에서 특정 단어가 차지하는 중요도' 라고 볼 수 있다.
3) 최종적으로 과정을 정리해 보자.
가중치 $a$(어떤 단어가 얼마나 중요한지)를 구하기 위해서 수행한 과정 = Attention Weight
최종적인 맥락 벡터 $c$ 로 출력하기 위해 $a$와 $hs$간 가중합을 구하는 과정 = Weight Sum
결국 Attention Weight 에서 먼저 $hs$(각 단어로 이뤄진 벡터) 와 $h$(문장 전체 벡터) 를 곱하고 가중합해 연산하여 도출된 $a$(Softmax 함수를 통화 정규화된 각 단어별 유사도) 와 $hs$(각 단어로 이뤄진 벡터) 를 곱하고 가중합해 최종적인 단일 맥락벡터를 추출하는 것이다.
최종적으로 어텐션 계층을 갖춘 디코더가 완성되었다! 어텐션을 적용한 seq2seq는 단어별 유사도를 보다 정확히 짚을 수 있고, 해당 원리를 통해 번역을 수행할 수 있는것이다!
3. 결론적으로 어텐션이 뭔데?
처음 언급했던 말이 기억 나는가?
주목이라는 의미를 가지는 이 기법은 입력데이터의 특정 부분에 집중하여
해당 부분이 더 중요하게 반영되도록 하는 방법을 통칭한다.
어텐션이란 바로 이러한 목적을 달성하기 위한 '방법' 을 의미한다. 즉, 위에서는 '벡터의 내적' 을 통해 어텐션을 구현했지만 굳이 이 방법만을 '어텐션' 이라고 생각하지 않아도 된다. 어디까지나 '어텐션' 이란 위와같은 '방법' 전체를 통칭하는 것이기 때문에... 실제로 유클리드 거리 방식이나, 멘하탄 거리 방식을 적용한 논문도 있다.(다만 일반적으로 각도와 크기를 모두 반영하는 벡터의 내적을 사용한다) 때문에 어떤 학자가 새로이 입력데이터를 선별하는 방법을 찾아 '개구리 어텐션'이라고 이름붙여도 전혀 이상하지 않은것이다.(좀 이상한가..?) 더하여 위 예제에서는 어텐션을 LSTM(RNN) 과 연계하여 사용하였지만 어텐션과 LSTM(RNN) 은 별개이다! 실제로 트랜스포머 모델에서는 RNN 대신 Self 어텐션만을 사용한다!
추가적으로 이것저것 주절주절 작성하고 싶지만. 해당 포스팅의 목적은 '어텐션' 이 무엇인가에 대해 설명하는 글이므로 더 궁금한 정보가 있다면 밑바닥부터 시작하는 딥러닝 2 도서를 참고하길 바란다. 내가 기재한 정보 외에도 유용한 설명이 많이 있다. 유명한 도서인 만큼 대부분 도서관에 책이 비치되어 있다. 한 번쯤 도서관에 들러 읽어보는 것을 추천한다.
'Artificial Intelligence > Basic' 카테고리의 다른 글
벨만 방정식(Bellman Equation) (0) | 2023.05.29 |
---|---|
마르코프 결정 프로세스(Markov Decision Process) (0) | 2023.05.28 |
점별 상호정보량(PMI, Pointwise Mutual Information) (0) | 2023.04.04 |
연쇄법칙(Chain Rule) (0) | 2023.03.31 |
배치정규화 (0) | 2023.03.19 |