파이토치에서는 임베딩 벡터를 사용하는 방법이 크게 두 가지가 있다. 임베딩 층 (embedding layer)를 만들어 훈련 데이터로부터 처음부터 임베딩 벡터를 학습하는 방법과 미리 사전에 훈련된 임베딩 벡터(pre-trained word embedding)들을 가져와 사용하는 방법이다.
우선 전자의 방법부터 알아보겟다.
임베딩 층의 입력으로 사용하기 위해서 입력 시퀀스의 각 단어들은 모두 정수 인코딩이 되어있어야 한다.
- 어떤 단어 -> 단어에 부여된 고유한 정수값 -> 임베딩 층 통과 -> 밀집 벡터
임베딩 층은 입력 정수에 대해 밀집 벡터로 매핑하고, 이 밀집 벡터는 인공 신경망의 학습 과정에서 가중치가 학습되는 것과 같은 방식으로 훈련된다. 훈련 과정에서 단어는 모델이 풀고자하는 작업에 맞는 값으로 업데이트 된다. 이 밀집 벡터를 임베딩 벡터라고 한다.
특정 단어와 맵핑되는 정수를 인덱스로 가지고 있는 테이블로부터 임베딩 벡터 값을 가져오는 곳은 룩업 테이블이다. 이 테이블은 단어 집합의 크기만큼의 행을 가지고 있으므로, 모든 단어는 고유한 임베딩 벡터를 가진다.
파이토치는 단어를 정수 인덱스로 바꾸고 원-핫 벡터로 한번 더 바꾸고나서 임베딩 층의 입력으로 사용하는 것이 아니라, 단어를 정수 인덱스로만 바꾼채로 임베딩 층의 입력으로 사용해도 룩업 테이블 된 결과인 임베딩 벡터를 리턴한다.
Logic w/o nn.Embedding()
nn.Embedding()을 사용하지 않고, 임베딩의 로직을 코드로 이해해보겠다.
1. 임의의 문장으로부터 단어 집합을 만들고, 각 단어에 정수를 부여한다.
train_data = 'you need to know how to code'
word_set = set(train_data.split()) # 중복을 제거한 단어들의 집합인 단어 집합 생성.
vocab = {word: i+2 for i, word in enumerate(word_set)} # 단어 집합의 각 단어에 고유한 정수 맵핑.
vocab['<unk>'] = 0
vocab['<pad>'] = 1
print(vocab)
>>> {'code': 2, 'you': 3, 'know': 4, 'to': 5, 'need': 6, 'how': 7, '<unk>': 0, '<pad>': 1}
2. 단어 집합의 크기를 행으로 가지는 임베딩 테이블을 구현한다. 단, 여기서 임베딩 벡터의 차원은 3으로 정한다.
# 단어 집합의 크기만큼의 행을 가지는 테이블 생성.
# len(vocab) X 3
embedding_table = torch.FloatTensor([
[ 0.0, 0.0, 0.0],
[ 0.0, 0.0, 0.0],
[ 0.2, 0.9, 0.3],
[ 0.1, 0.5, 0.7],
[ 0.2, 0.1, 0.8],
[ 0.4, 0.1, 0.1],
[ 0.1, 0.8, 0.9],
[ 0.6, 0.1, 0.1]])
3. 임의의 문장에 대해 룩업 테이블을 통해 임베딩 벡터들을 업데이트 시켜준다.
# 임의의 샘플 문장
sample = 'you need to run'.split()
idxes=[]
# 각 단어를 정수로 변환
for word in sample:
try:
idxes.append(vocab[word])
except KeyError: # 단어 집합에 없는 단어일 경우 <unk>로 대체된다.
idxes.append(vocab['<unk>'])
idxes = torch.LongTensor(idxes)
# 룩업 테이블
lookup_result = embedding_table[idxes, :] # 각 정수를 인덱스로 임베딩 테이블에서 값을 가져온다.
print(lookup_result)
# 순서대로 you, need, to, run 단어에 대한 벡터값이 생성됐다.
>>> tensor([[0.1000, 0.5000, 0.7000],
[0.1000, 0.8000, 0.9000],
[0.4000, 0.1000, 0.1000],
[0.0000, 0.0000, 0.0000]])
'Data Science > ML&AI' 카테고리의 다른 글
[군집화] Clustering 알고리즘 쉽게 이해해보기 (1) | 2021.06.03 |
---|---|
[NLP] Embedding - fastText란? (0) | 2021.04.14 |
[NLP] BERT란? - 자연어 처리 모델 알아보기 (0) | 2021.03.20 |
[NLP] NLP 사전 훈련 변천사: 1. Word Embedding & ELMo (0) | 2021.03.17 |
[머신러닝] Undersampling과 Oversampling이란? (0) | 2020.09.20 |