본문 바로가기

머신러닝/[딥러닝을 이용한 자연어 처리]

Real-Time Translation Learning to Decode

학습목표

Docoding 하는 방법을 고민해보고, 동시통역에 대해 공부합니다.

핵심키워드

  • 완전탐색(Exhaustive Search, Brute-force Search)
  • Ancestral Sampling, Forward Sampling
  • 탐욕적 탐색(Greedy Search)
  • 빔 탐색(Beam Search)
  • 동시통역(Simultaneous Translation)

학습하기

 마지막 주제는, 생성문제에 대해 자세히 살펴보겠습니다. 여태까지 Representation을 뽑는 방법, 뽑아진 토큰들을 스코어링하는 방법 다 배웠는데, 중요한 것 하나를 안했죠. 스코어링된 토큰들을 어떻게 선택해서, 좋은 번역 결과를 뽑을 것이냐. 이 얘기를 가장 뒤로 미뤄왓던 이유는, 아직 명확한 베스트 원이 나오지 않았기 때문입니다. 이미 상용되고 있긴 하지만, 왜 그게 최곤지 최고가 맞는지.. 알 수 없습니다.

 기본적으로, 스코어링이 되어있을 때, 완전 탐색을 해볼 수 있죠. 모든 가능한 경우의 수를 다 탐색하면서 가장 높은 점수를 뽑으면 되는데, 당연히 실전에서는 불가능하겠죠.

 두번째 방법이 Ancestral Sampling. 말 그대로 분포를 보고 적당히 샘플링해와서 문장을 완성하는건데, 문장 공간이 크다보니, 고작 몇 번의 샘플링 가지고 좋은 문장을 만들 수 있을리가 없죠. 그렇다고 샘플링을 수없이 많이 하는 건 또 실전에서는 불가능하고, 적은 샘플링으로 결과를 출력한다면, 어제는 잘 됬던 번역이, 오늘은 개판이고. 이런 상황을 마주할 수 있습니다.

 Bias-Variance trade off 라는게 있죠. Bias, 그러니까 얼마나 정확하지 않은지에 대한 건데, 정확도를 조금 포기하면, Variance를 줄일 수 있습니다. 비슷하게 Greedy search라고 해서, 정확한 답은 주지 않지만, 분산을 최소화하는 탐색법을 사용할 수 있죠. 이게 기계번역에 어울려보이죠. 계산상으로나 메모리상으로나 굉장히 효율적이고, 분산이 낮으니까요. 그런데 실제로 해보면, 굉장히 Suboptimal합니다. 안좋은거죠. 왜냐면 미래에 뭐가 좋은지 모르는데, 첫번째 선택, 을 기반으로 두번째 선택, 을 기반으로 세번째 선택.. 으로 이어가기 때문에. 어느 순간 발목이 잡히면, 돌아와서 고치는 행위가 안되기 때문이죠.

 그래서 이걸 개선해서  Beam search를 사용합니다. 하나의 선택지만을 가져가는 Greedy search와 달리 한 번에 여러 개의 후보군을 들고 가는거에요. 각각의 후보에 대해 다음 경우를 보고, 다음을 보고, 하는 거죠. 그래서 초반에 어떤 잘못된 선택을 하더라도, 후보군 중 하나라도 실수를 안한게 있다면 괜찮은 결과가 도출되겠죠. 물론 이런 후보군의 개수를 무한하게 늘리면 결국 완전 탐색이긴 하겠죠. 그러나 이러면 다시 복잡도 문제가 올라오구요. 그럼 후보군의 개수를 모노토닉하게 증가시키면 성능이 좋아지느냐. 그건 또 아니에요. 그래서 최근에는 검증셋의 결과를 보고 적절한 후보군의 개수를 조절해나가는 방식을 사용합니다.

 그리고 실제로 디코딩을 해보면, 서로 다른 알고리즘들이 결과가 꽤 다릅니다. 무엇보다도, 이런 방법론들이 지금 얼마나 잘 되고있는가-에 대한 판단히 힘들어요. 이게 한계점에 도달한건지, 아직 개선할게 많이 남아있는건지.

 그렇게 여러가지 탐색법을 생각하고, 실험해보다보면, 아 이걸 하는건 아니거같다-라는 답을 얻게됩니다. 디코딩을 한다는건, 스코어링된 정보를 가지고, 스코어가 가장 높은 번역 결과를 찾는 행윈데, 사실 높은 점수를 갖는 문장이 모든 Task에 대해 좋을 리가 없어요. 생각을 해보면, 실시간 번역이 필요한 환경에서는 퀼리티도 좋아야하지만 무엇보다 딜레이가 낮아야하고, 저학년들이 사용할 번역에서는 생성된 문장에 너무 어려운 단어들이 포함되어서는 안되야 하며, 모바일 기기 등에서 작동하는 번역기는 계산복잡도가 낮아야겠죠. 이렇게 필요한 영역이 제각기 다른데, 이런 것에 특화된 말뭉치 데이터도 없고, 뭐 어디에 가장 좋은 모델을 찾는거자체가 좀 어렵죠. 그래서 어떻게 해야하나. 제가 택한 방향 중 하나는, 그럼 생성하는 것도 머신 러닝으로 가능하냐-라는 겁니다.

 그걸 위해 우리가 알고 있는 CNN을 하나 봅시다. 아래 그림을 보면, CNN의 최종 Output보다도, 중간 레이어의 피쳐맵이 오히려 더 정확한 결과를 내포하고 있어요. 우리가 다루는 Autoregressive model, RNN도 다 같을 겁니다. 매번 다음 토큰을 예측할 때, 히든 레이어를 보면, 실제 뽑아낸 토큰보다 그 히든 레이어에 더 좋은 정보가 많다는거죠. 그리고 그럼 그 정보들을 이용해서 학습을 할 수 있을까-하는겁니다. 다만 이미지의 경우는 관련 연구가 많이 진행되었는데, 자연어 처리에서는 아는게 많이 없습니다. 그리고 이게 당연한게, 언어 데이터가 고차원으로 표현이 되다보니, 그걸 저희가 시각화하고, 패턴을 인식하는게 많이 어렵습니다. 못하는게 정상이죠. 다만 인간은 못하지만, Neural Net은 이미 잘 하고있죠.

 그러니까, 우리가 이걸 해석하려들지말고, 또다른 Neural Net을 사용해 해석하라고 시켜보자. 하는겁니다. 그럼 아래와 같은 형상이 되는데, 재밌는건 이런 형상이 강화학습과 굉장히 유사하다는 거에요. 덕분에 강화학습에서 사용되는 다른 방법론을 결합할 수 있습니다. 물론 그렇다고 잘 된다는 말은 아닙니다. 쨋든 이런 구조를 통해 인코딩을 풀어나가는 방법이 결과적으로는 가능했습니다.

 그래서 더 나아간 것이 Simultaneous translation인데요. 기존에는 문장이 통째로 들어오면, 번역 문장을 출력했었는데. 이번에는 누군가 실시간으로 말을 내뱉는 것처럼, 순서대로 단어가 툭툭 박히면, 그에따라, 받아들여진 단어만으로 어떤 문장을 생성할지, 아니면 다음 단어들을 기다릴지를 선택해가며, 번역 문장을 내뱉게 하는거죠. 그래서 여기서는 퀼리티도 중요하지만, 딜레이가 굉장이 중요하겠죠. 그렇게 선택할지 말지를, 강화학습을 통해 처리하면, 딜레이와, 정확도 두가지를 모두 잡을 수 있었습니다. 이상입니다.