혜온의 이것저것

[Chapter 3 word2vec] 1 추론 기반 기법과 신경망 본문

Deep Learning/밑바닥부터 시작하는 딥러닝2

[Chapter 3 word2vec] 1 추론 기반 기법과 신경망

혜온 :) 2022. 3. 24. 10:54

3.1.1 통계 기반 기법의 문제점

통계 기반 기법에서는 주변 단어의 빈도를 기초로 단어를 표현했다. 단어의 동시발생 행렬을 만들고 그 행렬에 SVD를 적용하여 밀집벡터를 얻었다. 하지만 이 방식은 대규모 말뭉치를 다룰 때 문제가 발생한다.

 

통계 기반 기법은 말뭉치 전체의 통계를 이용해 단 1회의 처리만에 단어의 분산 표현을 얻는다.

추론 기반 기법에서는 신경망을 이용하는 경우 미니배치로 학습한다.

통계 기반 기법은 학습 데이터를 한꺼번에 처리한다. 이에 반해 추론 기반 기법은 학습 데이터의 일부를 사용하여 순차적으로 학습한다. 이 말은 말뭉치의 어휘 수가 많아 SVD 등 계산량이 큰 작업을 처리하기 어려운 경우에도 신경망을 학습시킬 수 있다는 뜻이다.

여러 머신과 여러 GPU를 이용한 병렬 계산도 가능해져서 학습 속도를 높일 수 있다.

 

3.1.2 추론 기반 기법 개요

추론 기반 기법은 추론이 주된 작업이다. 추론이란 주변 단어(맥락)가 주어졌을 때 빈칸에 무슨 단어가 들어가는지 추측하는 작업이다.

추론 문제를 풀고 학습하는 것이 추론 기반 기법이 다루는 문제이다. 이러한 추론 문제를 반복해서 풀면서 단어의 출현 패턴을 학습한다.

추론 기반 기법에는 어떠한 모델이 등장한다. 우리는 이 모델로 신경망을 사용한다. 모델은 맥략 정보를 입력받아 각 단어의 출현 확률을 출력한다. 이러한 틀 안에서 말뭉치를 사용해 모델이 올바른 추측을 내놓도록 학습시킨다. 그리고 그 학습의 결과로 단어의 분산 표현을 얻는 것이 추론 기반 기법의 전체 그림이다. 

 

3.1.3 신경망에서의 단어 처리

지금부터 신경망을 이용해 '단어'를 처리한다.

신경망은 'you'와 'say'등의 단어를 있는 그대로 처리할 수 없으니 단어를 고정 길이의 벡터로 변환해야 한다. 이때 사용하는 대표적인 방법이 단어를 one-hot벡터로 변환하는 것이다.

 

'You say goodbye and I say hello.'라는 한 문장짜리 말뭉치에는 어휘가 총 7개 등장한다.

이중 두 단어의 원핫 표현을 나타내면 다음과 같다.

단어는 텍스트, 단어ID, 원핫표현 형태로 나타낼 수 있다.

총 어휘 수만큼의 원소를 갖는 벡터를 준비하고, 인덱스가 단어 ID와 같은 원소를 1로, 나머지는 0으로 설정하면 원핫 표현으로 변환할 수 있다.

이처럼 단어를 고정 길이 벡터로 변환하면 우리 신경망의 입력층은 뉴런의 수를 고정할 수 있다.

입력층의 뉴련은 총 7개이다. 이 7개의 뉴런은 차례로 7개의 단어들에 대응한다.

 

단어를 벡터로 나타낼 수 있고, 신경망을 구성하는 계층들은 벡터를 처리할 수 있다. 다시 말해, 단어를 신경망으로 처리할 수 있다는 뜻이다.

신경망은 완전연결계층이므로 각각의 노드가 이웃 층의 모든 노드와 화살표로 연결되어 있다. 이 화살표에는 가중치(매개변수)가 존재하여, 입력층 뉴련과의 가중합이 은닉층 뉴런이 된다.

 

지금의 완전연결계층에 의한 변환은 파이썬으로도 다음과 같이 작성할 수 있다.

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인 단어를 원핫 표현으로 표현한 다음 완전연결계층을 통과시켜 변환하는 모습을 보여준다.

 

c는 원핫표현이므로 단어ID에 대응하는 원소만 1이고 그 외에는 0인 벡터이다. 따라서 앞 코드의 c와 W의 행렬곱은 결국 가중치의 헹벡터 하나를 뽑아낸 것과 같다.

그저 가중치로부터 행벡터를 뽑아낼 뿐인데 행렬 곱을 계산하는 건 비효율적이라고 생각할 수 있다. 이 것은 4.1에서 개선할 예정이다.

 

앞의 코드로 수행한 작업은 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]]

 

Comments