Posted:      Updated:

word2vec

추론 기반 기법과 신경망

통계 기반 기법의 문제점

SVD를 $n \times n$ 행렬에 적용하는 비용은 $O(n^3)$이다.
따라서 현업에서 다루는 거대 코퍼스에는 SVD를 적용하기 어렵다.

batch

통계 기반 기법은 1회 처리만으로 단어의 분산 표현을 얻는다.
신경망을 활용하는 추론 기반 기법에서는 미니배치로 학습한다.
미니배치 학습에서는 신경망이 소량의 샘플을 반복해서 학습하며 가중치를 갱신한다.

데이터를 작게 나눠 학습하기 때문에 계산량이 큰 작업에서도 신경망을 학습시킬 수 있다.

추론 기반 기법 개요

inference

추론이란 주변 단어(컨텍스트)가 주어졌을 때 어떤 단어가 들어갈지를 추측하는 작업이다.
이러한 추론 문제를 풀고 학습하는 것이 추론 기반 기법이 다루는 문제이다.
추론 문제를 반복해서 풀면서 단어의 출현 패턴을 학습하는 것이다.

inference2

신경망(모델)을 통해 맥락 정보를 입력받아 각 단어의 출현 확률을 출력한다.
코퍼스를 사용해 모델이 올바른 추측을 내놓도록 학습시킨다.
이렇게 학습 결과로 단어의 분산 표현을 얻는다.

‘단어의 의미는 주변 단어에 의해 형성된다’는 분포 가설에 기초한다.

신경망에서의 단어 처리

단어를 고정 길이의 벡터로 변환해야 하는데, 이때 원 핫 벡터로 변환한다.
원 핫 벡터는 벡터의 원소 중 하나만 1이고 나머지는 모두 0인 벡터를 말한다.

“You say goodbye and I say hello.” 라는 문장으로 예를 들어보자.

one-hot

총 어휘 수만큼의 원소를 갖는 벡터를 준비하고, 인덱스가 단어 ID와 같은 원소를 1로, 나머지는 0으로 설정한다.
단어를 고정 길이 벡터로 변환함으로써 신경망의 입력층이 뉴런 수를 고정할 수 있다.

neurons

입력층의 뉴런은 총 7개가 된다.
각 뉴런은 차례로 각 단어에 대응한다.

fully-connected-layer

원 핫 벡터를 완전연결계층을 통해 변환하는 모습이다.
각 노드가 이웃 층의 모든 노드와 화살표로 연결되어 있다.
화살표에는 가중치(매개변수)가 존재하고, 입력층 뉴런과의 가중합이 은닉층 뉴런이 된다.

여기서 편향은 생략했다.
편향을 이용하지 않는 완전연결계층은 행렬 곱 계산에 해당한다.
이 경우 MatMul 계층과 같아진다.
대부분 딥러닝 프레임워크들은 편향을 이용할지 선택할 수 있도록 한다.

bias

완전연결계층의 가중치를 $\mathbf{W}$ 행렬로 표현했다.

이를 파이썬으로 작성하면 아래와 같다.

import numpy as np

c = np.array([[1, 0, 0, 0, 0, 0, 0]]) # 입력
W = np.random.randn(7, 3) # 가중치
h = np.matmul(c, W) # 중간 노드

print(h)

# [[-0.70012195  0.25204755  -0.79774592]]

ID가 0인 단어를 원 핫 벡터로 표현하여 완전연결계층을 통과시켜 변환하는 코드이다.
편향이 생략되었으므로 np.matmul() 로 행렬 곱을 계산했다.

import sys
sys.path.append('..')
import numpy as np
from common.layers import MatMul

c = np.array([[1, 0, 0, 0, 0, 0, 0]])
W = np.random.randn(7, 3)
layer = MatMul(W)
h = layer.forward(c)

print(h)
# [[-0.70012195  0.25204755  -0.79774592]]

앞에서 구현했던 MatMul 계층으로 구현한 코드이다.
common 디렉토리에 있는 MatMul 계층을 import 해서 사용한다.
forward() 메서드를 호출해 순전파를 수행했다.

단순한 word2vec

word2vec에서는 CBOW 모델과 skip-gram 모델이 주로 사용된다.
여기서는 CBOW 모델을 사용한다.

CBOW 모델의 추론 처리

CBOW 모델은 컨텍스트로부터 타깃(target)을 추측하는 용도로 사용하며, 활성화 함수를 사용하지 않는 간단한 구성의 신경망이다.
타깃은 중앙 단어이고, 주변 단어들이 컨텍스트이다.

