chatGPT를 위한 NLP 기초 : 워드 임베딩
Word2vec는 분포 가설의 아이디어를 따른다. 분포 가설이란 비슷한 문맥에서 같이 등장하는 경향이 있는 단어들은 비슷한 의미(높은 유사도를 가진 벡터)를 가진다는 뜻이다.
이 Wrod2Vec에는 크게 두 가지 기법이 있는데 CBoW와 Skip-gram이다. 이 둘은 매우 유사하다. 차이점이 있다면 CBoW의 경우는 주변에 있는 단어로 중간의 단어를 예측하는 기법이고 Skip-gram은 중간 단어로 주변 단어를 예측하는 기법이다.
주변에 있는 단어로 중심 단어를 예측하는 CBoW는 앞뒤로 몇 개의 단어를 주변 단어로 삼을지 윈도우(window)를 설정해 줘야 한다. 윈도우는 쉽게 말해 범위라고 생각하면 된다.
출처 : https://medium.com/analytics-vidhya/word2vector-using-gensim-e055d35f1cb4
윈도우의 크기를 1로 지정하면 앞뒤 한 단어씩 주변 단어로 인식하고 2로 지정하면 앞뒤 각각 두 단어씩 주변 단어로 인식한다. 윈도우 크기를 지정하고 나면 윈도우를 움직여 주변 단어와 중심 단어를 바꿔가며 학습하는 슬라이딩 윈도우(sliding window)를 통해 데이터 셋을 만든다.
((like), I), ((I, natural), like), ((like, language), natural), ((natural, processing), language), ((language), processing)
이렇게 만들어진 데이터 셋을 통해서 원-핫 인코딩을 통해 원-핫 벡터로 변환 후 CBoW에 입력하여 출력을 얻는다. 자세한 설명은 아래의 그림을 풀어가며 살펴보도록 하겠다.
출처 : https://lilianweng.github.io/posts/2017-10-15-word-embedding/
위 그림을 살펴보면 입력층, 은닉층, 출력층으로 구성되어 있는 것을 확인할 수 있다. 은닉층이 1개 이기 때문에 얕은 신경망이라고 부른다. 여기서 입력층과 출력층의 크기는 단어 집합의 크기인 V, 은닉층의 크기는 사용자가 정의하는 하이퍼 파라미터로 N이라고 하겠다.
우선 출력층에서 은닉층으로 가는 과정을 살펴보면 원-핫 벡터를 Matrix W(가중치 행렬)와 곱하게 된다. 식으로 보면 V X N이 된다. 이렇게 되면 룩업 테이블(lookup table)이 된다. 왜냐하면 원-핫 벡터는 각 단어의 정수 인덱스 해당하는 위치에만 1의 값을 가지고 나머지는 0이다. 그래서 행렬 곱을 하게 되면 0X0은 0이기 때문에 정수 인덱스에 해당하는 가중치 행렬의 특정 행을 제외하고는 다 0이 된다. 즉, 테이블에서 특정 행의 값을 그대로 룩업해 온 것이다.
다음은 은닉층을 거치는 과정이다. 가중치 행렬을 거친 주변 단어 벡터들을 가지고 은닉층을 거친다. CBoW에서는 벡터들의 평균을 구하거나, 합하는 방법으로 최종 은닉층의 결과로 출력한다.
Word2Vec에서는 은닉층의 활성화 함수가 없고 가중치 행 곱만 수행하기 때문에 투사층(projection layer)라고 부른다.
이번에는 은닉층에서 출력층을 거치는 과정이다. 식으로는 N X V로 표현할 수 있으며 출력층은 활성화 함수로 소프트 맥스 함수를 사용해 모든 차원의 총합이 1이 되는 벡터로 변경이 된다. 즉, 확률로 변환을 하는 것이다. 그리곤 이 확률과 정답 레이블로부터 교차 엔트로피 오차를 구한 후, 값을 손실로 사용해서 학습을 진행한다.
CBoW 과정을 모두 거친 원-핫 벡터는 출력층의 벡터를 중심 단어의 원-핫 벡터와의 손실(loss)을 최소화하도록 학습시킨다. 학습이 다 되면 N 차원의 크기를 갖는 W의 행이나 W'의 열로부터 어떤 것을 임베딩 벡터로 사용할지 결정하거나 W와 W'의 평균치를 구해 임베딩 벡터로 결정한다.
Skip-gram은 CBoW와 반대로 주변 단어로 중심 단어를 예측한다. 이렇게 되면 형성되는 데이터 셋도 다를 수밖에 없다. 데이터 셋은 밑에서 확인해 보도록 하겠다.
(i, like) (like, I), (like, natural), (natural, like), (natural, language), (language, natural), (language, processing), (processing, language)
출처 : https://lilianweng.github.io/posts/2017-10-15-word-embedding/
Skip-gram은 위의 그림과 같은 프로세스를 가진다. CBoW와 다른 점은 은닉층에서 벡터의 덧셈과 평균을 구하는 과정이 없다는 것이다. 이외의 나머지는 CBoW와 동일하다.
참고 : negative sampling라는 것이 있다. 다중 클래스 분류 문제를 시그모이드 함수를 사용한 이진 분류 문제로 바꾼다. 이는 Word2Vec는 연산량이 많기 대문에 이를 보완하기 위해서 고안된 기법이다.
참고자료 : http://jalammar.github.io/illustrated-word2vec/