01) 토큰화(Tokenization)


Computer Vision과 달리 NLP에서 텍스트 자체를 바로 피처로 사용할 수는 없습니다. 사전에 텍스트 전처리 작업이 반드시 필요합니다. 텍스트 전처리를 위해서는 토큰화(tokenization) & 정제(cleaning) & 정규화(normalization)하는 일을 하게 됩니다. 이번에는 그중에서도 토큰화에 대해서 알아보도록 하겠습니다.

 

주어진 코퍼스(corpus)에서 토큰(token)이라 불리는 단위로 나누는 작업을 토큰화(tokenization)라고 합니다. 그럼 먼저 말뭉치(Corpus, 코퍼스)의 뜻에 대해 먼저 알아보면

말뭉치 또는 코퍼스(영어: corpus, 복수형: corpora)는 자연언어 연구를 위해 특정한 목적을 가지고 언어의 표본을 추출한 집합이다. 컴퓨터의 발달로 말뭉치 분석이 용이해졌으며 분석의 정확성을 위해 해당 자연언어를 형태소 분석하는 경우가 많다. 확률/통계적 기법과 시계열적인 접근으로 전체를 파악한다. 언어의 빈도와 분포를 확인할 수 있는 자료이며, 현대 언어학 연구에 필수적인 자료이다. 인문학에 자연과학적 방법론이 가장 성공적으로 적용된 경우로 볼 수 있다.
 

형태 분석 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 형태 분석(形態分析)은 단어를 보고 형태소 단위로 분리해내는 과정을 말한다. 수작업으로 하기도 했으나 컴퓨터의 발달로 점차 자동화되어 정확도가 높아지

ko.wikipedia.org

어렵게 설명이 되어 있는데, 그냥 우리가 사용하는 텍스트 표본이라고 생각합시다.

 

토큰(Token)이란 문법적으로 더 이상 나눌 수 없는 언어 요소를 뜻합니다. 텍스트 토큰화(Text Tokenization)란 말뭉치로부터 토큰을 분리하는 작업을 뜻합니다.

 

예를 들어, 아이유의 노래 Love poem의 가사 중 "Here i am"이라는 말뭉치를 토큰화 한다고 가정하면 "Here", "i", "am" 이런 식으로 나뉘게 될 겁니다.(이상적인 경우)

 

텍스트 토큰화의 유형은 문장 토큰화와 단어 토큰화로 나눌 수 있습니다. 문장 토큰화는 텍스트에서 문장을 분리하는 작업을 뜻하고, 단어 토큰화는 문장에서 단어를 토큰으로 분리하는 작업을 뜻합니다.

 

문장 토큰화(Sentence Tokenization)

문장 토큰화는 문장의 마침표(.), 개행문자(\n), 느낌표(!), 물음표(?) 등 문장의 마지막을 뜻하는 기호에 따라 분리하는 것이 일반적입니다. 하지만 꼭 그렇지는 않습니다. 예를 들어, "Hello! I'm a Ph.D student."라는 텍스트를 문장 토큰화를 진행 할 경우 "Hello", "I'm a ph.D student"로 2개의 문장으로 분리를 해야 하는데, 마침표(.)를 기준으로 문장 토큰화를 하면 "Hello", "I'm a ph", "D student"로 3개의 문장으로 엉터리로 분리하게 됩니다. 따라서 100% 정확하게 문장을 분리하는 것은 쉬운 일이 아닙니다. 

from nltk.tokenize import sent_tokenize

text = "His barber kept his word. But keeping such a huge secret to himself was driving him crazy. Finally, the barber went up a mountain and almost to the edge of a cliff. He dug a hole in the midst of some reeds. He looked about, to make sure no one was near."
print('문장 토큰화1 :',sent_tokenize(text))
['His barber kept his word.', 'But keeping such a huge secret to himself was driving him crazy.', 'Finally, the barber went up a mountain and almost to the edge of a cliff.', 'He dug a hole in the midst of some reeds.', 'He looked about, to make sure no one was near.']

3개의 문장이 잘 분류가 되고 있는 것을 확인할 수 있습니다. 위의 3 문장의 경우 단순히 마침표만으로 구분해도 구분할 수 있는 문장인데요. 중간에 마침표로 사용되지 않는 Ph.D가 포함된 문장도 토큰화를 진행해보도록 하겠습니다.

 

text_sample = 'I am actively looking for Ph.D. students. and you are a Ph.D student.'
tokenized_sentences = sent_tokenize(text_sample)
print('Ph.D.가 포함된 문장 토큰화 :',sent_tokenize(text_sample))
Ph.D.가 포함된 문장 토큰화 : ['I am actively looking for Ph.D. students.', 'and you are a Ph.D student.']

마침표(.)를 기준으로 분리하지 않았기 때문에 정확히 분리된 것을 볼 수 있습니다.

 

단어 토큰화 (Word Tokenization)

단어 토큰화는 기본적으로 띄어쓰기를 기준으로 합니다. 영어는 보통 띄어쓰기로 토큰이 구분되는 반면, 한국어는 띄어쓰기 만으로 토큰을 구분하기는 어렵습니다. 심지어 띄어쓰기가 잘못되어 있는 경우도 허다하고요. 우선은 영어를 기반으로 실습해보겠습니다.

from nltk.tokenize import word_tokenize
from nltk.tokenize import WordPunctTokenizer
from tensorflow.keras.preprocessing.text import text_to_word_sequence