CBOW 모델의 입력은 컨텍스트이며, 컨텍스트를 원 핫 벡터로 변환하여 CBOW 모델이 처리할 수 있도록 준비한다.

CBOW

CBOW 모델의 신경망 구조이다.
입력층이 2개 있고, 은닉층을 거쳐 출력층에 도착한다.

두 입력층에서 은닉층으로의 변환은 같은 완전연결계층이 처리하고, 은닉층에서 출력층 뉴런으로의 변환은 다른 연결계층이 처리한다.
입력층의 개수는 컨텍스트에 포함시킬 단어의 수로 결정한다.
여기서는 컨텍스트에 포함시킬 단어가 2개이므로 입력층이 2개이다.

은닉층의 뉴런은 입력층의 완전연결계층에 의해 변환된 값이다.
입력층이 여러개이면 전체를 평균한다.

출력층의 뉴런은 7개로, 각각의 뉴런이 각 단어에 대응한다.
출력층 뉴런은 각 단어의 점수를 뜻하고, 값이 높을수록 대응 단어의 출현 확률이 높아진다.
점수는 확률로 해석되기 전의 값이고, 소프트맥스 함수를 적용해서 확률을 얻을 수 있다.

완전연결계층의 가중치 $W_{in}$ 은 $7 \times 3$ 행렬이며, 이 가중치의 각 행에는 해당 단어의 분산 표현이 담겨 있다.
학습을 진행할수록 맥락에서 출현하는 단어를 잘 추측하는 방향으로 표현들이 갱신된다.

이때, 은닉층의 뉴런 수를 입력층의 뉴런 수보다 적게 해야 한다.
단어 예측에 필요한 정보를 간결하게 담아야 밀집 벡터 표현을 얻을 수 있다.
여기서 은닉층의 정보가 인코딩에 해당한다.
은닉층의 정보로부터 원하는 결과를 얻는 작업을 디코딩이라고 한다.

CBOW2

CBOW 모델의 앞단에는 2개의 MatMul 계층이 있으며, 출력을 더한 뒤 평균하여 은닉층 뉴런을 구한다.
은닉층 뉴런에 또 다른 MatMul 계층을 적용하여 점수(score)를 출력한다.

위에서 언급한 것처럼, 편향을 사용하지 않는 완전연결계층의 처리는 MatMul 계층의 순전파와 같다.

CBOW 모델의 추론 처리를 파이썬으로 구현하면 아래와 같다.

import sys
sys.path.append('..')
import numpy as np
from common.layers import MatMul

# 샘플 컨텍스트 데이터
c0  np.array([[1, 0, 0, 0, 0, 0, 0]])
c1 = np.array([[0, 0, 1, 0, 0, 0, 0]])

# 가중치 초기화
W_in = np.random.randn(7, 3)
W_out = np.random.randn(3, 7)

# 계층 생성
in_layer0 = MatMul(W_in)
in_layer1 = MatMul(W_in)
out_layer = MatMul(W_out)

# 순전파
h0 = in_layer0.forward(c0)
h1 = in_layer1.forward(c1)

h = 0.5 * (h0 + hl)
s = out_layer.forward(h)

print(s)
# [[ 0.30916255 0.45060817 -0.77308656 0.22054131 0.15037278
# -0.93659277 -0.59612048]]

가장 먼저 필요한 가중치를 초기화한다. 입력층에서 사용할 MatMul 계층을 가중치를 공유하도록 컨텍스트 수만큼 생성한다. 출력층의 MatMul 계층은 1개만 생성한다.

입력층 측의 MatMul 계층들의 forward() 메서드를 호출하여 중간 데이터를 계산하고, 출력층 측의 MatMul 계층을 통과시켜 점수를 구한다.

CBOW 모델의 학습

CBOW 모델에서 출력한 점수에 소프트맥스 함수를 적용하면 확률을 얻을 수 있다.
이 확률은 컨텍스트가 주어졌을 때 중앙에 어떤 단어가 출현하는지를 나타낸다.

CBOW 모델의 학습에서는 올바른 예측을 할 수 있도록 가중치를 조절하는 일을 한다.
결과로 가중치 $W_{in}$에 단어의 출현 패턴을 파악한 벡터가 학습된다.

CBOW 모델은 단어 출현 패턴 학습 시 사용한 코퍼스로부터 학습하므로, 코퍼스가 다르면 학습 후 얻게 되는 단어의 분산 표현도 달라진다.

