시작하기에 앞서 논문의 리뷰는 아래 두 링크를 많이 참조 했음을 밝힙니다.
https://wikidocs.net/24996
https://youtu.be/4DzKM0vgG1Y
2014년에 발표되어 딥러닝을 활용한 기계번역에 큰 역할을 했다.
이전에도 다양한 시도가 있었지만 seq2seq가 나오면서 딥러닝이 기계번역에 폭발적으로 활용이 되었다. 후대에 나온 알고리즘에 큰 영향을 미쳤다.
sequence는 하나의 문장을 의미하며 이것은 여러개의 단어(토큰)로 구성되어 있다.
Seq2Seq는 두개의 RNN인 encoder와 decoder를 합친 알고리즘이다.
한국 말을 영어로 바꾸는 등의 번역, 질문과 대답으로 구성된 챗봇 등 입력된 시퀀스로부터 다른 도메인의 시퀀스를 출력하는 분야에서 사용될 수 있다.
이미지 출처 : https://wikidocs.net/24996
seq2seq의 특징은 encoder를 거친 문장의 정보를 하나의 고정된 크기의 벡터에 담는다는 것이다. 따라서 만약 이 벡터가 입력 문장에 대한 정보를 제대로 담지 못한다면 번역에 문제를 발생할 수 있다. 이 한계를 극복하기 위해 이후의 알고리즘들은 입력 시퀀스 전체를 활용하는 방식을 채택하게 되었다.
언어모델이란 문장에 확률을 부여하는 모델을 의미한다.
언어모델은 통계를 이용하거나, 인공 신경망을 통해서 만들 수 있다.
언어를 문법을 통해서 접근하는 것과 유사하다.
일반적으로 사람이 사용하는 언어는 체화에 가깝지만 그 언어의 구조를 체계적으로 분해 한다면 기계에 언어를 이해시킬 수 있기 때문이다.
조건부 확률의 연쇄법칙chain rule을 통한 문장의 확률은
https://wikidocs.net/21687 참고
기계가 학습한 코퍼스 데이터에서 count가 된 횟수를 바탕으로 확률을 계산한다.
길어지는 문장(희소한 문장)에 대해서는 확률이 0이 된다는 한계를 가진다.(희소 문제)
n개의 연속적인 단어를 정해줌으로써 문장이 지나치게 길어져서 코퍼스 데이터에서 찾기가 힘들어지는 문제를 해결한다. 인접한 일부 단어만을 고려한다. 하지만 이 역시도 여전히 희소의 문제가 존재하며, n의 선택은 결국 카운트 횟수를 늘리는 것(문장이 짧아질수록)과 정확도를 높이는 것(문장이 길어질 수록) 사이의 trade-off일 뿐이며 근본적인 문제 해결을 위한 해결책이 되지 못한다는 한계를 가진다.
timestep이라는 개념을 적용한 알고리즘이다. rnn의 경우 고정된 개수의 인풋을 가질 필요가 없기 때문에 코퍼스 데이터에 문장의 개수를 맞춰야하는 이전 알고리즘들의 문제로부터 자유로울 수 있다.
입력층 -> 임베딩층(linear) -> 은닉층(sigmoid) -> 출력층(softmax)를 거친다.
각 층에서의 파라미터들은 재사용된다.
이미지 출처 : https://wikidocs.net/24996
입력과 출력의 크기가 같다고 가정한다.
언어별로 어순이 다르기 때문에 매 입력마다 출력을 해준다면 적절한 결과값을 얻기가 힘들다.
인코더가 문맥에 대한 정보를 가진 (고정된 크기의)벡터를 만들어주고
디코더가 이 벡터로부터 번역의 결과를 추론한다.
LSTM을 이용하면 문맥 벡터를 만드는데 좀더 좋은 결과를 낼 수 있다.
이미지 출처 : https://wikidocs.net/24996
context vector는 인코더 rnn 셀의 마지막 시점의 은닉 상태이며 디코더 rnn 셀의 첫번째 은닉 상태에서 사용된다.
인코더와 디코더에서 입력값을 각각의 언어에 맞는 차원의 벡터로 바꾸어준다.
이전 시점의 은닉상태와 현재 시점의 입력 벡터를 조합하여 현재 시점의 은닉상태를 출력한다.
인코더에서는 이 은닉상태를 출력하지 않고 다음의 시점에 넘겨주는데 이용하며
디코더에서는 은닉상태가 여기에 더해서 fc층과 softmax함수를 거쳐서 (번역되어)출력이 된다.
seq2seq 모델은 크게 두 가지 문제를 가진다.
1.하나의 고정된 크기의 벡터에 모든 정보를 압축하려고 하면 정보 손실이 발생한다.
2.RNN의 고질적인 문제인 vanishing gradient문제가 나타난다.
이에 따라 입력 문장이 길어지면 번역 품질이 떨어지는 문제가 나타난다.
어텐션은 디코더에서 출력 단어를 예측하는 매 시점(time step)마다, 인코더의 전체 입력 문장을 다시 한번 참고한다. 이때 전체 입력을 동일 비율로 참고하는 것이 아니라, 해당 시점에서 예측해야할 단어와 연관이 있는 단어 부분을 좀더 집중해서 보게 된다.
Query : t 시점의 디코더 셀에서의 은닉 상태
Keys : 모든 시점의 인코더 셀의 은닉 상태들
Values : 모든 시점의 인코더 셀의 은닉 상태들
특이한 점은 인코더의 모든 입력 단어들을 참고할때 softmax를 사용한다는 것이다. 다시말해서 예측에서 연관이 있는 단어를 좀더 집중해서 참고한다고 볼 수 있다.
어텐션 스코어는 디코더의 현재 시점의 단어를 예측하기 위해, 인코더의 모든 은닉 상태 각각이 디코더의 현재 시점의 은닉 상태와 얼마나 유사한지를 판단하는 값이다.
어텐션 스코어는 디코더의 은닉상태st를 인코더의 은닉상태들hi에 내적을 해서 구할 수 있다.
해당 그림은 인코더와 디코더 셀의 뉴런의 개수, 은닉 상태의 차원이 같다고(4개 혹은 4차원) 가정을 했다. 따라서 어텐션 스코어는 내적이 된 스칼라 값들의 벡터가 될 것이다.
어텐션 분포는 어텐션 스코어의 각각의 값들에 소프트 맥스 함수를 적용한 확률 분포이며, 각각의 값들은 어텐션 가중치attention weight라고 한다.
따라서 디코더의 시점 t에서의 어텐션 분포를 at라고 한다면 at = softmax(attention score, et)가 된다.
어텐션의 최종 결과값을 얻기 위해서 각 인코더의 은닉 상태와 어텐션 가중치값들을 곱하고 더한다. 따라서 디코더 시점 t에서의 어텐션 값을 att라고 한다면 att = a1t x h1 + a2t x h2 + ... ant x hn이 될 것이다.
어텐션 값은 인코더의 문맥을 포함하고 있다고 볼 수 있기 때문에 컨텍스트 벡터로 볼 수 있다. seq2seq에서 인코더의 마지막 은닉 상태를 컨텍스트 벡터로 부르는 것과 비교해서 볼 수 있다.
출력 층 연산을 위한 벡터 st를 결과값으로 내는 층을 하나더 만들어 준다.
가중치 행렬과 연산후에 활성함수로 하이퍼볼릭 탄젠트함수를 사용한다.
이렇게 하면 결과가 좀더 좋은 모양이다.