시계열 또는 일반적인 시퀀스 데이터를 처리할 수 있는 딥러닝 모델을 살펴보겠습니다. 시퀀스 데이터를 처리하는 기본적인 딥러닝 모델은 순환 신경망(enn)과 1D 컨브넷(1D convnet) 두 가지입니다.
1. 테스트 데이터 다루기
텍스트는 가장 흔한 시퀀스 형태의 데이터입니다. 텍스트는 단어의 시퀀스나 문자의 시퀀스로 이해할 수 있습니다. 다른 모든 신경망과 마찬가지로 텍스트 원본을 입력으로 사용하지 못합니다. 딥러닝 모델은 수치형 텐서만 다룰 수 있습니다. 텍스트를 수치형 텐서로 변환하는 과정을 텍스트 벡터화라고 합니다.
다음과 같은 방법이 있습니다.
- 텍스트를 단어로 나누고 각 단어를 하나의 벡터를 변환합니다.
- 텍스트를 문자로 나누고 각 문자를 하나의 벡터로 변환합니다.
- 텍스트에서 단어나 문자의 n-그램(n-gram)을 추출하여 각 n-그램을 하나의 벡터로 변환합니다. n-그램은 연속된 단어나 문자의 그룹으로 텍스트에서 단어나 문자를 하나씩 이동하면서 추출합니다.
텍스트를 나누는 이런 단위를 토큰이라고 합니다. 그리고 텍스트를 토큰으로 나누는 작업을 토큰화라고 합니다. 모든 텍스트 벡터화 과정은 어떤 종류의 토큰화를 적용하고 생성된 토큰에 수치형 벡터를 연결하는 것으로 이루어집니다. 이런 벡터는 시퀀스 텐서로 묶여져서 심층 신경망에 주입됩니다.
토큰과 벡터를 연결하는 방법은 여러 가지가 있습니다. 토큰의 원-핫 인코딩과 토큰 임베딩(일반적으로 단어에 대해서만 사용되므로 단어 임베딩이라고 부릅니다.)입니다.
단어 n-그램은 문장에서 추출한 N개(또는 그 이하)의 연속된 단어 그룹입니다. 같은 개념이 단어 대신 문자에도 적용될 수 있습니다. 만약 2-그램 또는 3-그램을 2-그램을 2-그램 가방, 3-그램 가방이라고 합니다. 가방(bag)이란 용어는 다루고자 하는 것이 리스트나 시퀀스가 아니라 토큰의 집합이라는 사실을 의미합니다. 이 토큰에는 특정한 순서가 없습니다. 이런 종류의 토큰화 방법을 BoW(Bag-of-Words)라고 합니다.
BoW가 순서가 없는 토큰화 방법이기 때문에 딥러닝 모델보다 얕은 학습 방법의 언어 처리 모델에 사용되는 경향이 있습니다.
2. 단어와 문자의 원-핫 인코딩
원-핫 인코딩은 토큰을 벡터로 변환하는 가장 일반적이고 기본적인 방법입니다. 케라스에는 원본 텍스트 데이터를 단어 또는 문자 수준의 원-핫 인코딩으로 변환해 주는 유틸리티가 있습니다. 특수 문자를 제거하거나 빈도가 높은 N개의 단어만 선택하는 등 여러 가지 중요한 기능들이 있기 때문에 이 유틸리티를 사용하는 것이 좋습니다.
from keras.preprocessing.text import Tokenizer
samples = ['The cat sat on the mat.', 'The dog ate my homework.']
#가장 빈도가 높은 1,000개의 단어만 선택하도록 Tokenizer객체를 만듭니다.
tokenizer = Tokenizer(num_words=10000)
#단어 인덱스를 구축합니다.
tokenizer.fit_on_texts(samples)
#문자열을 정수 인덱스의 리스트로 변환합니다.
sequences = tokenizer.texts_to_sequences(samples)
#직접 원-핫 이진 벡터 표현을 얻을 수 있습니다. 원-핫 인코딩 외에 다른 벡터화 방법들도 제공합니다.
one_hot_results = tokenizer.texts_to_matrix(samples, mode='binary')
#계산된 단어 인덱스를 구합니다.
word_index = tokenizer.word_index
print(len(word_index))
print(word_index)
3. 단어 임베딩 사용하기
단어와 벡터를 연관 짓는 강력하고 인기 있는 또 다른 방법은 단어 임베딩이라는 밀집 단어 벡터(word vector)를 사용하는 것입니다. 원-핫 인코딩으로 만든 벡터는 희소(sparse)하고(대부분 0으로 채워집니다.) 고차원입니다.(어휘 사전에 있는 단어의 수와 차원이 같습니다.) 반면에 단어 임베딩은 저차원의 실수형 벡터입니다. (희소 벡터의 반대인 밀집 벡터입니다.) 원-핫 인코딩으로 얻은 단어 벡터와 달리 단어 임베딩은 데이터로부터 학습됩니다.
단어 임베딩을 만드는 방법은 두 가지입니다.
- (문서 분류나 감성 예측 같은) 관심 대상인 문제와 함께 단어 임베딩을 학습합니다. 이런 경우에는 랜덤 한 단어 벡터로 시작해서 신경망의 가중치를 학습하는 것과 같은 방식으로 단어 벡터를 학습합니다.
- 풀려는 문제가 아니고 다른 머신 러닝 작업에서 미리 계산된 단어 임베딩을 로드합니다. 이를 사전 훈련된 단어 임베딩이라고 합니다.
4. 기본 Embedding 프로그램 실습
Embedding층에 사용할 IMDB 데이터 로드하기
from keras.datasets import imdb
from keras import preprocessing
#특성으로 사용할 단어의 수
max_features = 10000
#사용할 텍스트의 길이(가장 빈번한 max_features개의 단어만 사용합니다.)
maxlen = 20
#정수 리스ㅡ로 데이터를 로드합니다.
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words = max_features)
#리스트를(samples, maxlen)크기의 2D 정수 텐서로 변환합니다.
x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=maxlen)
IMDB데이터에 Embedding층과 분류기 사용하기
from keras.models import Sequential
from keras.layers import Flatten, Dense, Embedding
model = Sequential()
#나중에 임베딩된 입력을 Flatten 층에서 펼치기 위해 Embeding층에 input_length를 지정합니다.
#Embedding 층의 출력 크기는 (samples, maxlen, 8)이 됩니다.
model.add(Embedding(10000, 8, input_length=maxlen))
#3D 임베딩 텐서를 (samples, maxlen*8) 크기의 2D 텐서로 펼칩니다.
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
model.summary()
history = model.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.2)
test_mse_score, test_mae_score = model.evaluate(x_test, y_test)
print(test_mse_score, test_mae_score)
상기 프로그램을 실행하면 accurate가 75% 정도의 검증 정확도가 나옵니다. 하지만 임베딩 시퀀스를 펼치고 하나의 Dense층을 훈련했으므로 입력 시퀀스에 있는 각 단어를 독립적으로 다루었습니다. 단어 사이의 관계나 문장 구조를 고려하지 않았습니다. 각 시퀀스 전체를 고려한 특성을 학습하도록 임베딩 층 위에 순환 층이나 1D 합성곱 층을 추가하는 것이 좋습니다.
'Lecture AI > 6장.텍스트와 시퀀스를 위한 딥러닝' 카테고리의 다른 글
5. 온도예측 실습과 함께 알아보는 순환 신경망의 고급 사용법 : 드럽아웃, 스테킹 순환층, 양방향 RNN (0) | 2021.07.26 |
---|---|
4. 온도예측 실습과 함께 알아보는 순환 신경망의 고급 사용법 (0) | 2021.07.24 |
3. 순환 신경망의 이해와 SimpleRNN과 LSTM의 차이 (0) | 2021.07.23 |
2. 모든 내용을 적용하기: 원본 텍스에서 단어 임베딩까지 (0) | 2021.07.22 |