for textmining

Neural Probabilistic Language Model

|

이번 포스팅에선 단어의 분산표상(distributed representation) 방식 가운데 하나인 Neural Probabilistic Language Model(NPLM)에 대해 살펴보도록 하겠습니다. NPLM은 Bengio(2003)에서 제안된 모델인데요, 단어를 벡터로 바꾸는 뉴럴네트워크 기반 방법론으로 주목을 받았습니다. 이번 글은 고려대 강필성 교수님 강의와 네이버랩스 박은정 박사의 발표원고를 바탕으로 정리했음을 먼저 밝힙니다. 자 그럼 시작해볼까요?

Distributed representation

컴퓨터에게 단어를 가르쳐 주려면 어떻게 해야 할까요? 참으로 어려운 문제이지요. 컴퓨터는 그저 사칙연산 수행을 잘 하는 계산기일 뿐이니까요. 단어를 숫자로 바꿔서 입력해야 컴퓨터는 그제야 연산을 수행할 수 있습니다. 대표적인 방법론이 바로 one-hot-encoding입니다. ‘코끼리’, ‘사자’, ‘뱀’ 세 개 단어로 이뤄진 사전이 있다고 쳐보겠습니다. 이걸 one-hot-vector로 표현(representation)하면 아래와 같습니다.

코끼리 : [1, 0, 0]

사자 : [0, 1, 0]

: [0, 0, 1]

one-hot-vector는 가장 간단하고 직관적인 표현법입니다. 어떤 단어가 해당하는 요소만 1이고 나머지는 0으로 채워 넣으면 끝입니다. 그런데 사전에 등재된 단어 수가 100개, 1000개 이렇게 늘어난다면 어떻게 될까요? 각각의 단어 벡터들은 100차원, 1000차원을 갖게 될 겁니다. 실제 대다수 자연어들은 단어 수가 10만개 안팎이기 때문에 한 언어의 모든 단어들을 one-hot-vector로 바꾸면 그 차원수가 어마어마하게 클 겁니다. 이런 큰 차원의 벡터는 제 아무리 뛰어난 성능을 가진 컴퓨터라도 메모리 등 문제 때문에 계산복잡성이 크게 늘어나게 되겠죠. 게다가 이 벡터들은 딱 하나의 요소만 1이고 나머지는 모두 0인 sparse vector 형태를 갖습니다.

one-hot-vector의 단점은 또 있습니다. 바로 두 단어의 내적(inner product)이 0입니다. 위 예시에서 코끼리라는 단어 벡터([1, 0, 0])와 사자 벡터([0, 1, 0])를 내적하면 0이 된다는 사실을 알 수 있습니다. 길이가 1인 두 벡터의 내적은 두 벡터 사이의 각도(cosine)가 되므로 내적값이 0이라는 말은 두 벡터가 직교(orthogonal)한다는 의미인데요, 이를 확장해서 생각해보면 모든 one-hot-vector는 서로 독립(independent)이라는 사실 또한 추론해낼 수 있습니다. 하지만 현실에서는 단어들끼리 관련성이 전혀 없는 건 아닙니다. 유의어, 반의어 같이 단어들은 다른 단어들과 의미적으로 특정한 관계를 맺고 있거든요. 이러한 문제를 해결하기 위해 등장한 개념이 바로 분산표상(distributed representations)이라고 보시면 될 것 같습니다.

\[W\in { R }^{ \left| V \right| }\quad \rightarrow \quad W\in { R }^{ n }\\ n<<\left| V \right|\]

분산표상이 추구하는 바는 위 식과 같습니다. W는 단어벡터를 의미하는데요, one-hot-vector의 차원수는 사전의 전체 단어수(V)입니다. 이를 V보다 훨씬 작은 n차원 벡터로 바꿔보자는 것입니다. one-hot-vector는 그 요소가 0 혹은 1인 binary 구조이지만, 분산표상으로 표현된 단어벡터의 요소는 연속형의 실수값입니다. 듬성듬성한(sparse) 벡터를 빽빽한(dense) 벡터로 바꿔 표현한 것이라고 이해해도 좋을 것 같습니다. 뭔가 알 수 있을듯 없을듯 하지요? 분산표상을 그림으로 이해해보겠습니다.