print('단어 토큰화1 :',word_tokenize("Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop."))
단어 토큰화1 : ['Do', "n't", 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name', ',', 'Mr.', 'Jone', "'s", 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop', '.']

결과를 보시면 띄어쓰기를 기반으로 분리를 하되 콤마(,)와 마침표(.)는 별도의 토큰으로 구분했습니다. 어퍼스트로피(')가 있는 경우 Don't는 Do와 n't로  Jone's는 Jone'과 's로 구분했습니다. 

 

마지막으로 nltk가 아닌 keras의 text_to_word_sequence로 실습해보겠습니다.

from keras.preprocessing.text import text_to_word_sequence
sentence = "Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop."
words = text_to_word_sequence(sentence)
print("keras_text_to_word_sequence : ",words)
keras_text_to_word_sequence :  ["don't", 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name', 'mr', "jone's", 'orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop']

keras의 text_to_word_sequence는 모든 알파벳을 소문자로 바꾸고, 구두점(컴마, 마침표 등)을 없애고, 어퍼스트로피(')도 보존하여 토큰을 제대로 구분해준 것을 볼 수 있습니다.(성능이 괜찮네요)

문장 토큰화와 단어 토큰화 모두 정규 표현식을 활용하여 토큰화하는 작업도 가능합니다.(정규화를 쓸 경우에는 정교하게 진행해야 제공되는 api이상 혹은 비슷한 성능이 나올 겁니다.) 문장 토큰화는 문장 자체가 중요한 의미를 가질 경우 사용되며, 일반적으로는 단어 토큰화만 사용해도 충분합니다.

 

영어는 해봤으니 앞으로 사용할 한국어의 경우에는 박상길님이 개발한 KSS(Korean Sentence Splitter)를  '딥러닝을 이용한 자연어 처리 입문'에서 추천하고 있습니다. KSS를 설치합니다.

pip install kss

KSS를 통해서 문장 토큰화를 진행해보겠습니다.

import kss

text = '아이유의 2022년도 콘서트 이름은 골든아워입니다. 저번주 주말에 갔는데 팬들에게 방석을 나눠주더라구요. 저는 연두색 방석을 받았습니다.'
print('한국어 문장 토큰화 :',kss.split_sentences(text))
한국어 문장 토큰화 : ['아이유의 2022년도 콘서트 이름은 골든아워입니다.', '저번주 주말에 갔는데 팬들에게 방석을 나눠주더라구요.', '저는 연두색 방석을 받았습니다.']

출력 결과는 정상적으로 모든 문장이 분리된 결과를 보여줍니다. (조금 애매한 문장을 잘 안나뉘는 케이스들도 있습니다. 참고하시기 바래요.)

한국어에서의 토큰화의 어려움

영어는 New York과 같은 합성어나 he's 와 같이 줄임말에 대한 예외처리만 한다면, 띄어쓰기(whitespace)를 기준으로 하는 띄어쓰기 토큰화를 수행해도 단어 토큰화가 잘 작동합니다. 거의 대부분의 경우에서 단어 단위로 띄어쓰기가 이루어지기 때문에 띄어쓰기 토큰화와 단어 토큰화가 거의 같기 때문입니다.

하지만 한국어는 영어와는 달리 띄어쓰기만으로는 토큰화를 하기에 부족합니다. 한국어의 경우에는 띄어쓰기 단위가 되는 단위를 '어절'이라고 하는데 어절 토큰화는 한국어 NLP에서 지양되고 있습니다. 어절 토큰화와 단어 토큰화는 같지 않기 때문입니다. 그 근본적인 이유는 한국어가 영어와는 다른 형태를 가지는 언어인 교착어라는 점에서 기인합니다. 교착어란 조사, 어미 등을 붙여서 말을 만드는 언어를 말합니다.

 

1) 교착어의 특성

예를 들어봅시다. 영어와는 달리 한국어에는 조사라는 것이 존재합니다. 예를 들어 한국어에 그(he/him)라는 주어나 목적어가 들어간 문장이 있다고 합시다. 이 경우, 그라는 단어 하나에도 '그가', '그에게', '그를', '그와', '그는'과 같이 다양한 조사가 '그'라는 글자 뒤에 띄어쓰기 없이 바로 붙게됩니다. 자연어 처리를 하다보면 같은 단어임에도 서로 다른 조사가 붙어서 다른 단어로 인식이 되면 자연어 처리가 힘들고 번거로워지는 경우가 많습니다. 대부분의 한국어 NLP에서 조사는 분리해줄 필요가 있습니다.

 

띄어쓰기 단위가 영어처럼 독립적인 단어라면 띄어쓰기 단위로 토큰화를 하면 되겠지만 한국어는 어절이 독립적인 단어로 구성되는 것이 아니라 조사 등의 무언가가 붙어있는 경우가 많아서 이를 전부 분리해줘야 한다는 의미입니다.

 

한국어 토큰화에서는 형태소(morpheme) 란 개념을 반드시 이해해야 합니다. 형태소(morpheme)란 뜻을 가진 가장 작은 말의 단위를 말합니다. 이 형태소에는 두 가지 형태소가 있는데 자립 형태소와 의존 형태소입니다.

 

  • 자립 형태소 : 접사, 어미, 조사와 상관없이 자립하여 사용할 수 있는 형태소. 그 자체로 단어가 된다. 체언(명사, 대명사, 수사), 수식언(관형사, 부사), 감탄사 등이 있다.
  • 의존 형태소 : 다른 형태소와 결합하여 사용되는 형태소. 접사, 어미, 조사, 어간를 말한다.

예를 들어 다음과 같은 문장이 있다고 합시다.

  • 문장 : 에디가 책을 읽었다

이 문장을 띄어쓰기 단위 토큰화를 수행한다면 다음과 같은 결과를 얻습니다.

  • ['에디가', '책을', '읽었다']

하지만 이를 형태소 단위로 분해하면 다음과 같습니다.

자립 형태소 : 에디, 책
의존 형태소 : -가, -을, 읽-, -었, -다

'에디'라는 사람 이름과 '책'이라는 명사를 얻어낼 수 있습니다. 이를 통해 유추할 수 있는 것은 한국어에서 영어에서의 단어 토큰화와 유사한 형태를 얻으려면 어절 토큰화가 아니라 형태소 토큰화를 수행해야한다는 겁니다.

 

2) 한국어는 띄어쓰기가 영어보다 잘 지켜지지 않는다.

사용하는 한국어 코퍼스가 뉴스 기사와 같이 띄어쓰기를 철저하게 지키려고 노력하는 글이라면 좋겠지만, 많은 경우에 띄어쓰기가 틀렸거나 지켜지지 않는 코퍼스가 많습니다.

한국어는 영어권 언어와 비교하여 띄어쓰기가 어렵고 잘 지켜지지 않는 경향이 있습니다. 그 이유는 여러 견해가 있으나, 가장 기본적인 견해는 한국어의 경우 띄어쓰기가 지켜지지 않아도 글을 쉽게 이해할 수 있는 언어라는 점입니다. 띄어쓰기가 없던 한국어에 띄어쓰기가 보편화된 것도 근대(1933년, 한글맞춤법통일안)의 일입니다. 띄어쓰기를 전혀 하지 않은 한국어와 영어 두 가지 경우를 봅시다.

EX1) 제가이렇게띄어쓰기를전혀하지않고글을썼다고하더라도글을이해할수있습니다.

EX2) Tobeornottobethatisthequestion