다중 클래스 분류를 수행하는 신경망을 학습하기 위해서 소프트맥스와 교차 엔트로피 오차를 사용한다.
소프트맥스 함수를 이용해 점수를 확률로 변환하고, 확률과 정답 레이블로부터 교차 엔트로피 오차를 구한 후, 이 값을 손실로 사용해 학습한다.

network

CBOW 모델의 손실을 구하는 계산의 흐름이자 신경망의 순전파이다.
앞의 CBOW 모델에 Softmax 계층과 Cross Entropy Error 계층을 추가한 것이다.
이 두 계층을 Softmax with Loss라는 하나의 계층으로 구현할 수 있다.

network2

word2vec의 가중치와 분산 표현

word2vec에서 사용되는 신경망에는 두 가지 가중치가 있다.
입력 측 완전연결계층의 가중치($W_{in}$)와 출력 측 완전연결계층의 가중치($W_{out}$)이다.
입력 측 완전연결계층의 가중치 $W_{in}$의 각 행이 각 단어의 분산 표현에 해당한다.
출력 측 가중치 $W_{out}$에도 단어의 의미가 인코딩된 벡터가 저장되고 있다.
다만 출력 측 가중치는 열방향(수직 방향)으로 저장된다.

inandout

각 단어의 분산 표현은 입력 측과 출력 측 모두의 가중치에서 확인할 수 있다.

어떤 가중치를 사용할 지는 여러가지 방법이 존재하지만, word2vec(특히 skip-gram 모델)에서는 입력 측의 가중치를 사용하는 것이 대중적이다.
많은 연구에서 출력 측 가중치는 버리고 입력 측 가중치만을 최종 단어의 분산 표현으로 사용한다.

학습 데이터 준비

컨텍스트와 타깃

word2vec에서 사용하는 신경망의 입력은 컨텍스트이다.
정답 레이블은 컨텍스트 사이의 단어인 타깃이다.
따라서 신경망에 컨텍스트를 입력했을 때 타깃이 출현할 확률을 높여야 한다.

contexts

목표 단어를 타깃으로, 주변 단어를 컨텍스트로 뽑아낸 결과이다.
이를 구현한 코드는 아래와 같다.

import sys
sys.path.append('..')
from common.util import preprocess


def create_contexts_target(corpus, window_size=1):
  target = corpus[window_size-window_size]
  contexts = []

  for idx in range(window_size, len(corpus)-window_size):
    cs =[]
    for t in range(-window_size, window_size + 1):
      if t == 0:
        continue
      cs.append(corpus[idx + t])
    contexts.append(cs)

  return np.array(contexts), np.array(target)


text = 'You say goodbye and I say hello.'
corpus, word_to_id, id_to_word = preprocess(text)
print(corpus)
# [0 1 2 3 4 5 6]

print(id_to_word)
#  {0: 'you', 1: 'say', 2: 'goodbye', 3: 'and', 4: 'i', 5: 'hello', 6: '.'}

contexts, target = create_contexts_target(corpus, window_size=1)

print(contexts)
# [[0 2]
#  [1 3]
#  [2 4]
#  [3 1]
#  [4 5]
#  [1 6]]

print(target)
# [1 2 3 4 1 5]

원 핫 벡터로 변환

컨텍스트와 타깃을 단어ID에서 원 핫 벡터로 변환한다.
컨텍스트의 형상은 (6,2)인데, 원 핫 벡터로 표현하면 (6,2,7)이 된다.

import sys
sys.path.append('..')
from common.util import preprocess, create_contexts_target, convert_one_hot

text = 'You say goodbye and I say hello.'
corpus, word_to_id, id_to_word = preprocess(text)

contexts, target = create_contexts_target(corpus, window_size=1)

vocab_size = len(word_to_id)
target = convert_one_hot(target, vocab_size)
contexts = convert_one_hot(contexts, vocab_size)

CBOW 모델 구현

network2

구현할 신경망은 위와 같다.
SimpleCBOW 라는 이름으로 구현할 예정이다.
아래는 초기화 메서드이다.

import sys
sys.path.append('..')
import numpy as np
from common.layers import MatMul, SoftmaxWithLoss

