questionet

word2vec 본문

Deep learning/딥러닝 학습기법

word2vec

orthanc 2021. 2. 8. 16:10

이 페이지는 밑바닥부터 시작하는 딥러닝2권의 내용을 정리한 것이다

살펴볼 주제

1 추론기반 기법(word2vec)을 쓰는 이유
2 추론기반 기법(word2vec)의 원리
3 CBOW 모델 구현해보기

 

인간이 말하고 쓰는 언어를 컴퓨터에게 이해시키는 방법

   1. 유의어사전(thesaurus)을 이용하는 방법
   2. 통계 기반 기법
   3. 추론 기반 기법 

아이디어

   분포가설(distributional hypothesis)

   단어 자체에는 의미가 없다. 
   단어의 의미는 주변 단어에 의해, 그 단어가 사용된 맥락에 의해 형성된다.

우리가 원하는 것

   = '단어의 의미'를 정확하게 파악할 수 있는 벡터 표현
   = 좋은 분산표현 distributional representation 을 얻어내는 것

 

Q1 : '단어의 의미'를 정확하게 파악할 수 있는 벡터라는 게 정확히 무슨 뜻일까? 어떤 방법들이 있을까?



왜 추론기반기법을 쓰는 것일까?

추론기반 기법은 통계기반 기법이 가진 문제를 피할 수 있다.

1. 학습 방법의 문제
추론기반 기법은 미니배치 학습이 가능하지만
통계기반 기법은 배치학습으로 이뤄진다. 여기서 문제가 생긴다.

   통계기반 기법의 문제점 

      동시발생행렬을 만들고
      PPMI를 사용해 얻어낸 단어벡터가
      아무리 좋은 분산표현을 갖는다 해도

      corpus 자체가 아주 클 때는 
      단어벡터 또한 너무나도 커져서 컴퓨터 연산에 너무 많은 시간과 자원이 소요된다.


Q2 : 말뭉치가 커지면 왜 단어벡터가 커질까?

A : 통계기반 기법에서는 모든 단어의 출현빈도를
하나의 행렬에 담은 행렬(동시발생행렬)을 가지고서
단어의 좋은 분산표현을 얻을 수 있게 하는
PPMI행렬을 구하기 때문이다.
다시 말해, 처음부터 말뭉치에 사용되는 모든 단어를
다 담고 있는 행렬을 가지고 NLP를 하기 때문에
말뭉치의 크기에 따라 단어벡터의 크기가 비례하게 된다.


A :말뭉치가 커짐에 따라 단어벡터가 커지는 것이 왜 컴퓨터 연산의 비효율을 낳을까?

1. 통계기반 기법의 핵심은 사용되는 모든 단어의
출현빈도를 하나의 행렬에 담은 행렬을 사용한다는 데 있다.
여기에 SVD를 적용하는 방법은 단 1회의 행렬곱 연산이
필요하다. 이 때 시간복잡도는 n**3 에 비례한다고 한다.

2. 애초에 SVD를 하는 이유는 말뭉치의 어휘수가
증가함에 따라 단어 벡터의 차원수도 증가하는 문제를
해결하기 위한 것이었다.
그런데 차원감소를 하기 위해서 SVD 계산을 시도할 때 
연산의 적용 대상이 되는 단어 벡터 자체가 이미 너무너무
커서 계산 시간이 n**3 에 비례할 만큼 커진다면,
수단이 목적을 전도시키는 꼴이 돼버리기 때문이다.

 

2. 분산표현의 갱신 문제

 

3. 분산표현의 차이

 

Q3. 그래서 통계기반 기법은 사장됐나? 쓰인다면 어디에 어떤 식으로 쓰이고 있을까?


추론기반 기법이란 뭘까?

위와 같은 추론 문제를 반복해서 풀면서 단어의 출현 패턴을 학습하여 출현 확률을 출력한다.
CBOW모델은 맥락으로부터 타깃을 추측하고
Skip-gram은 타깃으로부터 맥락을 추측한다

통계기반 기법에서는 말뭉치에 있는 모든 단어들에 대해서
각 단어의 맥락에 해당하는(주변에 있는) 단어의 출현 빈도를 매겨 단어의 벡터를 만든다.

그러나 추론기반기법 word2vec에서는 각 단어들을
말뭉치의 총 어휘수만큼의 원소를 갖는 벡터 안에서 원핫인코딩으로 변환한다.

즉 각 단어들은 고정길이(총 말뭉치의 크기) 벡터로 변환된다.


얼핏 보면, 1과 0으로 이뤄져 있다는 점과 전체 길이가 말뭉치의 크기와 같다는 점에서
동시발생행렬과 단어 벡터는 비슷해 보이지만
둘의 의미는 완전히 다르다.

 

                                  입력층은 1 by 7 행렬로 볼 수 있다.

 

 

 

 

 

 

 

                                                 

