
one-hot encoding을 통해 나온 one-hot vectors은 표현하고자 하는 단어의 인덱스 값만 1이고, 나머지는 모두 0으로 표현되는 벡터 표현 방법이었다. 이렇게 벡터 또는 행렬의 값이 대부분 0으로 표현되는 방법을 희소 표현이라고 한다. one-hot vector은 희소 벡터이다.
희소 벡터는 단어 개수가 늘어나면 벡터의 차원이 한없이 커져 공간 낭비를 야기한다는 단점이 있다. 또한, 단어의 의미를 표현하지 못한다는 단점도 있다.
밀집 표현은 벡터의 차원을 단어 집합의 크기로 상정하지 않는다. 사용자 정의 값으로 모든 단어의 벡터 표현의 차원을 맞춘다. 또한, 이 과정에서 0과 1만 가진 값이 아니라, 실수값을 가지게 된다.
<희소 표현>
강아지 = [ 0 0 0 0 1 0 0 0 0 0 0 0 ... 중략 ... 0]
이때 1 뒤의 0의 수는 9995개. 차원은 10,000
<밀집 표현>
강아지 = [0.2 1.8 1.1 -2.1 1.1 2.8 ... 중략 ...]
이 벡터의 차원은 128
위 예시와 같이, 벡터의 차원이 조밀해졌으므로 밀집 벡터라고 한다.
단어를 밀집 벡터의 형태로 표현하는 방법을 워드 임베딩이라고 한다. 그리고 이 밀집 벡터를 워드 임베딩 과정을 통해 나온 결과라고 하여 임베딩 벡터라고도 한다. 케라스에서 제공하는 도구인 Embedding() 은, 단어를 랜덤한 값을 가지는 밀집 벡터로 변환한 뒤에, 인공 신경망의 가중치를 학습하는 것과 같은 방식으로 단어 벡터를 학습하는 방법을 사용한다.
one-hot 벡터는 단어 벡터 간 유의미한 유사도를 계산할 수 없다는 단점이 있다. 그래서 그 유사도를 반영할 수 있도록 단어의 의미를 수치화할 방법이 필요한데, 그 대표적인 방법이 워드투벡터이다.
희소 표현은 인덱스를 0 또는 1로만 표현하기 때문에, 각 단어 벡터간 유의미한 유사성을 표현할 수 없다는 단점이 있다. 이에 대해 분산 표현(Distributed Representation) 이 대안으로 제시됐는데, 이는 단어의 의미를 다차원 공간에 벡터화하는 방법이다. 이렇게 분산 표현으로 단어 간 의미적 유사성을 벡터화하는 작업을 워드 임베딩이라고 부르며, 이렇게 표현된 벡터를 임베딩 벡터라고 한다.
<희소 표현>
강아지 = [ 0 0 0 0 1 0 0 0 0 0 0 0 ... 중략 ... 0]
<분산 표현>
강아지 = [0.2 0.3 0.5 0.7 0.2 ... 중략 ... 0.2]
희소 표현이 고차원에 각 차원이 분리된 표현 방법이었다면, 분산 표현은 저차원에 단어의 의미를 여러 차원으로 분산하여 표현하는 방법이다. 이러한 방식으로 단어 벡터 간 유의미한 유사도를 계산할 수 있다.
CBOW은 주변에 있는 단어들을 입력으로 하여 중간에 있는 단어들을 예측하는 방법이다. 다음과 같은 예문이 있다.
The fat cat sat on the mat
CBOW 방식에 의하면, ['The', 'fat', 'cat', 'on', 'the', 'mat']라는 주변 단어(context word) 로부터 중심 단어(center word) 인 sat을 예측할 수 있다.
중심 단어를 예측하기 위해, 전후로 몇 개의 단어를 볼 지 정하기 위해 윈도우(window) 라는 범위를 정한다. 예를 들어, 윈도우 크기가 2이었다면, sat 앞의 두 단어 fat, cat, 뒤의 두 단어 on, the가 입력으로 사용된다. 즉, 윈도우 크기가 n이면, 참고되는 주변 단어의 개수는 2n이다.

윈도우 크기가 정해지면 윈도우를 옆으로 움직여서 주변 단어와 중심 단어의 선택을 변경하며 학습을 위한 데이터셋을 만드는데, 이 방법을 슬라이딩 윈도우(sliding window) 라고 한다.
한편, CBOW의 인공 신경망을 도식화하면 다음과 같다.

입력층에 주변 단어들의 one-hot vectors가 입력으로 들어가고, 출력층에서 예측하고자 하는 중심 단어의 one-hot vector가 레이블로 필요하다. 참고로, 위 그림과 같이, Word2Vec은 은닉층이 다수인 딥러닝 모델이 아니라, 은닉층이 한 개인 shallow neural network이다. 또한, 그 은닉층은 활성화 함수가 존재하지 않으며, 룩업 테이블이라는 연산을 담당하는데, 투사층(projection layer)이라고도 불린다.

위 그림을 보면, 투사층의 크기가 인 것을 알 수 있다. CBOW에서 투사층의 크기 은 임베딩하고 난 벡터의 차원이 된다. 또한, 입력층과 투사층 사이의 가중치 는 행렬이며, 투사층에서 출력층 사이의 가중치 는 행렬이다. 여기서 은 단어 집합의 크기이며, 두 행렬은 동일한 행렬을 전치한 것이 아니고, 서로 다른 행렬이다. 이렇게 CBOW은 주변 단어로 중심 단어를 더 정확하게 맞추기 위해 와 을 계속해서 학습해간다.