왼쪽 그림을 보시면 총 9개 개체가 있습니다. 이를 one-hot-vector로 표현한다면 9차원짜리 벡터 9개가 나올 겁니다. 그런데 자세히 보면 9개 그림은 2개의 속성, 즉 색상(color)과 모양(shape)으로 설명할 수가 있겠네요. 즉 녹색이면서 해 모양이라면 첫번째 개체라는 걸 특정할 수가 있습니다. 그렇다면 9개 개체는 [색상, 모양]이라는 2차원짜리 벡터로도 충분히 표현할 수가 있습니다. 이것이 바로 분산표상 개념입니다.

분산표상은 데이터의 차원수를 줄이려는 것이 1차적 목적이지만, 그 효과는 실로 대단합니다. 위 예시처럼 색상이나 모양 기준으로 개체간 유사성을 잴 수 있듯이, 단어 벡터도 그 요소값이 연속적이기 때문에 단어 벡터 간에 거리나 유사도를 잴 수가 있게 됩니다. 의미가 유사한 단어는 벡터공간에서 가깝게, 반대의 경우는 멀게 배치하는 것이 분산표상의 목표입니다. 바로 아래 그림처럼요.

Neural Probabilistic Language Model 개요

NPLM은 단어들의 연쇄가 주어졌을 때 다음 단어가 무엇인지 맞추는 과정에서 분산표상된 단어벡터들을 만드는 방법론입니다. 뭔가 알쏭달쏭하죠? 한번 예를 들어 보겠습니다.

발 없는 말이 천리 __

위와 같이 ‘발’, ‘없는’, ‘말이’, ‘천리’ 네 개 단어가 주어졌다고 합시다. 그 다음에 올 단어는 무엇일까요? 수많은 동사가 올 수 있겠지만 ‘간다’라는 단어가 등장할 확률이 높을 겁니다. 우리는 ‘발 없는 말이 천리 간다’는 속담을 자주 쓰는 편이니까요. 이를 수식으로 쓰면 아래와 같습니다.

\[P({ w }_{ t }|{ w }_{ t-1 },...,{ w }_{ t-n+1 })=\frac { exp({ y }_{ { w }_{ t } }) }{ \sum _{ i }^{ }{ exp({ y }_{ i }) } }\]

NPLM은 위 식의 조건부확률을 최대화하는 방향으로 학습을 하게 됩니다. 즉, $P(간다$|$발,없는,말이,천리)$를 높이고 싶은거죠. 바꿔 말하면 ‘발’, ‘없는’, ‘말이’, ‘천리’ 네 개 단어로 ‘간다’를 맞추자는 겁니다. 이처럼 NNLM은 직전까지 등장한 $n-1$개 단어들로 $n$번째 단어를 맞추는 N-gram 모델이 그 본질입니다.

NPLM의 입출력

다음 값을 최대화하려면 우변의 분자는 키우고 분모는 줄여야할 겁니다.

\[P({ w }_{ t }|{ w }_{ t-1 },...,{ w }_{ t-n+1 })=\frac { exp({ y }_{ { w }_{ t } }) }{ \sum _{ i }^{ }{ exp({ y }_{ i }) } }\]

$y_{w_t}$는 $w_t$라는 단어에 해당하는 점수 벡터입니다. 그 크기는 말뭉치 전체의 단어수($V$)에 해당하는 차원을 가졌습다. 만약 $V$가 3이라면 $y_{w_t}$는 $[1.2, 3.4, 2.1]$ 이런 식의 벡터가 됩니다.

NNLM 구조 말단의 출력은 $V$차원의 스코어 벡터 $y_{w_t}$에 소프트맥스 함수를 적용한 $V$차원의 확률 벡터입니다. NNLM은 확률값이 가장 높은 요소의 인덱스에 해당하는 단어가 실제 정답 단어와 일치하도록 학습을 진행하게 됩니다.

요컨대 정답 인덱스에 해당하는 스코어(분자)를 높이고, 나머지 인덱스에 해당하는 스코어(분모)는 낮춰야 위 식에 정의된 조건부확률을 높일 수 있습니다.