첫번째 단어 you를 가중치 행렬과 행렬곱을 하게 되면
그 결과는 결국 가중치 행렬의 맨 첫번째 행을 출력한 결과와 같다.
결국 7개 단어를 차례대로 연산하면,
가중치 행렬의 각 행을 차례 대로 출력하는 것과 같게 된다.
이러한 결과를 얻기 위해 행렬곱을 하는 건 비효율적이다.
이럴 거면 가중치 행렬에서 단어 ID에 해당하는 행을 바로 추출하는 게 훨씬 간단하고 빠르다
이것을 책에선 embedding 계층 이라고 부른다.
Q4. word2vec에서 말하는 embedding vector가 바로 이것인가?


CBOW 모델의 예

you와 goodbye 사이에
어떤 단어가 올 확률이 높을까?

맥락에 포함시킬 단어를 
타깃단어 주변의 한단어씩만 고려한다고 한다면
입력층은 2개가 된다.
(N개를 고려하면 입력층은 N개가 된다)

첫번째 입력으로 [1,0,0,0,0,0,0]
두번째 입력으로 [0,0,1,0,0,0,0] 을 주면

각각 가중치 행렬과 행렬곱 연산을 한 후
같은 위치에 있는 원소끼리 더한 후 2를 나눠준
평균값이 은닉층에 저장된다.
( 1 x 7 ) X ( 7 x 3 ) = ( 1 x 3 )

은닉층 뉴런에 저장된 값은 
다시 출력층으로 전달돼야 하는데
총 7개 단어 중 어떤 단어가 나와야 하는 지를     
맞춰야 하므로,                                                                                              가중치 뉴런이 단어의 분산표현이다.
출력층 뉴런으로의 변환은 3 x 7 행렬곱이 필요해진다. 
최종적으로 출력층에 넘겨진 점수에 소프트맥스 함수를 적용해
확률은을 얻는다.

핵심은 은닉층의 뉴런 수를 입력층의 뉴런 수보다 작게 하는 것이다.
그래야 은닉층에 단어 예측에 필요한 정보가 간결하게 담기게 되기 때문이다.

입력층과 행렬곱 연산이 이뤄지는 가중치 행렬은 모든 입력층에 똑같이 공유된다.

가중치 행렬은 순전파와 역전파를 거듭하며 단어의 출현 패턴을 학습한다.

CBOW 모델은 활성화 함수를 사용하지 않는다.

CBOW 모델은 단어 출현패턴을 학습 시에 사용한 말뭉치로부터 배운다.
따라서 말뭉치가 다르면 분산표현도 달라진다.

Q5. 몇몇의 특정 주제, 혹은 여러 주제 수준이 아닌 '모든' 주제, 분야의 말뭉치를 학습한 NLP모델이 가능할까?
그것이 의미하는 게 뭘까?
(이루다 사건과 관련하여, 나아가 그 너머를 그려보며)

 

Q6.
이게 전부인가?
그냥 이렇게만 해도 정말 단어의 좋은 분산표현을 얻어낼 수 있단 말인가?
단순히 신경망 구조를 쓰는 것만으로?

A :
"지금까지의 실험에 의해 word2vec 모델로 얻을 수 있는 단어의 분산표현은
단어의 의미 면에서나 문법 면에서 모두
우리의 직관에 부합하는 경우를 많이 볼 수 있습니다"

word2vec 에서 사용하는 신경망에는
가중치 행렬이 두 개가 있다.
하나는 입력층 쪽 가중치 행렬
다른 하나는 출력층 쪽 가중치 행렬

그렇다면 단어의 분산표현으로 쓸 임베딩 벡터는 무엇으로 하면 좋을까?

책에서는 특히 skip-gram모델이 경우 입력층 쪽 가중치 행렬을 가장 많이 사용한다고 한다.



CBOW 모델 구현해보기

책에서는 다중 클래스 분류를 수행하는 신경망을 만들고자 한다.
소프트맥스 함수를 이용해 점수를 확률로 변환하고
그 확률과 정답 레이블로부터 교차 엔트로피를 구한 후
그 값을 손실로 사용해 학습을 진행하는 모델을 구성한다.

 

1. 맥락과 타깃 만들기

각 샘플 데이터에서 맥락의 수는 여러 개가 될 수 있으나
당연하게도 타깃은 오직 하나뿐이다. 그래서 맥락을 영어로 쓸 때는 's'를 붙여준다.

Q7. 타깃이 두 개 이상일 수는 없나?

말뭉치 단어에 인덱싱을 해주고 아래와 같은 배열을 반환하는 함수를 코딩한다

인덱싱 값들을 다시 원핫 인코딩해준다

맥락 단어 두 개가 하나의 벡터에 paring 되었던 것이
원핫인코딩을 하면
두 차원의 벡터로 나뉘어 저장된다.

Comments