영어의 경우에는 띄어쓰기를 하지 않으면 손쉽게 알아보기 어려운 문장들이 생깁니다. 이는 한국어(모아쓰기 방식)와 영어(풀어쓰기 방식)라는 언어적 특성의 차이에 기인합니다. 이 책에서는 모아쓰기와 풀어쓰기에 대한 설명은 하지 않겠습니다. 다만, 결론적으로 한국어는 수많은 코퍼스에서 띄어쓰기가 무시되는 경우가 많아 자연어 처리가 어려워졌다는 것입니다.

 

품사 태깅(Part-of-speech tagging)

단어는 표기는 같지만 품사에 따라서 단어의 의미가 달라지기도 합니다. 예를 들어서 영어 단어 'fly'는 동사로는 '날다'라는 의미를 갖지만, 명사로는 '파리'라는 의미를 갖고있습니다. 한국어도 마찬가지입니다. '못'이라는 단어는 명사로서는 망치를 사용해서 목재 따위를 고정하는 물건을 의미합니다. 하지만 부사로서의 '못'은 '먹는다', '달린다'와 같은 동작 동사를 할 수 없다는 의미로 쓰입니다. 결국 단어의 의미를 제대로 파악하기 위해서는 해당 단어가 어떤 품사로 쓰였는지 보는 것이 주요 지표가 될 수도 있습니다. 그에 따라 단어 토큰화 과정에서 각 단어가 어떤 품사로 쓰였는지를 구분해놓기도 하는데, 이 작업을 품사 태깅(part-of-speech tagging)이라고 합니다. NLTK와 KoNLPy를 통해 품사 태깅 실습을 진행합니다.

 

from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag

text = "I am actively looking for Ph.D. students. and you are a Ph.D. student."
tokenized_sentence = word_tokenize(text)

print('단어 토큰화 :',tokenized_sentence)
print('품사 태깅 :',pos_tag(tokenized_sentence))
단어 토큰화 : ['I', 'am', 'actively', 'looking', 'for', 'Ph.D.', 'students', '.', 'and', 'you', 'are', 'a', 'Ph.D.', 'student', '.']
품사 태깅 : [('I', 'PRP'), ('am', 'VBP'), ('actively', 'RB'), ('looking', 'VBG'), ('for', 'IN'), ('Ph.D.', 'NNP'), ('students', 'NNS'), ('.', '.'), ('and', 'CC'), ('you', 'PRP'), ('are', 'VBP'), ('a', 'DT'), ('Ph.D.', 'NNP'), ('student', 'NN'), ('.', '.')]

한국어 자연어 처리를 위해서는 KoNLPy(코엔엘파이)라는 파이썬 패키지를 사용할 수 있습니다. 코엔엘파이를 통해서 사용할 수 있는 형태소 분석기로 Okt(Open Korea Text), 메캅(Mecab), 코모란(Komoran), 한나눔(Hannanum), 꼬꼬마(Kkma)가 있습니다.

한국어 NLP에서 형태소 분석기를 사용하여 단어 토큰화. 더 정확히는 형태소 토큰화(morpheme tokenization)를 수행해보겠습니다. 여기서는 Okt와 꼬꼬마 두 개의 형태소 분석기를 사용하여 토큰화를 수행하겠습니다.

from konlpy.tag import Okt
from konlpy.tag import Kkma

okt = Okt()
kkma = Kkma()

print('OKT 형태소 분석 :',okt.morphs("아이유 콘서트는 최고입니다."))
print('OKT 품사 태깅 :',okt.pos("아이유 콘서트는 최고입니다."))
print('OKT 명사 추출 :',okt.nouns("아이유 콘서트는 최고입니다."))
OKT 형태소 분석 : ['아이유', '콘서트', '는', '최고', '입니다', '.']
OKT 품사 태깅 : [('아이유', 'Noun'), ('콘서트', 'Noun'), ('는', 'Josa'), ('최고', 'Noun'), ('입니다', 'Adjective'), ('.', 'Punctuation')]
OKT 명사 추출 : ['아이유', '콘서트', '최고']

Vision에서 최근에 많이 들 쓰고 있는 Transformer계열의 모델을 공부하려고 보니 Transformer 및 해당하는 자연어처리 Task에 해당하는 배경지식이 너무 없어서 아래에 해당하는 e-book을 보고 정리해나갈 예정

 

https://wikidocs.net/book/2155

 

딥 러닝을 이용한 자연어 처리 입문

많은 분들의 피드백으로 수년간 보완되어 온 딥 러닝 자연어 처리 무료 eBook입니다. 기본적인 텍스트 전처리부터 BERT와 같은 PLM의 다양한 다운스트림 태스크를 ...

wikidocs.net

 

1. 머신 러닝 워크플로우(Machine Learning Workflow)


데이터를 수집하고 머신 러닝을 하는 과정을 크게 6가지로 나누면, 아래의 그림과 같습니다. (나누는 과정은 Task별로 조금 달라 질 수 있습니다.)