class SimpleCBOW:
  def = __init__(self, vocab_size, hidden_size): 
    V , H = vocab_size, hidden_size

    # 가중치 초기화
    W_in = 0.01 * np.random.randn(V, H).astype('f')
    W_out = 0.01 * np.random.randn(H, V).astype('f')

    # 계층 생성
    self.in_layer0 = MatMul(W_in)
    self.in_layer1 = MatMul(W_in)
    self.out_layer = MatMul(W_out)
    self.loss_layer = SoftmaxWithLoss()

    # 모든 가중치와 기울기를 리스트에 모으기
    layers = [self.in_layer0, self.in_layer1, self.out_layer]
    self.params, self.grads =[], []
    for layer in layers
      self.params += layer.params
      self.grads += layer.grads

    # 인스턴스 변수에 단어의 분산 표현 저장
    self.word_vecs = W_in

인수로 어휘 수(vocab_size)와 은닉층의 뉴런 수(hidden_size)를 받는다.
가중치를 2개 생성하고 각각 작은 무작위 값으로 초기화한다.
입력층의 MatMul 계층을 2개, 출력층의 MatMul 계층을 하나, Softmax with Loss 계층을 하나 생성한다.
여기서 입력 측의 MatMul 계층의 수는 컨텍스트에서 사용하는 단어 수(윈도우 크기)와 같고, 모두 같은 가중치를 사용한다.

아래는 순전파 메서드를 구현한 코드이다.
인수로 컨텍스트와 타깃을 받아 손실을 반환한다.

def forward(self, contexts, target):
  h0 = self.in_layer0.forward(contexts[:, 0])
  h1 = self.in_layer1.forward(contexts[:, 1])
  h = (h0 + h1) * 0.5
  score = self.out _layer.forward(h)
  loss = self.loss_layer.forward(score, target)
  return loss

아래 그림은 역전파를 나타낸다.

backward

순전파와 반대 방향으로 전파하고, 1에서 시작하여 Softmax with Loss 계층에 입력된다.
Softmax with Loss 계층의 역전파 출력이 ds이며, ds를 출력 측 MatMul 계층으로 입력한다.
$\times$ 의 역전파는 순전파 시 입력을 서로 바꿔 기울기에 곱한다.
$+$ 의 역전파는 기울기를 그대로 통과시킨다.

아래는 역전파를 구현한 코드이다.

def backward(self, dout=1): 
  ds = self.loss_layer.backward(dout)
  da = self.out_layer.backward(ds)
  da *= 0.5
  self.in_layer1.backward(da)
  self.in_layer0.backward(da)
  return None

forward() 메서드를 호출하고 backward() 메서드를 실행하는 것만으로 변수 grads에 저장된 각 매개변수의 기울기가 갱신된다.

학습 코드 구현

import sys
sys.path.append('..')
from common.trainer import Trainer
from common.optimizer import Adam
from simple_cbow import SimpleCBOW
from common.util import preprocess, create_contexts_target, convert_one_hot

window_size = 1
hidden_size = 5
batch_size = 3
max_epoch = 1000

text = 'You say goodbye and I say hello.'
corpus, word_to_id, id_to_word = preprocess(text)

vocab_size = len(word_to_id)
contexts, target = create.contexts.target(corpus, window_size)
target = convert.one.hot(target, vocab_size)
contexts = convert.one.hot(contexts, vocab_size)

model = SimpleCBOW(vocab_size, hidden_size)
optimizer = Adam()
trainer = Trainer(model, optimizer)

trainer.fit(contexts, target, max_epoch, batch_size)
trainer.plot()

word_vecs = model.word_vecs
for word_id, word in id_to_word.items(): 
  print(word, word_vecs[word_id])

학습 데이터를 준비해 신경망에 입력한 다음, 기울기를 구하고 가중치 매개변수를 순서대로 갱신한다.

학습 과정에서 책에서 제공하는 Trainer 클래스를 활용한다.
매개변수 갱신 방법으로 Adam을 활용했다.
학습 데이터로부터 미니배치를 선택하고, 신경망에 입력해 기울기를 구하고, 기울기를 Optimizer에 넘겨 매개변수를 갱신하는 작업이 수행됐다.

loss

you [-0.9031807 -1.0374491 -1.4682057 -1.3216232 0.93127245]
say [ 1.2172916 1.2620505 -0.07845993 0.07709391 -1.2389531 ]
goodbye [-1.0834033 -0.8826921 -0.33428606 -0.5720131 1.0488235 ]
and [ 1.0244362 1.0160093 -1.6284224 -1.6400533 -1.0564581]
i [-1.0642933 -0.9162385 -0.31357735 -0.5730831 1.041875 ]
hello [-0.9018145 -1.035476 -1.4629668 -1.3058501 0.9280102]
. [1.0985303 1.1642815 1.4365371 1.3974973 -1.0714306]

