Word2Vec 개념 & 실습 Tutorial - 이론편
Word2Vec, Glove, FastText 등등의 단어 표현들은
NLP를 공부한다고 할 때 가장 기초적으로 공부하는 개념, 그야말로 기본 중의 기본 개념이다.
사실 너무너무 많이 듣다보니 개념만 대충 듣고 아 그런가보다~ 하고 넘어가기 쉬운데
실제 현업에서는 아직도 이 임베딩을 가져다 쓸 때가 많기 때문에 꼭 실습을 해봐야한다.
요 며칠간 이것들을 이용해서 Text Generation 코드를 짜야했는데, 우습게 봤다가 아주 큰코 다쳤다ㅋㅋ
큰 코 다친 김에, 알고 있던 이론에 실습으로 배운 것을 곁들여 정리해본다.
내가 잘 이해하지 못한 부분도 있겠지만,
사실 이론은 그냥 대충 할머니 옛날 얘기 듣는 바이브로 이해만 하고, 실습을 빡세게 하는 것이 최고인 것 같다.
그래서 이론은 최대한 쉽게 재미있게 설명하고, 실습은 최대한 상세하게 설명하겠다.
Index
[이론]
Word2Vec이 무엇인가?
왜 Word를 Vector로 만들까?
Word2Vec의 조상님, One hot vector
Word2Vec, GloVe, FastText
Word2Vec 손자(?), BERT와 GPT2
[실습]
케라스로 Word2Vec 사전 학습 가중치 이용하여 단어 생성 LSTM 모델 만들기
Word2Vec 사전 학습 가중치 준비하기
훈련 데이터에서 Vocabulary 구축하고 Embedding Matrix 만들기
Keras Embedding Layer에 사전 학습 가중치 로드하기
텐서 쉐입 체크하기 & 모델 컴파일
모델이 잘 되는지 확인해보자
Word2Vec이 무엇인가?
Word2Vec은 2013년 구글이 제안한 단어 표현 생성 모델이다.
말 그대로 단어 표현을 생성하는 것을 목표로 하는 딥러닝 모델!
"포카칩 맛있어" ---> Word2Vec ---> [[0.23, -0.5, 0.12, 0.54, 0.67], [0.12, -0.76, 0.4, 0.76, -0.1]]
왜 Word를 Vector로 만들까?
NLP에 익숙하지 않은 사람들은 '단어 표현'이라는 표현 자체에 낯설음을 느낄 것이다.
NLP 분야에서 단어 표현이라함은, 영어로 Word Representation라고 부른다.
단어 자체가 Representation인데 왜 굳이 단어 뒤에 '표현'을 또 붙여주는걸까?
바로 컴퓨터가 처리할 수 있는 형식으로 바꿔주었다는 것을 이야기 하기 때문이다.
즉 바보 컴퓨터가 사람 말을 이해하게 하려면, 숫자로 일단 바꿔줘야 한다는 것이다.
근데 그냥 숫자 하나만 주면 너무 정보가 적기 때문에, 여러 숫자(Vector)를 주겠다는 것이다.
그래서 단어 표현이란, 예를 들어 자연어 '포카칩'에 대한 단어 표현(Word Representation)이라는 건, '포카칩'을 어떤 변환식에 따라 산출한 벡터를 가리키는 것이다.
이 '포카칩'을 어떻게 숫자로 만들 것인가에 대한 논의를 하는 학문 분야가 바로 'Word Representation' 분야이다.
이 학문 분야에서는
야 얘드라 .. '포카칩'을 무슨 무슨 변환식에 따라 바꿨더니 컴퓨터가 언어를 잘 이해하는 거 같아!!
가 주요 관심사이다.
Word2Vec은 그 분야의 논문 중 하나에서 제안한 모델이고 말이다.
물론 Word2Vec 이전에도, '포카칩'을 어떻게 숫자로 만들어야 잘 만들었다고 소문이 날까에 대한 고민이 있어 왔다.
많은 사람들이 그 머리수 만큼 많은 방법을 제안했지만 가장 많이 쓰이던 것은 One hot vector 표현 방식이었다.
Word2Vec의 조상님, One hot Vector
One hot vector는 또 뭘까.
이름을 잘 뜯어보자.
일단 Vector이다. 숫자가 여러개라는 소리다.
[0.12556, 0.3412, 0.5422, 0.6756, 0.2512]
그런데 이 벡터가 One hot이란다. 한개가 핫하다고 한다.
hot & cold의 hot일 것 같다.
hot과 cold는
high와 low고
5V와 0V이고
0과 1이다.
즉, 여러 숫자(벡터) 중에 하나만(원) hot = high = 5V = 1(핫) 이다.
[0, 0, 0, 0, 1]
여러 개 중에 한 개만 핫하다는 건데.
이 여러개가 정확히 몇개냐면 사전에 기재된 단어 수이다.
따라서 정리하면,
사전에 있는 단어 목록 중에 표현하고 싶은 한 단어를 강조 표시 한 것이 one hot vector이다.
이 때 "사전"이라 함은, 우리가 아는 모든 단어를 전부 담고 있는 대국어사전이 아니다.
마음같아선 컴퓨터에 국어대사전에 있는 단어 몇백만개를 한번에 갖다 넣고 싶지만,
컴퓨터에는 한계가 있고 그렇게 계산하면 너무 비효율적이기 때문이다.
그래서 프로그래머한테, 너 무슨 무슨 단어 쓸거니? 한 몇만개만 골라서 목록 만들어서 단어 표현해. 라고 하는 것이다.
그래서 단어사전, 주로 Vocabulary 또는 Corpus라고 하는데,
이것은 이용하는 데이터셋 또는 도메인마다 달라지게 된다.
예를 들어 의학 분야의 언어를 이해하는 모델을 만들고싶다면, 의학 코퍼스 즉 의학 전문용어 위주로 학습시켜야 할 것이다.
그래서 정리하면, one hot vector는 사전 길이 만큼의 영벡터에, 표현하고자 하는 단어의 위치에 1을 표현해서 단어를 표현해 준 것을 말한다!
알고보면 굉장히 간단하고, 솔직히 이게 뭔가 싶지 않은가?
사전도 분야마다 달라지고, 단어 위치도 프로그래머가 어떻게 정의하느냐에 따라 달라질텐데..
기껏해야 '사전 내의 순서 표시' 정도의 정보로 컴퓨터가 단어의 풍부한 의미를 어떻게 학습한다는걸까?
Word2Vec, GloVe, FastText
많은 학자들도 그렇게 생각했다.
one hot vector는 단어의 의미 표현이라기보다는 최소한 컴퓨터가 알아듣기 쉬운 포맷을 정의하기 위한 초석에 가깝다.
이 one hot vector를 휘뚜루 마뚜루 지지고 볶아서 단어 의미를 풍부하게 담도록 하면 된다.
그래서 학자들은 단어의 의미를 어떻게 정량화할 수 있는지 고민하기 시작했다.
'포카칩'이,
'ㅍ,ㅗ,ㅋ,ㅏ,ㅊ,ㅣ,ㅂ'을 붙여 쓴 이 글자 덩어리가
오리지널 맛이 가장 맛있는 오리온 감자칩을 뜻하게 하는 가장 중요한 요소는 무엇일까?
다시 말해, 한 단어가 그 의미를 가지게 하는 가장 중요한 요소는 무엇일까?
어떤 사람은 문맥이라고 생각했고 어떤 사람은 단어 사이의 연관성이라고 생각했다.
뭐라고 생각했든 사실 프로그래머 입장에서는 별로 중요하지 않다! 그냥 대충 그런 고민이 있었고 다양한 방법이 나왔겠구나 라고 알면 된다.
그래서 Word2Vec, GloVe, FastText라는 각각의 방법론이 나오게 되었다. (갑자기??)
위의 세가지 모델은 전부 one hot vector를 어떤 변환식으로 계산해서 더 작은 벡터로 만드는 것을 목표로 한다.
왜 더 작은 벡터를 만들고 싶었을까?
one hot vector의 한 가지 문제점은, 사전 단어 목록이 커질수록 계산량이 엄청나게 증가한다는 것이었다.
예를 들어, 사전 단어 목록 개수가 500개 일 때와 5만개 일때를 비교해보자.
똑같은 "포카칩"을 표현하는 데, 첫번째 경우에는 벡터 길이가 500이고 두번째 경우에는 벡터 길이가 5만이다.
단어 하나당 5만개짜리 벡터를 연산할려면, 엄청난 리소스가 낭비될 것이다.
그래서 이 one hot vector의 길이를 좀 줄여보겠다는 것이다.
이 때, 그냥 줄여서는 이 작은 벡터가 제대로 계산된 것인지 아닌지 알 수 없다.
반드시 검산을 해보아야 한다.
만약 이 작은 벡터가 또 다른 계산식을 거쳐 원래의 one hot vector로 다시 돌아올 수 있다면 그 작은 벡터는 one hot vector의 축소표현이라고 할 수 있을 것이다.
주로 이 작은 벡터(dense representation)를, 큰 벡터(sparse representation)와 구분하여 Word Embedding이라고 부른다.
이 때
큰 벡터 = sparse representation = one hot vector
라고 봐도 무방하다.
희소벡터라고 하는 이유는, 1이 한개밖에 없고 나머지는 휑~하니 다 0이라서 그렇다.
반대로 밀집벡터는 0이 아닌 숫자들이 빽빽히 차있다. 이것이 Word Embedding이다.
자 다시 돌아와서,
위에서 설명한 것 처럼 one hot vector를 차원축소 했다가 다시 원래대로 돌려놔야 한다.
이처럼 원래의 입력을 똑같이 복구하는 것을 목표로 하는 모델이 마침 있었으니, 그것의 이름이 오토인코더였다.
이 오토인코더를 기반으로 단어 표현을 학습하는 방법론이 각각 Word2Vec, GloVe, FastText인 것이다.
Word2Vec, GloVe, FastText가 오토인코더인 것은 아니며,
정확히 말하면 이 모델들은 오토인코더로 연산이 가능한 단어의 중간 표현, 즉 작은 벡터를 산출하는 것이 목표이다.
세가지 모델의 차이점은 어떤 비선형 변환식을 사용했느냐 인데, 이건 정말 정말 관심있는 분들은 공식 가이드 문서를 참조하시면 된다.
아닌 사람들은 그냥 어떻게 쓰는지만 알면 된다.
셋 중에 사전이 가장 큰 것이 Word2Vec이고, 따라서 성능도 Word2Vec이 가장 좋다.
각각 특징이 조금씩 다르긴 하지만, 여기선 생략하겠다.
Word2Vec의 손자, GPT2와 BERT
NLP를 공부하는 사람이라면 트랜스포머라는 말을 한번쯤 들어보았을 것이다.
2017년경 혜성처럼 등장해서 NLP 분야에 지각변동을 일으킨 트랜스포머는 구글사에서 제안한 신경망 레이어 구조이다.
시계열 데이터 처리의 지난한 문제였던 sequential processing, 즉 앞 단어 처리가 끝나기 전까지는 뒷 단어 처리를 못하는 순차연산의 속도 문제를 획기적으로 해결하였다고 평가받는다.
BERT 와 GPT2는 이 Transformer를 이용하여 구성한 언어모델이다.
사실 얘들을 공부할 때 가장 이해가 잘 안되었다.
뭐 attention을 사용했니, Transformer가 어쩌니,
언어모델이니 하는 소리를 다 듣고, 다 뜯어 보고도,
그래서 이게 뭔데?
라는 질문에 답이 나오지 않아 답답했다.
그런데 이번에 Word Embedding을 다시 공부하면서 BERT와 GPT2를 또 다른 시각으로 바라보며 이해도를 조금 높일 수 있게 되었다.
BERT와 GPT2는 한마디로 말하면,
Word2Vec이랑 비슷하지만 문맥 표현을 더한 다용도 언어모델
이라고 할 수 있다.
우선 언어모델이란, 문맥을 고려한 언어 표현을 학습하는 것을 목표로 하는 모델이다.
위에서 비슷한 정의를 본 것 같지 않은가?
Word2Vec, GloVe, Fasttext는 단어 표현이다. 단어 표현은 단어를 표현하는 형식이다.
언어와 단어라는 차이가 있지만, 둘다 언어를 숫자표현으로 나타내려는 노력에서 제안된 방법론이다.
언어모델은 그 중에서도 문장또는 단어 내의 연속적인 분포(문맥)까지 학습하겠다는 것이 그 차이점이라고 할 수 있다.
대표적으로 꼽히는 차이점은, 아래 예시를 들 수 있다.
1. 배가 아프다
2. 배가 맛있다
위 두 문장의 '배'에 대하여, Word2Vec은 단어와 임베딩이 1:1 대응이 되기 때문에 '배'라는 표현을 똑같은 벡터로 표현한다.
그러나 BERT는, 문맥을 고려하여 서로 다른 벡터 표현이 생기게 된다.
이제 문맥은 무슨 뜻인지 알았으니, 왜 다용도 모델이라는 건지 알아보자.
BERT가 처음 소개되었을 때, 주 사용법은 finetuning이라는 전이학습 방식이었다.
BERT라는 커다란 언어모델의 지식을 작은 모델로 전이해서 학습시키겠다는 것이다.
좀 더 구체적으로 말하면 finetuning이란, BERT라는 거대한 신경망 위에 layer 하나를 올려 3~4번 정도만 학습해주는 방식이다.
이렇게 하면, 단어 분류, 문장 분류, QnA, 개체명인식 등 다양한 분야에 활용할 수 있다!
이게 가능한 이유는, 장작을 무작정 패다보면 힘이 세져서 물도 잘 푸고 나무도 잘 베게 되는 원리와 같다.
Word2Vec도, 단어를 표현할 수 있기만 하면 여러 분야에서 활용할 수 있다는 점에서 다용도라고 할 수 있다.
사실 다용도라기에도 좀 민망하다. 단어를 여러 분야에서 쓰는 것이 당연한데 그걸 굳이 다용도라고 명명할 수 있을까.
하지만 BERT의 경우 언어모델이라는 개념이 생소하기도 하고 소개될 당시 finetuning이라는 방법을 공식 논문에서 제안했기 때문에 이렇게 전이학습을 하는 방식이 표준이 되었다.
그런데 사실 BERT에서 Word Embedding만 뽑아내어 사용하는 것도 가능하다!
완전히 Word2Vec의 대체품으로 사용해볼 수도 있는 것이다.
궁금하신 분들은 BERT embedding을 검색해보면 된다.
BERT에서 Word embedding을 뽑아내는 것보다, GPT2 에서 Word embedding을 뽑아내는 것이 단어 생성 문제에서 더 효과가 좋다고 알려져있는데, 이를 한번 직접 실험해보고 성능을 비교하는 것도 재미있는 주제가 될 것 같다.
이렇게 해서 이론편은 Word2Vec을 이용하기 위해 필요한 기본적인 지식과 흐름을 살펴보는 시간을 가졌다.
Word2Vec에 관해서는 사실 이정도만 이해를 한다면, 내가 지금 뭘 하고 있는지에 대한 확신을 충분히 가질 수 있다고 생각한다.
다음편은, Word2Vec을 이용해서 할 수 있는 무수한 활용 중에서도 Word Generation 문제를 해결하는 과정을 살펴보고자 한다.