1) 수집(Acquisition)

머신 러닝을 하기 위해서는 기계에 학습시켜야 할 데이터가 필요합니다. 자연어 처리의 경우, 자연어 데이터를 말뭉치 또는 코퍼스(corpus)라고 부르는데 코퍼스의 의미를 풀이하면, 조사나 연구 목적에 의해서 특정 도메인으로부터 수집된 텍스트 집합을 말합니다. 텍스트 데이터의 파일 형식은 txt 파일, csv 파일, xml 파일 등 다양하며 그 출처도 음성 데이터, 웹 수집기를 통해 수집된 데이터, 영화 리뷰 등 다양합니다.

2) 점검 및 탐색(Inspection and exploration)

데이터가 수집되었다면, 이제 데이터를 점검하고 탐색하는 단계입니다. 여기서는 데이터의 구조, 노이즈 데이터, 머신 러닝 적용을 위해서 데이터를 어떻게 정제해야하는지 등을 파악해야 합니다.

이 단계를 탐색적 데이터 분석(Exploratory Data Analysis, EDA) 단계라고도 하는데 이는 독립 변수, 종속 변수, 변수 유형, 변수의 데이터 타입 등을 점검하며 데이터의 특징과 내재하는 구조적 관계를 알아내는 과정을 의미합니다. 이 과정에서 시각화와 간단한 통계 테스트를 진행하기도 합니다.

3) 전처리 및 정제(Preprocessing and Cleaning)

데이터에 대한 파악이 끝났다면, 머신 러닝 워크플로우에서 가장 까다로운 작업 중 하나인 데이터 전처리 과정에 들어갑니다. 이 단계는 많은 단계를 포함하고 있는데, 가령 자연어 처리라면 토큰화, 정제, 정규화, 불용어 제거 등의 단계를 포함합니다. 빠르고 정확한 데이터 전처리를 하기 위해서는 사용하고 있는 툴(이 책에서는 파이썬)에 대한 다양한 라이브러리에 대한 지식이 필요합니다. 정말 까다로운 전처리의 경우에는 전처리 과정에서 머신 러닝이 사용되기도 합니다.

4) 모델링 및 훈련(Modeling and Training)

데이터 전처리가 끝났다면, 머신 러닝에 대한 코드를 작성하는 단계인 모델링 단계에 들어갑니다. 적절한 머신 러닝 알고리즘을 선택하여 모델링이 끝났다면, 전처리가 완료 된 데이터를 머신 러닝 알고리즘을 통해 기계에게 학습(training)시킵니다. 이를 훈련이라고도 하는데, 이 두 용어를 혼용해서 사용합니다. 기계가 데이터에 대한 학습을 마치고나서 훈련이 제대로 되었다면 그 후에 기계는 우리가 원하는 태스크(task)인 기계 번역, 음성 인식, 텍스트 분류 등의 자연어 처리 작업을 수행할 수 있게 됩니다.

여기서 주의해야 할 점은 대부분의 경우에서 모든 데이터를 기계에게 학습시켜서는 안 된다는 점입니다. 뒤의 실습에서 보게되겠지만 데이터 중 일부는 테스트용으로 남겨두고 훈련용 데이터만 훈련에 사용해야 합니다. 그래야만 기계가 학습을 하고나서, 테스트용 데이터를 통해서 현재 성능이 얼마나 되는지를 측정할 수 있으며 과적합(overfitting) 상황을 막을 수 있습니다. 사실 최선은 훈련용, 테스트용으로 두 가지만 나누는 것보다는 훈련용, 검증용, 테스트용. 데이터를 이렇게 세 가지로 나누고 훈련용 데이터만 훈련에 사용하는 것입니다.

 

검증용과 테스트용의 차이는 무엇일까요? 수능 시험에 비유하자면 훈련용은 학습지, 검증용은 모의고사, 테스트용은 수능 시험이라고 볼 수 있습니다. 학습지를 풀고 수능 시험을 볼 수도 있겠지만, 모의 고사를 풀며 부족한 부분이 무엇인지 검증하고 보완하는 단계를 하나 더 놓는 방법도 있겠지요. 사실 현업의 경우라면 검증용 데이터는 거의 필수적입니다.

검증용 데이터는 현재 모델의 성능. 즉, 기계가 훈련용 데이터로 얼마나 제대로 학습이 되었는지를 판단하는 용으로 사용되며 검증용 데이터를 사용하여 모델의 성능을 개선하는데 사용됩니다. 테스트용 데이터는 모델의 최종 성능을 평가하는 데이터로 모델의 성능을 개선하는 일에 사용되는 것이 아니라, 모델의 성능을 수치화하여 평가하기 위해 사용됩니다. 쉽게 말해 시험에 비유하면 채점하는 단계입니다. 따라서 Test셋의 경우

이 책에서는 실습 상황에 따라서 훈련용, 검증용, 테스트용 세 가지를 모두 사용하거나 때로는 훈련용, 테스트용 두 가지만 사용하기도 합니다. 하지만 현업에서 최선은 검증용 데이터 또한 사용하는 것임을 기억해둡시다.

5) 평가(Evaluation)

미리 언급하였는데, 기계가 다 학습이 되었다면 테스트용 데이터로 성능을 평가하게 됩니다. 평가 방법은 기계가 예측한 데이터가 테스트용 데이터의 실제 정답과 얼마나 가까운지를 측정합니다.

6) 배포(Deployment)

평가 단계에서 기계가 성공적으로 훈련이 된 것으로 판단된다면 완성된 모델이 배포되는 단계가 됩니다. 다만, 여기서 완성된 모델에 대한 전체적인 피드백으로 인해 모델을 업데이트 해야하는 상황이 온다면 수집 단계로 돌아갈 수 있습니다.

 

유튜브의 10분 딥러닝을 참고하여 정리하였습니다.

 

1. Attention Mechanism

 

 

