attention에 대해 이해하고 싶어져서 nlp를 공부하게 되었다.

단어의 분산 표현

단어의 의미를 컴퓨터가 이해하도록 표현하는 것. 여기서 단어의 의미는 주변 단어에 의해 형성된다는 가설을 가지고 접근했다.

1. 통계 기반 기법

1회학습, 단어의 유사성 인코딩

  • 동시 발생 행렬 : window 안에서 동시에 발생하는 단어를 count하는 행렬

  • PMI : the와 같이 빈도가 높은 단어는 자주 동시에 발생한다고 해도 유사도가 낮다고 볼 수 있다.

    $log_2(\frac{P(x,y)}{P(x)P(y)})$

  • PPMI : log를 취하게 때문에 -$\infty$가 될 수 있음

    max(0, PMI(x,y))

차원 축소

  1. 특잇값 분해(SVD)

    $X=USV^{T}$ (U,V : 직교 행렬, S : singular value로 된 대각행렬)

    여기서 U 행렬은 단어 공간으로 취급될 수 있다. 행벡터 형태로 단어가 표현된다.

    S 행렬은 대각 성분에 특이값 singular value가 있다. 이것은 해당 축의 중요도를 의미하는데, 중요도가 낮은 것은 지워도 된다. S 행렬의 원소를 지우면서 단어공간을 의미하는 U 행렬도 축소할 수 있다.

  2. 특이값이 작다면 U에서 열벡터 삭제

2. 추론 기반 기법

맥락으로 부터 타깃을 추측

여러번 학습, 새로운 단어 추가 쉬움, 단어의 유사성과 단어 사이의 패턴 인코딩

  1. CBOW : 주변 단어들을 입력으로 중간에 있는 단어들을 예측, 학습 속도 빠름
  • input
  • hidden = $W_{in}$ * input
  • output = $W_{out}$ * hidden
  • output -> softmax -> cross entropy error
    • $W_{in}$ : 각 단어의 분산 표현,
    • $W_{out}$ : 단어의 의미가 인코딩 된 벡터
  1. skip-gram : 중간에 있는 단어들을 입력으로 주변 단어들을 예측, 성능 좋음

CBOW의 속도 개선

어휘 수가 많아지면 계산량도 커진다. 속도 개선을 위해 아래와 같은 방법을 사용했다.

1. Embedding

  • 1 hot 벡터에 $W_{in}$을 곱하는 것에서 생기는 속도 지연을 개선
  • 1 hot으로 바꿀 필요 없이 $W_{in}$의 특정 행을 출력하면 된다.
  • dh를 구하고 각 행의 값을 idx가 가리키는 장소에 더하기 (아직 이유를 이해하지 못했다.)

2. negative sampling

  • 다중 분류를 이중 분류로 근사, sigmoid -> cross entropy error
  • 정답에 해당하는 추론 값만 사용해서 loss 계산
  • 부정적인 예는 샘플링 해서 loss 계산
  • 샘플링 방법
    • 각 단어의 출현 횟수로 확률 분포를 구해 샘플링
    • np.random.choice 함수 사용
    • 이때 각 확률 분포에 0.75 제곱을 권함(∵ 출현확률이 낮아도 버리지 않으려고)