코드를 실행한 결과이다.

학습을 거듭할수록 손실이 줄어든다.
word_vecs의 각 행에는 대응하는 단어 ID의 분산 표현이 저장되어 있다.

word2vec 보충

CBOW 모델과 확률

A라는 현상이 일어날 확률은 $P(A)$ 라고 쓴다.
A와 B가 동시에 일어날 확률인 동시 확률은 $P(A,B)$ 로 쓴다.

사건이 일어난 후의 확률인 사후 확률은 $P(A|B)$ 로 쓴다.
B라는 정보가 주어졌을 때 A가 일어날 확률로도 해석할 수 있다.

CBOW 모델은 컨텍스트가 주어졌을 때 타깃 단어가 출현할 확률을 출력한다.

CBOW3

코퍼스를 $w_1, w_2, \cdots , w_T$ 처럼 단어 시퀀스로 표기하고, $t$ 번째 단어에 대해 윈도우 크기가 1인 컨텍스트를 고려하려고 한다.
이때, 타깃이 $w_t$ 가 될 확률을 아래와 같은 수식으로 표현할 수 있다.

\[P(w_t | w_{t-1}, w_{t+1})\]

이는 $w_{t-1}$ 과 $w_{t+1}$ 이 주어졌을 때 $w_t$ 가 일어날 확률이다.

교차 엔트로피 오차에 적용시켜 CBOW 모델의 손실 함수를 간결하게 표현할 수 있다.

\[L = - \sum_{k} t_k \log y_k\]

위 식에서 $y_k$ 는 $k$ 번째에 해당하는 사건이 일어날 확률을 뜻한다.
$t_k$ 는 정답 레이블이며, 원 핫 벡터로 표현된다.
$w_t$ 가 발생할 때, $w_t$ 에 해당하는 원소만 1이고 나머지는 0이 된다.
따라서 아래와 같은 식을 유도할 수 있다.

\[L = - \log{P(w_t | w_{t-1} , w_{t+1})}\]

따라서 CBOW 모델의 손실 함수는 $w_{t-1}$ 과 $w_{t+1}$ 이 주어졌을 때 $w_t$ 가 일어날 확률 식에 $\log$ 를 취한 다음 마이너스를 붙인 것이다.
이를 음의 로그 가능도(negative log likelishood) 라고 한다.

\[L = - \frac {1} {T} \sum_{t=1}^T \log P(w_t | w_{t-1} , w_{t+1})\]

샘플 데이터 하나가 아닌 코퍼스 전체로 확장한 식이다.
CBOW 모델의 학습은 이 손실 함수의 값을 가능한 한 작게 만드는 일을 수행한다.
이때의 가중치 매개변수가 단어의 분산 표현이다.

skip-gram 모델

skip-gram은 CBOW에서 다루는 컨텍스트와 타깃을 역전시킨 모델이다.

CBOW-and-skip-gram

CBOW 모델은 컨텍스트가 여러 개 있고, 여러 컨텍스트로부터 중앙의 단어(타깃)을 추측한다.
skip-gram 모델은 중앙의 단어(타깃)로부터 주변의 여러 단어(컨텍스트)를 추측한다.

skip-gram

skip-gram 모델의 신경망 구성이다.
입력층은 하나이고, 출력층은 컨텍스트의 수만큼 존재한다.
따라서 각 출력층에서 개별적으로 손실을 구하고, 개별 손실들을 모두 더한 값이 최종 손실이다.

중앙 단어(타깃) $w_t$ 로부터 컨텍스트인 $w_{t-1}$ 와 $w_{t+1}$ 을 추측하는 경우를 확률 표기로 나타내면 아래와 같다.

\[P(w_{t-1} , w_{t+1} | w_t)\]

이는 $w_t$ 가 주어졌을 때 $w_{t-1}$ 와 $w_{t+1}$ 이 동시에 일어날 확률을 뜻한다.

skip-gram 모델은 컨텍스트 단어들 사이에 관련성이 없다고 가정하고 아래와 같이 분해한다.
즉, 조건부 독립이라고 가정하고 분해한다.

\[P(w_{t-1} , w_{t+1} | w_t) = P(w_{t-1} | w_t) P (w_{t+1} | w_t)\]

교차 엔트로피 오차에 이를 적용하여 손실 함수를 유도한다.

\[\begin{matrix} L &=& - \log P (w_{t-1}, w_{t+1} | w_t) \\ &=& - \log P (w_{t-1} | w_t) P (w_{t+1} | w_t) \\ &=& - (\log P (w_{t-1} | w_t) + \log P (w_{t+1} | w_t)) \end{matrix}\]