인공신경망에서 Attention이라고 하는것은 어떤 특정한 신경망을 뜻하는것이 아니라 인간의 시각적 집중(Visual Attention) 현상을 구현하기위한 신경망적 기법을 말합니다.

 

Attention이 딥러닝 모델 혹은 layer가 아닌 기법인 이유

위의 그림과 같이 구현되어 있다고 가정한다면, 사람이 주목하는 부분에 대해서 고화질을 유지하고 그 이외의 영역에 대해서는 저화질을 유지하게 됩니다. 이 말을 다시 정리하자면, 우리의 초점이 맞는 곳 즉, 우리가 보고자 하는 영역에 대해서는 높은 집중도를 보여서 고화질을 유지하게되고 보지 않는것에 관해서는 낮은 저화질로 낮은 집중도를 유지하게 됩니다. 이러한 현상을 인공신경망에서도 구현을 해보고자 하는것이 Attention 기법이라고 할 수 있겠습니다.


 

2. 가중치와 어텐션의 공통점과 차이점

가중치도 결국 보고자하는 영역을 집중적으로 본다고 할 수 있는데 그럼 가중치를 학습하는것과 차이는 뭐야?

=> 가중치와 어텐션의 공통점과 차이점

가중치와 어텐션 모두 해당 값을 얼마나 가중시킬 것인가를 나타내는 역활을 하지만, 어텐션을 가중치와 달리 전체 또는 특정 영역의 입력값을 반영하여, 그 중에 어떤 부분에 집중해야 하는지를 나타내는 것을 목표로 한다. ( 어떻게 사용하냐에 따라서 선택적으로 사용할 수 있다는 부분이 다르다고 할 수 있겠다. )

 

좀 더 상세히 설명하자면 가중치의 경우 <Visual World> 의 이미지가 있다고 가정할 때 각 이미지의 모양, 형태에 집중하는것이 아닌 최종적으로 y와 얼마만큼 가까워지게 만들 수 있는지에 focus가 맞춰져 있다고 생각하시면 될 것 같습니다. 또 그 판단기준( y와 유사하게 만드는 값 )에 따라서 가중시킬것인지 축소시킬것인지가 결정됩니다. 하지만 어텐션의 경우 객체나 물체같은 경우를 인식해서 그 객체나 물체가 있는 특정영역만 집중을 하겠다라는게 어텐션의 컨셉이라고 생각하시면 됩니다.

 

 

3. 신경망 기계번역 

Attention기법이 인공신경망에 어떻게 적용되는지 특정분야를 가지고 설명을 하도록 하겠습니다. 대표적인 분야로 자연어처리 분야를 예로 사용하겠습니다.

우리가 번역하고자하는 언어를 데이터로 사용해서 번역하고자 언어로 변역하는 시스템이 신경망 기계번역이라고 보시면 될 것 같습니다.

 

4. 기계번역에서의 어텐션 메커니즘

인코더-디코더 방식의 경우 인풋데이터를 특정 크기의 벡터 사이즈로 압축 후 디코더를 통해 원하는 출력값을 산출하게 된다. ( 특정 크기의 벡터 사이즈가 고정되는 이유는 특정 크기의 벡터 사이즈로 데이터를 압축해서 표현하기 위함. Encoder -Decoder에 관해서는 따로 자세히 설명할 예정 ) 여기서 고정된 크기의 벡터를 사용했을 때 보통 이 벡터의 사이즈가 사용된 데이터를 압축하는식으로 진행되기 때문에 데이터의 특징을 대표하는 feature이면서 동시에 데이터의 손실이 발생하게 된다. 이에 대해서 문제제기를 Neural Machine Translation By Jointly Learning To Align Translate논문에서 했으며, 이를 극복방안 중 하나로 Attention 기법을 제안하였다.

 

5. 기계번역에서의 어텐션 메커니즘 구조

 메커니즘 구조에 대해서 좀 더 자세히 설명하자면 X_1 ~ X_T 까지의 입력 데이터값이 주어지게 되면 RNN의 구조를 통해서  Hidden state 값을 뽑아내게 되는데,  Hidden state 값의 경우 정방향 RNN에서 나온 Hidden state 값과 역방향 RNN에서 나온  Hidden state 값을 concatenate 이어붙여서 사용합니다.

 

위의 그림을 보시면 y의 경우에는 최종 출력물이고 s의 경우는 linear mapping을 한 상태 마지막으로 c의 경우 중간 값이라고 기억하시면 됩니다.

( 위의 구조 연산은 따로 좀 더 자세히 설명을 진행하도록 하겠습니다. Vision만하다보니 어텐션은 어렵네요...)

 

6. 어텐션 메커니즘의 의의

위의 수식을 보게 되면 어텐션을 사용하게 됐을 때, Softmax의 형태를 취하고 있음을 알 수 있습니다. 즉, 이말은 0~1사의 값을 가진다고 볼 수 있는데 이는 수학적으로 확률로 해석할 수 있음을 의미합니다.

 

기존의 RNN의 경우 연쇄적인 반영을 통해서 feedback시스템이 구성이 되기 때문에 길이가 길어질 경우 dependency가 생길 수 있지만 Attention의 경우 각각의 x에 따른 h를 뽑아내게 되고 각각의 a값에 따른 가중치들이 반영이 되기 때문에 기존의 RNN에 비해서 길어질 경우에 발생하는 부분을 조금 해소할 수 있을것 입니다.

 

 

 

참고 링크 : https://www.youtube.com/watch?v=6aouXD8WMVQ&ab_channel=10mindeeplearning

'nlp_study' 카테고리의 다른 글

Transformer  (0) 2021.12.22

요즘 최근 vision 모델에서 사용하는 Transformer 모델을 공부하기전에 transformer를 공부하기위해 정리한다. ( 물론 자연어쪽도 나름 공부하기 위해서 정리를 시작하려고 한다 내가 보기 위함)

 

1. Transformer

