brunch

You can make anything
by writing

C.S.Lewis

by Jean Feb 09. 2023

[NLP 논문 리뷰]1 Seq2Seq

Seq2Seq Learning with NN







    2014년 NIPS에 발표된 "Sequence to Sequence Learning with Neural Networks"는 가히 기계 번역의 패러다임을 바꾸었다.



(논문) Sequence to Sequence Learning with Neural Networks



    Seq2Seq의 가장 큰 특징은 source language의 문장 즉, sequence를 통째로 모델에 집어넣은 후 target language의 sequence를 통째로 뱉어낸다는 점이다. 이전 기계번역에서 주로 사용되던 RNN, LSTM은 source language sentence의 토큰 하나하나를 입력값으로 보고, 입력된 벡터의 개수와 동일한 개수의 출력값을 뱉어낸다. Source language가 한국어고 target language가 영어인 기계번역 모델에서 "나는 너를 사랑해"를 입력하면 해당 문장과 동일한 개수의 토큰을 가진 "I love you"라는 문장이 출력되는 것이다. 그러나 때에 따라 source language를 target language로 번역할 때 문장을 구성하는 단어의 개수가 달라야 할 수 있다. 예를 들어 "나는 너를 정말 사랑해"를 영어로 번역하면 "I love you so much"가 나와야 하지만 source language의 문장의 단어 개수에 맞춰 "I love you very" 등 어색한 문장을 출력할 수도 있는 것이다.


    하지만 Seq2Seq에서는 개별 토큰이 아니라 문장 전체를 하나의 단위로 보기 때문에 source language sentence와 target language sentence의 토큰 개수가 달라도 된다는 장점이 있다.


(출처) https://github.com/ndb796/Deep-Learning-Paper-Review-and-Practice


    

    위 그림처럼 Seq2Seq는 기본적으로 인코더(Encoder)와 디코더(Decoder)로 구성된다. 인코더에서는 입력 시퀀스를 하나의 context vector로 표현하고, 디코더에서는 context vector를 기반으로 시퀀스를 출력한다.


(출처) https://github.com/ndb796/Deep-Learning-Paper-Review-and-Practice



    고정된 크기의 context vector를 사용하는 Seq2Seq 발표 이후, 기계 번역 모델들은 개별 토큰이 아니라 입력 시퀀스 전체에서 정보를 추출하는 방향으로 발전하고 있다. 




(출처) https://gotensor.com/2019/02/28/recurrent-neural-networks-remembering-whats-important/


    위 이미지는 기존 RNN의 아키텍쳐이다. x는 source language의 토큰들(input), h는 hidden state, y는 target language의 토큰들(output)이라고 생각하면 된다. RNN에서는 입출력의 크기가 동일해야 한다는 것을 알 수 있다.


(출처) https://github.com/ndb796/Deep-Learning-Paper-Review-and-Practice


        Seq2Seq의 구조를 자세히 보자. 위 예시에서 입력 시퀀스는 총 4개의 토큰으로 이루어진다. <sos>는 "start of sequence"를, <eos>는 "end of sequence"를 의미한다. 첫 번째 입력 토큰 <sos>를 임베딩 층(embedding layer)에 통과시킨 입력값을 초기 은닉값 h0과 함께 인코더에 통과시킨다. 그러면 h1이 출력되는데, 이를 시퀀스의 두 번째 토큰인 "guten"의 임베딩 값과 함께 다음 인코더에 통과시킨다. 동일한 방식으로 h2가 출력되고, 앞의 과정을 반복한다. 이때 마지막 인코더가 출력하는 h4이 바로 context vector(v)가 되는 것이다. 


    이제 디코더를 보자. 인코더에서 구해진 context vector는 시퀀스의 시작을 알리는 <sos>와 함께 디코더를 통과하여 s1을 출력한다. s1이 linear function을 거쳐 "good"을 나타내는 벡터로 출력된다. 이 출력값 y1은 s1과 함께 다음 디코더의 입력값으로 사용된다. 두 번째 디코더를 거쳐 s2가 출력되고, 다시 y2가 출력된다. y2는 s2와 함께 세 번째 디코더를 통과한다. <eos>가 출력될 때까지 같은 과정을 거치면 된다.


    본 논문에서 사용된 인코더와 디코더는 모두 RNN이 아니라 LSTM이다. 인코더와 디코더는 서로 다른 패러미터를 갖는다. 성능 향상을 위해 두 개의 서로 다른 LSTM을 사용했다고 생각하면 된다. 또한 깊은 신경망이 얕은 신경망보다 성능이 월등하기 때문에 본 논문에서는 총 4개 층의 LSTM이 사용되었다.


    Seq2Seq의 또다른 특징은 모델을 학습시키고 테스트할 때 source language의 토큰 순서를 뒤집으면 성능이 향상된다는 것이다. 실제로 LSTM의 perplexity는 5.8에서 4.7로 감소하고, BLEU score는 25.9에서 30.6으로 향상됐다. 본 논문의 source language인 프랑스어와 target language인 영어는 어순이 비슷한데, 문장의 첫 단어가 context vector에 주는 영향이 줄어드는 long term dependency 문제가 입력 시퀀스의 순서를 뒤집음으로써 어느 정도 해결되기 때문이라고 짐작된다.







브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari