sliver__

[NLP] chapter04 - word2vec 속도개선 본문

CS/NLP

[NLP] chapter04 - word2vec 속도개선

sliver__ 2022. 2. 10. 16:18
728x90

[word2vec 개선 1]

 

  • CBOW 모델은 단어 2개를 맥락으로 사용해 타깃을 추측한다.
  • 100만 개의 단어를 학습시킬 때는 문제가 발생한다.
    • 입력층의 원핫 벡터와 가중치 행렬($W_{in}$)의 계산 -> Embedding 계층 도입
    • 은닉층과 가중치 행렬($W_{out}$)의 계산 -> negative sampling 

CBOW 모델

 

[Embedding 계층]

  • 어휘가 100만개, 은닉층 뉴런이 100개일 경우의 모델
  • 원핫 벡터와 가중치 행렬곱은 가중치 행렬의 특정 행만 추출하는 행위 => 필요없는 짓
  • Embedding 계층은 단어 ID에 해당하는 행을 추출하는 계층

 

 

[Embedding 계층 구현]

  • 가중치 W에서 전달받은 idx로 특정 행만 return
class Embedding:
    def __init__(self, W):
        self.params = [W]
        self.grads =[np.zeros_like[W]]
        self.idx = None

    def forward(self, idx):
        W, = self.params
        self.idx = idx
        out = W[idx]
        return out

 

  • 역전파는 가중치 기울기 dW 특정 행에만 반영

  • 중복되는 word_id를 고려해서 back-propagtation 값을 더해준다.(모두 고려하기 위해서)
    def backward(self, dout):
        dW, = self.grads
        dW[...] = 0
        
        for i, word_id in enumerate(self.idx):
            dW[word_id] += dout[i]
        
        return None

 


[word2vec 개선 2]

  • 은닉층 이후의 처리 softmax 계산처리를 negative sampling 으로 구현

 

[은닉층 이후 계산의 문제점]

  • 은닉층의 뉴련과 가중치 행렬($ W_{out} $)의 곱
  • Sotfmax 계층의 계산

$$ y_{k} = {exp(s_{k}) \over {\Sigma_{i=1}^1000000 exp (s_{i}) }}$$

 

[다중 분류에서 이진 분류로]

  • 네거티브 샘플링 : 다중 분류(multi-classification)을 이진 분류(binary-classification)으로 근사
  • 이진 분류는 단순히 Yes/No로 답하는 문제를 다룬다.
  •  

  • 출력층의 뉴런은 단 하나이다.
  • 은닉층과 출력 측의 가중치 행렬의 내적은 타깃 단어에 해당하는 열만을 추출한다.

  • 출력 측의 가중치 $ W_{out} $에서는 각 단어의 ID의 단어 벡터가 열로 저장되어 있다.
  • 해당 단어의 열벡터와 은닉층을 곱하여 점수를 계산한다.

 

[시그모이드 함수와 교차 엔트로피 오차]

  • 이진 분류 문제를 신경망으로 풀려면
    • 시그모이드 함수를 적용해 확률로 변환하고,
    • 교차 엔트로피 오차함수를 사용하여 손실을 구한다.
  • 시그모이드 함수 수식은 아래와 같다.

$$ y = {1 \over {1 + exp(-x)} }$$

  • 시그모이드 함수의 출력을 확률로 해석할 수 있다.
  • 교차 엔트로피 함수는 아래와 같다.

$$ L = -(t\logy + (1-t)\log(1-y)) $$

  • y는 시그모이드 함수의 출력이고 t는 정답이다.
  • 정답이면 (t==1) $ -t\logy $, 정답이 아니면 (t==0) $ -\log(1-y) $ 이다.

Sigmoid with loss forward / backward propagation

  • x가 loss에 영향을 미치는 정도는 y-t 이다.

 

[다중 분류에서 이진 분류로(구현)]

 

 

  • 은닉층 뉴런 h와, 출력 측의 가중치 $ W_{out} $ 에서 단어 say에 해당하는 단어 벡터와 내적을 계산한다.
class EmbeddingDot:
    def __init__(self, W):
        self.embed = Embedding(W)
        self.params = self.embed.params
        self.grads = self.embed.grads
        self.cache = None
        
    def forward(self, h, idx):
        target_W = self.embed.forward(idx)
        out = np.sum(target_W * h, axis=1)
        
        self.cache = (h, target_W)
        return out
    
    def backward(self, dout):
        h, target_W = self.cache
        dout = dout.reshape(dout.shape[0], 1)
        
        dtarget_W = dout * h
        self.embed.backward(dtarget_W)
        dh = dout * target_W
        return dh

 

[네거티브 샘플링]

  • 긍정적인 예를 타깃으로 한 경우의 손실을 구한다.
  • 동시에 부정적 예를 샘플링 하여 각 샘플에 대한 손실을 구한다.
  • 각각의 데이터의 손실을 더한 값을 최종 손실로 한다.

 

[네거티브 샘플링 기법]

  • 부정적 예를 샘플링하는 방법은 통계 데이터를 기초로 자주 나오는 단어를 샘플링한다.
  • 말뭉치에서 단어의 출현 횟수를 구해 확률 분포로 나태낸 뒤 확률 분포대로 단어를 샘플링.
  • 흔한 단어를 잘 처리하는 편이 좋은 결과로 이어질 것이다.
  • word2vec의 네거티브 샘플링에서는 아래와 같은 식을 사용한다.

$$  P'(w_{i}) = { P(w_{i})^{0.75} \over { \Sigma_{j}^{n} P(w_{j})^{0.75} } } $$

  • 사용하는 이유는 출현 확률이 낮은 단어를 버리지 않기 위해서이다.
728x90

'CS > NLP' 카테고리의 다른 글

[Hands on Python NLP] - NLP 기본의 이해  (0) 2022.10.09
[NLP] Auto Encoder (1)  (0) 2022.08.11
[NLP] Chapter3 - word2vec  (0) 2022.02.10
[NLP] Chapter 2 - 자연어  (0) 2022.02.09
[NLP] Chapter 1 - 신경망 복습  (0) 2022.02.06
Comments