Transformers
Seq2Seq에서 RNN을 아예 빼버리고 attention으로 구성해보면 어떨까? → Transformer의 구조 현재는 seq2seq + attention에서는 하나의 벡터로…
2025/04/27
Jinsoolve.
Categories
Tags
4월 안에는 꼭...
About
저번에 word vector에 대해서 알아봤는데, 이번에는 word vector의 프레임워크인 Word2Vec에 대해서 좀 더 알아보자.
먼저 Word2Vec이 어떤 식으로 동작하는 지 가볍게 살펴보자.
각 단어당 2개의 벡터가 있었는데 outside(context)와 center에서의 벡터가 각각 있었음을 기억하자.
위와 같은 방식으로 의 단어에 대해서 결과를 얻으려면 위와 같이 계산하는 방식이다.
이때 "Bag of words" (BOW) 라는 말을 쓰는데, 여기서 BOW란, 단어의 순서나 위치에 상관없이 주변에 존재하는지의 여부만 확인해서 어떤 단어가 주변에 있는지를 확인한다.
Word2Vec은 이전 포스트에서도 봤다시피 순서에 신경쓰지 않았던 것을 확인할 수 있다.
Word2Vec에서는 2가지 방식을 선택할 수 있다.
또한 Loss Function에 대해서 다양한 방식들이 있다.
Negative Sampling 방식은 거짓 랜덤 샘플 k개를 생성해서, 모델을 진짜 단어가 올 확률을 높이고, 가짜 단어가 올 확률을 낮추는 방향으로 모델을 학습시킨다.
손실함수는 다음과 같다.
는 unigram distribution. 즉, 단어 등장 확률 분포이다. 는 정규화 상수로 정규 분포로 만들어준다는 의미다.
에 제곱을 함으로써, 기존 단어집에서 자주 등장하는 단어는 덜 뽑히고 덜 등장하는 단어는 약간 더 자주 뽑히도록 샘플링한다.
그래서 위 방식대로 Stochastic GD를 한다면, 한 번에 하나의 윈도우만 보고 gradient를 계산하는데 한 윈도우 안에는 (m: 윈도우 크기, k: negative 샘플 수) 개의 단어 정도만 있게 된다.
따라서 전체 단어 에 비해 업데이트해야 하는 단어 수가 매우 적어진다. 즉, 매우 Sparse하게 된다.
이 Sparse 함을 이용해서 우리는 계산을 좀 더 효율적으로 해볼 수 있을 것이다!
아래 같은 방식들이 있을 수 있다.
word2vec을 쓰려면 코퍼스를 계속 반복하면서 학습해야 word vector를 얻을 수 있다.
굳이 word2vec을 써야 하는 걸까?
그냥 같은 문장에서 얼마나 자주 같이 등장했는지의 횟수만 쓰면 안 되는 걸까?
즉, co-occurence counts를 쓰면 되지 않을까?
이런 식으로 같이 등장한 횟수를 세는 것이다.
근데 이 행렬은 보다시피 sparse matrix이기 때문에, 이를 적은 수의 dense vector로 쪼개보자.
선대의 꽃(?)인 Singular Value Decomposition (SVD) 를 쓰자. (또 당신입니까...)
SVD를 이용해서 쪼개버린다면 우리는 적은 수의 dense vector만 저장하면 된다.
그냥 쓰면 효과가 적다.
우리는 the, he, has 같은 쓸데(?)없지만 자주 등장하는 단어들(function word)이 있음을 상기해보자. 이런 단어들은 자주는 등장하지만 의미에 큰 영향을 주지 않는다. 따라서 이런 단어들을 제거해줄 필요가 있다.
이런 식으로 데이터를 정제해준 후에 SVD를 하는 것이 좋다.
위 논문에서는 단어의 의미를 벡터의 차이로 표현하자는 제안을 한다.
그래서 위에서 구한 co-occurence probability의 비율을 벡터 공간의 선형 구조로 표현하고자 한다.
→ Log-bilinear model로 벡터 차이 값을 표현한다.
이런 식으로 표현할 수 있다.
이렇게 loss 함수를 설정하면 Word2Vec과 비교해서 빠르게 훈련이 가능하고 거대한 코퍼스에 대해서도 가능하다.
하지만 하나의 단어에는 여러 개의 의미가 있다.
예를 들어, "pike" 라는 단어에는 다음과 같은 뜻들이 존재한다.
이런 걸 어떻게 구분할 수 있을까?
우리는 위 뜻들의 pike들이 벡터로 표현돼서 결국 하나의 벡터로 합쳐지게 된다. 그걸 수식으로 하면 다음과 같다.
근데 놀랍게도! 이 단어들은 서로 구분이 된다.
그 이유는 대다수의 경우, 하나의 문장에는 하나의 의미로써 쓰이지.. 같은 단어임에도 서로 다른 의미로 해당 단어를 쓰는 문장은 거의 없다.
그러다보니 저 들이 sparse 하게 되어서 자동으로 분리가 되어버린다.
근데 이름 같은 고유명사 같은 경우는 이게 사람 이름인지 지명 이름인지 헷갈릴 때가 존재할 수 있다.
이건 어떻게 해결해야 할까?
SSimple NER에서는 수작업으로 데이터들을 라벨링해서 supervised learning을 했다고 한다.
binary logistic classifier로 학습했다. (물론 실제로는 multi-class softmax를 쓴다.)
yes or no로 학습.
전통적인 softmax 분류기는 선형 구분 밖에 못하지만, 신경망으로는 비선형적인 분류 또한 가능하다
Seq2Seq에서 RNN을 아예 빼버리고 attention으로 구성해보면 어떨까? → Transformer의 구조 현재는 seq2seq + attention에서는 하나의 벡터로…
2025/04/27
언어 모델이라는 건, 사실 다음에 올 단어를 확률로 예측하는 것이다. 이러한 언어 모델들을 어떻게 발전시켜왔는 지 살펴보자. 이미 이전 포스트에서 자세히 살펴보았던 내용이다.…
2025/04/27
이전 포스트에서 RNN에서 Vanishing Gradient로 인해 장기 의존성 문제가 있다는 사실을 이야기했다. 이런 Vanishing Gradient를 해결하기 위해 크게…
2025/04/27
기존 RNN의 병목 현상을 해결하기 위해 Attention이 등장했다. Decoder에서 한 단어를 예상할 때, 해당 단어와 특별히 관련되어 있는 Encoder의 특정 단어를…
2025/04/27