트랜스포머(Transformer)는 2017년 구글이 발표한 논문인 "Attention is all you need"에서 나온 모델로 기존의 seq2seq의 구조인 인코더-디코더를 따르면서도, 논문의 이름처럼 어텐션(Attention)만으로 구현한 모델입니다. 이 모델은 RNN을 사용하지 않고, 인코더-디코더 구조를 설계하였음에도 성능도 RNN보다 우수하다는 특징을 갖고있습니다.

 

2. 트랜스포머(Transformer)의 주요 하이퍼파라미터

시작에 앞서 트랜스포머의 하이퍼파라미터를 정의합니다. 각 하이퍼파라미터의 의미에 대해서는 뒤에서 설명하기로하고, 여기서는 트랜스포머에는 이러한 하이퍼파라미터가 존재한다는 정도로만 이해해보겠습니다. 아래에서 정의하는 수치는 트랜스포머를 제안한 논문에서 사용한 수치로 하이퍼파라미터는 사용자가 모델 설계시 임의로 변경할 수 있는 값들입니다.

dmodel = 512
트랜스포머의 인코더와 디코더에서의 정해진 입력과 출력의 크기를 의미합니다. 임베딩 벡터의 차원 또한 dmodel이며, 각 인코더와 디코더가 다음 층의 인코더와 디코더로 값을 보낼 때에도 이 차원을 유지합니다. 논문에서는 512입니다.

num_layers = 6
트랜스포머에서 하나의 인코더와 디코더를 층으로 생각하였을 때, 트랜스포머 모델에서 인코더와 디코더가 총 몇 층으로 구성되었는지를 의미합니다. 논문에서는 인코더와 디코더를 각각 총 6개 쌓았습니다.

num_heads = 8
트랜스포머에서는 어텐션을 사용할 때, 1번 하는 것 보다 여러 개로 분할해서 병렬로 어텐션을 수행하고 결과값을 다시 하나로 합치는 방식을 택했습니다. 이때 이 병렬의 개수를 의미합니다.

dff = 2048
트랜스포머 내부에는 피드 포워드 신경망이 존재하며 해당 신경망의 은닉층의 크기를 의미합니다. 피드 포워드 신경망의 입력층과 출력층의 크기는 dmodel입니다.

3. 트랜스포머(Transformer)

트랜스포머는 RNN을 사용하지 않지만 기존의 seq2seq처럼 인코더에서 입력 시퀀스를 입력받고, 디코더에서 출력 시퀀스를 출력하는 인코더-디코더 구조를 유지하고 있습니다. 다만 다른 점은 인코더와 디코더라는 단위가 N개가 존재할 수 있다는 점입니다.

이전 seq2seq 구조에서는 인코더와 디코더에서 각각 하나의 RNN이 t개의 시점(time-step)을 가지는 구조였다면 이번에는 인코더와 디코더라는 단위가 N개로 구성되는 구조입니다. 트랜스포머를 제안한 논문에서는 인코더와 디코더의 개수를 각각 6개를 사용하였습니다.

위의 그림은 인코더와 디코더가 6개씩 존재하는 트랜스포머의 구조를 보여줍니다. 이 책에서는 인코더와 디코더가 각각 여러 개 쌓여있다는 의미를 사용할 때는 알파벳 s를 뒤에 붙여 encoders, decoders라고 표현하겠습니다.

위의 그림은 인코더로부터 정보를 전달받아 디코더가 출력 결과를 만들어내는 트랜스포머 구조를 보여줍니다. 디코더는 마치 기존의 seq2seq 구조처럼 시작 심볼 <sos>를 입력으로 받아 종료 심볼 <eos>가 나올 때까지 연산을 진행합니다. 이는 RNN은 사용되지 않지만 여전히 인코더-디코더의 구조는 유지되고 있음을 보여줍니다.

트랜스포머의 내부 구조를 조금씩 확대해가는 방식으로 트랜스포머를 이해해봅시다. 우선 인코더와 디코더의 구조를 이해하기 전에 트랜스포머의 입력에 대해서 이해해보겠습니다. 트랜스포머의 인코더와 디코더는 단순히 각 단어의 임베딩 벡터들을 입력받는 것이 아니라 임베딩 벡터에서 조정된 값을 입력받는데 이에 대해서 알아보기 위해 입력 부분을 확대해보겠습니다.

 

4. Transformer Architecture

우선 논문에서 제시한 transformer의 기본 architecture는 아래와 같습니다.

위 구조가 바로 Transformer 모델의 구조입니다. Encoder-Decoder 구조를 갖는다는 것 외에는 모르는 단어가 상당히 많은데, Self-Attention, Multi-head Attention, Positional Encoding 등 Transformer 모델의 구성요소와 동작원리에 대해서 알아보도록 하죠.

 

5. Self-Attention

먼저 Dot-product attention에 대해서 알아보자.

각 value가 key에 매칭 되어 있다고 하자. Python의 Dictionary를 떠올려도 좋습니다.
※ dict{key1 : {value1}, key2 : {value2}, ..., keyt : {value_t}}로 구성된 dictionary가 있다고 생각하자구요.

어떤 query가 들어오면 dot-product attention은 value의 convex sum을 출력한다.

이 때 weight들은 query와 key의 dot-product를 0~1 사이 값으로 normalize한 값과 같다.
즉, query와 key가 비슷하면 weight가 높게, 유사성이 낮으면 weight는 낮으며, 모든 weight의 합은 1이 된다.

 

전혀 새로운 개념이 아니다. Attention 포스팅에서다룬 내용도 s를 query로 가지고 key가 h1, ..., ht였던 dot-product attention과 동일하다. 그럼 self-attention은 어떤 함수일까?

 

바로 key query, value 동일한 집합에 있는 것이다. 예를 들면 s_t와 s_1, ..., s_t간의 각각의 유사성을 convex sum형태로 표현한 것이다. 위 과정을 그림으로 나타내면 아래와 같다.

[출처 : Peter Bloem - Transformer]