유도 과정에서 $\log xy = \log x + \log y$ 라는 로그의 성질을 이용한다.

\[L = - \frac {1} {T} \sum_{t=1}^T (\log P (w_{t-1} | w_t) + \log P (w_{t+1} | w_t))\]

샘플 데이터 하나가 아닌 코퍼스 전체로 확장한 식이다.

단어 분산 표현의 정밀도 면에서 skip-gram 모델의 결과가 더 좋은 경우가 많으므로, CBOW 모델보다는 skip-gram 모델을 사용하는 것이 좋다.
또한, 코퍼스가 커질수록 저빈도 단어나 유추 문제의 성능 면에서 skip-gram 모델이 더 뛰어난 경향이 있다.
반면 skip-gram 모델은 손실을 맥락 수만큼 구해야 해서 계산 비용이 커지므로, 학습 속도 면에서는 CBOw 모델이 더 빠르다.

skip-gram 모델은 하나의 단어로부터 주변 단어들을 예측하므로, CBOW 모델보다 어려운 문제에 도전한다고 할 수 있다. 따라서 더 어려운 상황에서 단련하는 만큼 skip-gram 모델에서 산출한 단어의 분산 표현이 더 뛰어날 가능성이 커지는 것이다.

통계 기반 vs. 추론 기반

통계 기반 기법은 코퍼스의 전체 통계로부터 1회 학습하여 단어의 분산 표현을 얻는다.
추론 기반 기법은 코퍼스를 일부분씩 여러 번 보면서 학습하는 방식인 미니배치 학습을 사용한다.

어휘에 추가할 새 단어가 생겨서 단어의 분산 표현을 갱신해야 하는 상황

  1. 통계 기반 기법

계산을 처음부터 다시 해야 한다.
동시발생 행렬을 다시 만들고 SVD를 수행하는 작업을 다시 해야 한다.

  1. 추론 기반 기법 (word2vec)

매개변수를 다시 학습할 수 있다.
지금까지 학습한 가중치를 초깃값으로 사용해 다시 학습하면 된다.
기존에 학습한 경험을 해치지 않으면서 단어의 분산 표현을 효율적으로 갱신할 수 있게 된다.

분산 표현의 성격

  1. 통계 기반 기법

단어의 유사성이 인코딩된다.

  1. 추론 기반 기법 (word2vec)

단어의 유사성은 물론, 한층 복잡한 단어 사이의 패턴까지도 파악되어 인코딩된다.
“king - man + woman = queen”과 같은 유추 문제를 풀 수 있게 된다.

결론

이러한 이유로 추론 기본 기법이 통계 기반 기법보다 정확하다고 오해하곤 한다.
실제로 단어의 유사성을 정량 평가한 결과, 의외로 두 방식의 우열을 가릴 수 없었다고 한다.

“Don’t count, predict! (세지 말고, 추측하라)” 논문에 따르면 통계 기반 기법과 추론 기반 기법을 체계적으로 비교한 결과 추론 기반 기법이 항상 더 정확했다고 한다. 그러나 이후 다른 논문에서는 단어의 유사성 관련 작업의 경우 정확성은 하이퍼파라미터에 크게 의존하며 통계 기반과 추론 기반의 우열을 명확히 가릴 수 없다고 보고했다.

또한 추론 기반 기법과 통계 기반 기법은 서로 관련되어 있다.
skip-gram과 이후 등장할 네거티브 샘플링을 이용한 모델은 모두 코퍼스 전체의 동시발생 행렬을 살짝 수정한 행렬에 특수한 행렬 분해를 적용한 것과 같다고 한다.
즉, 특정 조건 하에 서로 연결되어 있다고 할 수 있다.

word2vec 이후 추론 기반 기법과 통계 기반 기법을 융합한 GloVe 기법이 등장했다.
Glove의 기본 아이디어는 코퍼스 전체의 통계 정보를 손실 함수에 도입해 미니배치 학습을 하는 것이다.

정리

토마스 미콜로프가 제안한 word2vec은 많은 자연어 처리 과업에서 유용성을 입증했다.
CBOW 모델은 기본적으로 2층 구성의 아주 단순한 신경망이고, MatMul 계층과 Softmax with Loss 계층을 사용해 구축하여 작은 코퍼스를 학습할 수 있다.
다만 처리 효율 면에서 몇 가지 문제가 있으므로 이를 개선해야 한다.

Categories:

댓글남기기