모델의 출력을 알아봤으니 이번엔 입력벡터 $x_t$를 만드는 과정을 살펴보겠습니다. 다음 식과 같습니다.

\[{ x }_{ t }=C\cdot { w }_{ t }\]

우선 $m$ x |$V$| 크기를 갖는 커다란 매트릭스를 우선 만듭니다. $m$은 $x_t$의 차원수로, $C$의 모든 요소 값은 초기에 랜덤 설정합니다. $w_t$는 $t$번째 단어에 대한 One-hot-Vector입니다. $t$번째 요소만 1이고 나머지는 0인 벡터이죠. $C$와 $w_t$의 내적은 $C$라는 행렬에서 $t$번째 열만 참조(lookup)하는 것과 본질적으로 같습니다.

NPLM의 구조

이번엔 NPLM 구조를 전체적으로 살펴보겠습니다.

입력부터 천천히 살펴보겠습니다. 처음 말씀드렸던 것처럼 우리는 ‘발’, ‘없는’, ‘말이’, ‘천리’ 이렇게 네 개 단어가 주어졌을 때 ‘간다’라는 단어를 예측하고 싶은 겁니다. 우선 네 개의 각각의 단어에 해당하는 인덱스값을 불러옵니다. 이 인덱스에 해당하는 $C$ 행렬의 열벡터를 불러옵니다. 이렇게 네 개 단어에 해당하는 열벡터를 $C$에서 참조해 묶어주면 $x_t$가 됩니다.

입력층(Input Layer)에서 은닉층(Hidden Layer)을 거쳐 출력층(Output Layer)으로 보내는 연산은 다음과 같습니다. 우선 $x_t$와 $H$를 내적한 뒤 bias term ‘d’를 더해 은닉층을 만듭니다. 여기에 $U$를 내적한 뒤 bias term $b$를 더해주면 스코어벡터 $y_{w_t}$가 나오게 됩니다.

\[{ y }_{ { w }_{ t } }=b+U\cdot tanh(d+H{ x }_{ t })\]

마지막으로 $y_{w_t}$에 소프트맥스 함수를 적용한 뒤 이를 정답 단어인 ‘간다’의 인덱스와 비교해 역전파(backpropagation)하는 방식으로 학습이 이루어지게 됩니다.

NPLM의 학습 parameter

NPLM의 parameter 차원수는 아래와 같습니다.

\[H\in { R }^{ h\times (n-1)m },\quad { x }_{ t }\in { R }^{ (n-1)\times m },\quad d\in { R }^{ h\times 1 }\\ U\in { R }^{ |V|\times h },\quad b\in { R }^{ |V| },\quad y\in { R }^{ |V| }\quad,C\in{R}^{m\times|V|}\]

$x_t$는 모델이 예측해야 하는 마지막 단어를 제외한 $n-1$개의 $m$차원 단어 벡터들입니다. 여기에 입력층에서 은닉층으로 보내주는 가중치 매트릭스 $H$를 곱하면 은닉층은 사용자가 지정하는 $h$차원 벡터가 됩니다. 여기에 같은 차원의 bias 벡터 $d$를 더해주고, 이후 은닉층에서 출력층으로 보내주는 가중치 매트릭스 $U$를 내적한 뒤 bias 벡터 $b$를 더해주면 말뭉치 단어 개수인 $V$차원의 스코어 벡터가 생성되는 구조입니다.

마치며

NPLM의 최종 목적은 단어벡터들의 모음이기도 한 $C$를 얻어내는 데 있습니다. 직전 $n-1$개 단어들이 주어졌을 때 마지막 $n$번째 단어를 맞추는 데 최적화된 단어벡터들의 모음이 바로 단어를 분산표상으로 임베딩한 결과물이라는 것이죠. 다만 NPLM은 C외에 H, U, b, d 등 다른 파라메터들도 업데이트해야 하기 때문에 계산복잡성이 높습니다. 이러한 문제점을 극복하기 위해 학습파라메터를 확 줄이는 방향으로 제안된 모델이 바로 최근 각광받고 있는 Word2Vec입니다.



Comments