만약 윈도우 크기가 2라면, 중심 단어를 예측하기 위해 총 4개가 입력 벡터로 사용된다. 따라서 평균을 구할 때, 4개의 결과 벡터에 대해 평균 을 구하게 된다. 평균 벡터 은 두 번째 가중치 행렬 와 곱해진다. 곱셈 결과가 Softmax 함수를 지나면서 벡터의 각 원소들의 값은 0과 1 사이의 실수로, 총 합은 1이 된다. 다중 클래스 분류 문제를 위한 일종의 스코어 벡터(score vector) 이다.

역전파를 수행하면 와 가 학습되는데, 학습이 완료되면 차원의 크기를 가지고 있는 의 행렬의 행을 각 단어의 임베딩 벡터로 사용하거나 , 행렬 두 가지 모두를 가지고 임베딩 벡터를 사용하기도 한다.
Skip-gram은 중심 단어에서 주변 단어를 예측하는 방식이다. 윈도우 크기가 2일 때, 데이터셋은 다음과 같이 구성된다.

인공신경망을 도식화하면 다음과 같다. 중심 단어로부터 주변 단어를 예측하기 때문에 투사층에서 벡터들의 평균을 구하는 과정은 없다. 여러 논문에 의해, 전반적으로 Skip-gram이 CBOW보다 성능이 더 좋다고 알려져 있다.


| NNLM | Word2Vec |
|---|---|
| 워드 임베딩 도입 → 단어 벡터 간 유사도 구하기 | 워드 임베딩 자체 집중 → NNLM의 느린 학습 속도 및 정확도 개선 |
| 다음 단어 예측 | 중심 단어 예측 |
| 예측 단어의 이전 단어만 참고 | 예측 단어의 앞, 뒤 모든 단어 참고 |
| 은닉층 존재 | 은닉층 부재(투사층 다음에 바로 출력층으로 연결) |
Word2Vec의 출력층에서는 Softmax 함수를 지난 단어 집합 크기의 벡터와 실제값인 one-hot 벡터와의 오차를 구하고, 이로부터 임베딩 테이블에 있는 모든 단어에 대한 임베딩 벡터 값을 업데이트한다. 그런데 단어 집합의 크기가 수만 이상이라면, Word2Vec은 해당 작업을 수행하기에는 너무 무겁다. 예를 들어, Word2Vec은 역전파 과정에서 모든 단어의 임베딩 벡터값의 업데이트를 수행하는데, 만약 현재 집중하고 있는 중심 단어와 주변 단어가 '강아지', '고양이', '귀여운'과 같은 단어라면, 이와 무관한 '돈가스', '컴퓨터' 등 수많은 단어의 임베딩 벡터값까지 업데이트하는 것은 비효율적이다.

Negative Sampling은 Word2Vec이 학습 과정에서 전체 단어 집합이 아니라 일부 단어 집합에만 집중할 수 있도록 한다. 이렇게 하나의 중심 단어에 대해서 전체 단어 집합보다 훨씬 작은 단어 집합을 만들고, 마지막 단계를 이진 분류 문제로 변환한다. 주변 단어들을 긍정(positive), 랜덤으로 샘플링된 단어들을 부정(negative)으로 레이블링하면 이진 분류 문제를 위한 데이터셋이 된다.

Skip-gram은 중심 단어를 입력 받아 주변 단어를 예측하는 모델이라고 했다. SGNS은 중심 단어와 주변 단어 모두 입력이 되고, 이 두 단어가 실제로 윈도우 크기 내에 존재하는, 이웃 관계인지 그 확률을 예측한다.

위 그림에서 좌측 테이블은 기존 Skip-gram을 학습하기 위한 데이터셋이다. 그러나 SGNS을 학습하기 위해서는, 우측 테이블로 수정해야 한다. Skip-gram 데이터셋에서 중심 단어와 주변 단어를 각각 입력 1, 입력 2로 하며, 이 둘은 실제 윈도우 크기 내에서 이웃 관계였으므로 레이블은 1로 한다. 그리고나서 다음과 같이 레이블이 0인 샘플을 준비한다.

단어 집합에서 랜덤으로 선택한 단어들을 입력 2로 하고, 레이블을 0으로 한다. 그리고나서 두 개의 임베딩 테이블을 다음과 같이 준비한다. 두 임베딩 테이블은 훈련 데이터의 단어 집합의 크기를 가지므로 그 크기가 같다.

두 테이블 중 하나는 입력 1인 중심 단어의 테이블 룩업을 위한 임베딩 테이블이고, 하나는 입력 2인 주변 단어의 테이블 룩업을 위한 임베딩 테이블이다. 각 단어는 각 임베딩 테이블을 테이블 룩업하여 임베딩 벡터로 변환한다.

중심 단어와 주변 단어의 내적값을 이 모델의 예측값으로 하고, 레이블과의 오차로부터 역전파하여 중심 단어와 주변 단어의 임베딩 벡터값을 업데이트한다. 학습 후에는, 임베딩 행렬을 좌측의 임베딩 행렬을 임베딩 벡터로 사용할 수도 있고, 두 행렬을 더한 후 사용하거나 두 행렬을 연결(concatenate)해서 사용할 수도 있다.

<참고 문헌>
유원준/안상준, 딥러닝을 이용한 자연어 처리 입문
https://wikidocs.net/21694
박호현 교수님, 인공지능, 중앙대학교 전자전기공학부, 2024