2018년 8월 26일 일요일

Deep Learning with Sequence Data and text (순차적 데이터와 텍스트의 딥러닝 PyTorch) (2)

시작하기 전에


여기 글의 예제는 PyTorch 로 되어 있습니다.
본문의 내용은 Deep Learning with PyTorch (Vishnu Subramanian) 책 내용으로 구성 되어있으며, 해당 내용은 Chapter 6 의 내용으로 구성되어 있습니다.

Vectorization(벡터화)

생성된 토큰과 숫자들의 벡터를 매핑시키는 두가지 방법이 있습니다. one-hot encoding, word embedding 입니다.

One-hot encoding

각각의 토큰은 N길이의 벡터(숫자)로 표현됩니다. 여기에서의 N은 사전(사전의 의미는 자료구조의 set과 비슷합니다. 중복되지 않는 데이터를 의미하며 또한 고유 주소나 index를 가지고 있습니다.)의 크기 입니다.
간단한 예제를 가지고 설명하겠습니다.
An apple a day keeps doctor away said the doctor.
결과
An     100000000
apple  010000000
a      001000000  
day    000100000
keeps  000010000
doctor 000001000
away   000000100
said   000000010
the    000000001
위 결과 표는 토큰과 one-hot encoded 표현을 보여줍니다.
문장에서 9개의 중복되지 않은 단어가 있기 때문에 벡터 길이는 9 입니다. 많은 머신러닝 라이브러리는 이 변환을 쉽게 할 수 있는 방법이 있습니다. 여기에서는 Dictionary class를 만들어 보겠습니다. 

Dictionary class
import numpy as np

class Dictionary(object):
 def __init__(self):
  self.word2idx = {}
  self.idx2word = []
  self.length = 0
 def add_word(self,word):
  if word not in self.idx2word:
   self.idx2word.append(word)
   self.word2idx[word] = self.length + 1
   self.length += 1
  return self.word2idx[word]
 def __len__(self):
  return len(self.idx2word)
 def onehot_encoded(self,word):
  vec = np.zeros(self.length)
  vec[self.word2idx[word]] = 1
  return vec

3가지 중요한 기능들을 제공합니다.
1. 초기화 함수 : __init__, word2idx 사전을 생성하고 거기에 인덱스를 가지고 모든 중복이 안되는 단어를 저장합니다. (실제로 단어라기 보다는 index를 저장하고 키로서 단어를 입력하는 구조입니다. 단어key를 가지고 인덱스를 빨리 알아래는 구조입니다.) idx2word 리스트는에 중복안되는 단어를 저장합니다. length 변수는 전체 중복이 안되는 단어수를 저장하고 있습니다.
2. add_word 함수는 단어와 word2idx, idx2word에 그 단어를 추가합니다. 그리고 사전의 단어 갯수를 증가시킵니다.
3. onehot_encoded 함수는 0을 가지는 N길이의 벡터를 리턴합니다. 단, 단어의 인덱스 부분은 0이 되지 않습니다. 마약 index가 2인 단어라면 벡터의 두번째가 1이 되고 나머지는 0이 되는 벡터를 리턴할것입니다.

앞에서 dictionary class를 만들었으니 앞에서 사용한 thor_review 데이터를 넣어서 실행해보겠습니다.  

thor_review = "The action scenes were top notch in this movie. Thor has never been this epic in the MCU. He does some pretty epic sht in this movie and he is definitely not under-powered anymore. Thor in unleashed in this, I love that."

dic = Dictionary()

for tok in thor_review.split():
 dic.add_word(tok)
 
print(dic.word2idx)

결과
{'The': 1, 'action': 2, 'scenes': 3, 'were': 4, 'top': 5, 'notch': 6, 'in': 7, 'this': 8, 'movie.': 9, 'Thor': 10, 'has': 11, 'never': 12, 'been': 13, 'epic': 14, 'the': 15, 'MCU.': 16, 'He': 17, 'does': 18, 'some': 19, 'pretty': 20, 'sht': 21, 'movie': 22, 'and': 23, 'he': 24, 'is': 25, 'definitely': 26, 'not': 27, 'under-powered': 28, 'anymore.': 29, 'unleashed': 30, 'this,': 31, 'I': 32, 'love': 33, 'that.': 34}

'were' 라는 단어의 one-hot encoding 결과 입니다. 
print(dic.onehot_encoded('were'))

결과
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

one-hot 표현은 데이터가 너무 희소하고 사전 크기에 비해 벡터의 크기가 너무 급격하게 증가합니다. 이런 제약이 있어서 딥러닝에 있어서 드물게 사용됩니다.







댓글 없음:

댓글 쓰기