위 예제에서 w_ij의 의미는 key x_i와 query x_j의 weight를 의미한다.
즉, y2는 x1-x2, x2-x2, x3-x2, x4-x2를 비교해 각 value들을 convex sum한 결과가 된다.

그런데 이 대로는 사실 쓸모가 없다. 왜냐하면 w_ij는 sequence(x1, ..., x4)만 있으면 자동으로 계산되는 상수나 마찬가지기 때문에다. 그래서 '학습'을 위해서 학습될 수 있는 parameter가 필요하다. (parameterize)

 

그래서 query, key, value에 각각 파라미터 Wq, Wk, Wv를 적용하면 위와 같이 표현할 수 있다. 이렇게 하면 학습을 통해 적절한 파라미터를 찾아서 자기 자신의 self-attention 을 학습할 수 있게 된다. 

이렇게 했을 때 어떤 효과가 있을까? 

위 예시는 'The', 'animal' ... 'tired' 스스로 self attention 한 결과이다. 예를 들면 'it'은 어떤 단어와 유사성이 가장 높았는지 self attention을 계산한 결과 it은 animal과 가장 높은 유사성을 가진 것을 알 수 있는데, 이런 효과도 대표적인 self-attention의 효과다.

6. Scaled Dot-Product Attention

Scaled Dot-Product Attention은 앞에서 배운 Dot-product attention과 거의 동일하다.

 

Dot-Product Attention은 기존 방법에 Key의 차원 D_k를 나눠서 scaling한 것이다.
(self attention이라면 Q, K, V의 차원이 모두 같다.)

※ 논문에서는 통상 Key의 차원이 매우 높기 때문에 (예를 들어 책 한권에 나오는 모든 단어가 key가 된다.) scaling을 하지 않으면 weight vector가 잘 계산되지 않는다고 한다.

지금까지 배운 것을 한번 시뮬레이션 해보자.

 

I, am, a, student라는 단어가 주어졌을 때 각각을 어떤 숫자로 vectorized 시켰다고 하자.

이 vector를 Wq, Wk, Wv로 parameterize시키면 I, am, a, student 각각의 Q, K, V 벡터를 얻을 수 있다.

 

그리고 'I'의 query를 각 단어에 scaled dot product self-attention을 해보자.

'I'의 query와 'I', 'am', 'a', 'student'의 key의 dot-product를 구하고 scaling 해 주면 각 단어들간의 유사도(Attention score)가 계산된다.

 

이 attention score에 softmax를 취해 합이 1인 값으로 바꿔보니 'I'는 'I'와 'student'간 유사도 높은 것을 확인할 수 있다. 이 값들을 모두 더하면 Attention value (혹은 Context vector)가 최종적으로 도출되게 된다.

7. Multi-Head Attention

앞서 Q, K, V를 Linear transform으로 parameterized 시켜 학습할 수 있게 만들었었다. 그런데 1개씩의 파라미터로 모델이 충분한 복잡성을 못 가질 수도 있기 때문에 여러번 Linear transform 시켜줄 수 있다. 이 개념이 Multi-head attention이다.
※ CNN에서 1개 이미지를 1개 필터로 Conv.하는 것이 아니라 여러개의 필터를 사용해서 많은 feature map을 뽑는 것과 동일하다.

Multi-head attention은 위에서 언급한 것 처럼 학습 파라미터 수를 늘려 모델의 복잡도를 올리는 방법이고 num_head는 하이퍼파라미터가 된다. (논문에서는 num_head = 8로 설정했다.)

 

Multi-head attention을 앞서 보여줬던 예제에 적용하면 위 그림과 같다. 동일한 과정을 num_head만큼 수행하는 것을 활인할 수 있다.

Encoder 그림의 가장 핵심인 Multi-head self-attention을 이해했다면 인코더의 80%는 이해한 것이다. Position Encoding이나 Position-wise Feedfoward net은 encoder, decoder 모두에서 사용되는 기법이니 곧 설명할 예정이다.

 

다시 한번 전체 모습을 살펴보면 Transformer는 3개의 attention을 가지고 있다.

  • Encoder self-attention : Encoder에 입력된 단어들의 self-attention
  • Decoder self-attention : Decoder에서 예측한 단어들의 self-attention
  • Encoder-Decoder attention :
    당연히 [10-2. Attention] 과 같이 입력 문장과 예측 문장간의 Attention이 필요하다.
    이 때 Q는 decoder에서, K, V는 encoder의 output에서 온다.

우리는 위 3가지 중 1, 2번째인 self-attention의 원리에 대해서 알게된 것이다.
그리고 Encoder-Decoder attention은 [10-2. Attention]과 동일하다.

그럼 이제 Encoder, Decoder에서 공통적으로 가지고 있는 Position-wise FFNN과 Positional Encoding에 대해서만 알면 필요한 기술은 모두 배운것이다. 

 

8. Position-wise Feedforward Networks

Transformer 모델은 Encoder-Decoder로 나눠져 있긴 하지만, Encoder, Decoder자체가 마치 hidden layer 처럼 여러층을 쌓을 수 있다. 이 때 Encoder layer를 Encoder #1, #2 이렇게 표현해 보자.

 

 

그리고 각 인코더는 위 그림과 같이 Fully Connected layer들로 이어져 있다.

위 식에서 x는 multi-head self-attention에서 나온 matrix이다.

즉, transformer model의 FFN은 1개 은닉층을 가지는 neural net이며, 논문에서는 hidden layer의 크기를 2048로 설정했다.

 

이 때 모델의 복잡도가 너무 올라가는 것을 고려한 skip connection과 layer normalization이 적용된다. 

  • skip connection은 CNN 포스트의 ResNet과 정확히 같은 개념이며,
  • layer normalization역시 CNN 포스트의 Layer normalization과 동일한 개념이기 때문에 자세한 설명은 생략하도록 한다.

9. Positional Encoding

