[Text2img PART2 Prior Knowledge] Word Embedding
프로젝트에서 사용할 데이터는 사진과 텍스트 데이터이다. 하지만 딥러닝 모델은 수치형 텐서만을 이용하기 때문에 텍스트 원본을 입력으로 사용할 수 없다. 따라서 텍스트 데이터를 수치형 텐서로 변경하는 과정이 필요하다. PART3에서 볼 수 있지만 기존의 text2image 모델에서 텍스트 데이터를 처리하기 위해 단어 임베딩을 주로 사용한다. 하지만 이로 인해 테스트에서 이슈가 발생하게된다. 해당 이슈 내용은 PART4에서 확인 가능하다. 그 이전에 기존 text2image에서 사용한 단어 임베딩에 대해 먼저 이해해보려한다.
해당 문서는 아래 링크에서 더 자세한 내용을 확인할 수 있다.
단어 임베딩을 진행할 때 처음 접하는 것이 원 핫 인코딩(One-hot-encoding)이다. 해당 방법에 대해서 따로 설명은 진행하지 않겠다. (위 링크에서 확인 가능)
원 핫 인코딩 방식을 이용하는 것은 여러 한계를 가진다.
-
단어의 갯수가 늘어나면 벡터의 차원이 늘어난다. (sparse, 고차원임)
-
유사성을 전혀 표현할 수 없다.
이를 해결하기 위해 텍스트의 의미를 R차원의 Vector로 매핑시키는 단어 임베딩 (word Embedding) 방식을 이용한다. 단어 임베딩이란 단어를 임베딩하여 벡터 공간으로 옮겨 놓는 것을 의미한다. 따라서 고차원의 원 핫 인코딩 방식과 달리 저차원의 실수형 벡터로 표현된다. 잘 구축된 embedding 공간에서는 동의어가 비슷한 단어 벡터로 embedding될 것이다. 일반적으로는 두 단어의 벡터 사이의 거리가 단어들 사이의 의미상 거리와 관계된다.
기존에 주로 알려진 word Embedding에는 word2vec, Glove, FastText, ELMo등이 있다. 이러한 word Embedding 기술들의 차이는 주어진 데이터의 언어적 특성을 포착하는 기술뿐만이 아닌 다운스트림 작업에 있어 예상치 못한 결과를 가져오기도 한다.
Word2Vec
word2vec과 관련해서는 인터넷에 워낙 좋은 자료가 많이 있으므로 간단하게 정리하고 넘어가려한다.
“단어 연결 기반으로 단어의 연관성을 벡터로 만든다”
문장 내부의 단어(word token)를 벡터로 변환하는 도구이다. 즉 단어의 연결을 기반으로 단어의 연관성을 벡터로 만들어준다. 이를 이용하여 단어의 의미를 파악하게 할 수 있다.
사용자가 주변단어 몇 개를 볼 지(window)를 정해주면 Word2Vec은 말뭉치를 window 크기로 슬라이딩하면서 스크린하며 중심단어별로 주변단어들을 보고 각 단어에 해당하는 벡터들의 요소값들을 조금씩 업데이트함으로써 단어를 벡터로 임베딩한다.
다시 말해 Word2Vec은 window 내에 등장하지 않는 단어에 해당하는 벡터는 중심단어 벡터와 벡터공간상에서 멀어지게끔(내적값 줄이기), 등장하는 주변단어 벡터는 중심단어 벡터와 가까워지게끔(내적값 키우기) 한다는 것이다.
Glove
앞서 word2vec와 동일하게 Glove는 단어를 쪼개질 수 없는 단위로 나누어 벡터를 생성한다. 또한 두 모델은 그들의 co-occurrence information(동시 등장 정보)를 이용하여 단어의 벡터를 학습한다. 다시 말해 큰 텍스트 말뭉치 내에서 얼마나 빈번하게 ‘같이 함께 등장’했는가를 학습한다. 그러나 word2vec은 ‘예측적’인 모델인 반면에 Glove는 ‘카운트 기반’의 모델이다.
예측모델의 경우는 loss의 예측 능력을 향상시키기위해 벡터를 학습한다.
즉 위에서 보았듯이 벡터를 표현하기 위해서 주변 단어로 부터 대상단어를 예측하기위한 loss을 향상 시키기 위해 학습을 진행한다 (feed-forward nn, SGD). 카운트 기반의 모델은 본질적으로 ‘co-occurrence counts matrix(카운트 행렬)’의 차원 축소로 학습을 진행한다. 먼저 동시 등장 정보의 큰 행렬을 구성한다. 행렬은 큰 말뭉치에 대해 ‘단어(행)’ 그리고 ‘context(열)’로 구성된다 → (word * context). ‘학습을 진행한다는 것’은 각 ‘단어(행)’에 대해서 어떤 ‘context(열)’에서 이 단어를 얼마나 자주 볼 수 있는지를 계산하는 것이다. ‘context’라는 것은 당연히 거대하다. 왜냐하면 본질적으로 사이즈가 combinatorial(조합적)이기 때문이다. 아무튼 위에서 보았듯이 이 거대한 차원의 행렬을 축소해야한다. 따라서 다음 단계는 (wordcontext) 행렬을 요인화(factorize)해야한다. 즉, 각 행이 각각 단어에 대한 벡터를 산출하는 저차원 행렬(wordfeature)을 생성해야한다.
일반적으로 이 과정은 ‘reconstruction(재구성) loss’를 최소화함으로써 이루어진다. 즉, 고차원 데이터의 대부분의 variance를 찾을 수 있는 낮은 차원의 표현을 찾는 과정이다. Glove의 경우에는 카운트를 정규화하고 log-smoothing하는 과정을 통해 카운트 matrix를 사전 처리한다.
그러나 앞서 지적했듯 모든 학습용 하이퍼파라미터에 대해 제어를 하는경우 위의 두가지 방법을 사용하여 생성된 임베딩은 다운스트림의 NLP 작업에 있어 매우 비슷하게 동작하는 경향이 있다. word2vec에 비해 Glove가 가지는 부가적인 이점은 구현을 병렬화하기 쉽다는 것이다. 즉 더 많은 데이터들을 보다 쉽게 학습을 진행할 수 있다는 것이다.
위에 어려웠던 말들을 다시 이해해보자. Glove란 Global Vectors로 global matrix, 즉 전역 행렬을 요인화(분해)하고 local 문맥을 이용하는 것이다.
자꾸 어려운 말이 나오는데… 동시 등장이 있는 단어의 단어 벡터를 이용하여 동시 등장의 값을 예측하는 회귀 문제를 다룬다. (word2vec은 하나의 대상 단어의 단어 벡터를 이용하여 주변 단어의 벡터를 예측하는 모델이다. )