앞의 과정을 상기해보면, Transformer 모델은 input sequence의 단어를 마치 python의 dictionary형태로 저장해놓고 self attention을 수행하는 것을 알 수 있다. 그런데 여기서 문제점은 각 단어의 벡터가 key로 등록은 되는데 몇 번째 단어인지는 알 수가 없다.
예를 들어 위 그림에서 'am'을 key값으로 찾을 순 있지만 2번째 있는 단어라는 것은 알 수가 없는 것이다.

그래서 Transformation model에서는 Positional Encoding 값을 embedding(vectorized word)에 더해줌으로써 위치 정보를 만들어 준다. 이 과정을 시각화 하면 아래와 같다.

 

위 그림을 보면 오른쪽에 있는 단어일 수록 positional encoding 값도 오른쪽이 큰 것을 알 수 있다. 어떻게 해야 이런 값을 만들 수 있을까?

위 식은 단어위 위치 pos와 각 단어의 벡터의 index i가 주어졌을 때 Positional Encoding(PE)값을 구하는 방법이다. 식으로는 이해가 어려우니 예제를 한번 살펴보자.

 

위 예제는 각 단어를 4차원으로 embedding 한 것을 가정한 것이다. (논문에는 128차원으로 embedding 했다.) 그리고 각 단어 vector의 i번째 차원값은 sin과 cos의 변환하면서 계산되고, 계산 결과 위 그림처럼 출력된다. 이게 어떤 의미를 가질까? PE의 단순한 예를 하나 더 살펴보자.

 

만약 우리가 10진수를 2진수로 표현한다고 가정해 보자. 2진수의 자릿수를 10개 (=차원)으로 나타낸다고 하면 위 그림과 같이 변환할 수 있다.

i=1의 값은 1, 0, 1, 0 순으로 빠르게 변하고, i=2의 값은 1, 1, 0, 0, 1, 1 과 같이 조금 늦게, i=3인 값은 1, 1, 1, 1, 0, , ... 더 늦게 변화하는 것을 확인할 수 있다. 

즉, word를 이런 방식으로 표현하면 만약 같은 단어가 2번 나왔더라도 어디쯤 위치한 word인지 알 수가 있다.  

 

위 그림은 126차원으로 embedding된 50개의 단어을 Positional Encoding 시킨 결과이다.

우리는 각 단어의 PE된 vector가 어떤 값을 갖는지는 알 필요가 없다. 하지만 컴퓨터에게는 이 vector로 하여금 각 단어의 위치정보를 알 수 있게 해준다. (이 위치정보를 알게 해주는것이 핵심!!)

 

지금까지 각 구성요소에 대해서 각각 살펴봤는데 이제 전체그림으로 조립해보자.

  • vectorized 된 단어들이 parameter를 가진 embedding으로 입력된다.
  • embedding된 단어가 위치 정보를 담을 수 있도록 Positional Encoding 된다.
  • 각 단어의 vector가 Self-Attention + FFNN 되는데, 일종의 "입력된 문장을 이해하는 과정"으로 볼 수 있다. 그리고 인코더는 num_layers만큼 쌓을 수 있다.
    ※ CNN으로 치면 Conv, Pooling을 반복하는 과정이다.
  • Encoder에서 출력된 Context vector를 통해 Decoder에서 단어를 예측하는데, 이 때는 Self-Attention이 아니라 Encoder-Decoder Attention을 수행한다.
  • 그리고 Decoder에서 예측된 단어들은 매번 Self-Attention을 통해, 일종의 "예측된 문장을 이해하는 과정"을 반복한다.

 

출처 : https://wikidocs.net/31379

 

1) 트랜스포머(Transformer)

* 이번 챕터는 앞서 설명한 어텐션 메커니즘 챕터에 대한 사전 이해가 필요합니다. 트랜스포머(Transformer)는 2017년 구글이 발표한 논문인

wikidocs.net

 

https://sonsnotation.blogspot.com/2020/11/10-3-transformer-model.html

 

[머신러닝/딥러닝] 10-3. Transformer Model

 

sonsnotation.blogspot.com

https://mangastorytelling.tistory.com/entry/%EB%94%A5%EB%9F%AC%EB%8B%9D%EC%9D%84%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9E%90%EC%97%B0%EC%96%B4-%EC%B2%98%EB%A6%AC-%EC%9E%85%EB%AC%B8-1701-%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%EB%A8%B8Transformer

 

[딥러닝을이용한 자연어 처리 입문] 1701 트랜스포머(Transformer)

- 2017년 구글이 발표한 논문인 "Attention is all you need"에서 나온 모델로 기존의 seq2seq의 구조인 인코더-디코더를 따르면서도, 논문의 이름처럼 어텐션(Attention)만으로 구현한 모델 - 이 모델은 RNN을..

mangastorytelling.tistory.com

 

https://blog.naver.com/PostView.nhn?blogId=winddori2002&logNo=222008003445&parentCategoryNo=1&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView 

 

[바람돌이/딥러닝] Transformer 이론 및 개념(Attention is all you need 리뷰)

안녕하세요. 오늘은 transformer에 대해 정리하겠습니다. 해당 내용은 'Attention is all you need&#...

blog.naver.com

https://engineering-ladder.tistory.com/73

 

Attention & Transformer의 개념

 이번 글에서는 시계열 분석에서 State-of-Art라고 할 수 있는, Transforemer에 대해 정리해보고자 한다. 일반적으로 시계열 분석이라 하면, Recurrent Neural Network (RNN)이나 Long-Short Term Memory (LSTM)..

engineering-ladder.tistory.com

https://123okk2.tistory.com/164

 

자연어 처리 : 트랜스포머

출처 : 동빈나 유튜브 www.youtube.com/watch?v=AA621UofTUA&t=44s *해당 글은 학습을 목적으로 위의 포스팅 내용 중 일부 내용만을 요약하여 작성한 포스팅입니다.  상세한 내용 및 전체 내용 확인은 위의

123okk2.tistory.com

 

'nlp_study' 카테고리의 다른 글

딥러닝 어텐션 (Attention)  (0) 2022.01.12

+ Recent posts