[Tensorflow] 3. Natural Language Processing in TensorFlow (3 week Sequence models) : programming (4)

gunny·2024년 4월 14일
0
post-thumbnail

[Tensorflow] 3. Natural Language Processing in TensorFlow (3 week Sequence models) : programming (4)

IMDB 리뷰 데이터세트용 모델 구축

  • 여기서는 4개의 모델을 구축하고 전체 단어 인코딩을 사용하여 IMDB 리뷰 데이터세트에서 모델을 학습해본다.
    여기서는 Embeding 후 Flatten, LSTM, GRU 및 Conv1D와 같은 다른 레이어를 사용해서 성능을 비교하고 이 특정 데이터 세트에 어떤 아키텍처가 가장 적합한지 확인한다.

[1] import

import tensorflow as tf
import numpy as np
import tensorflow_datasets as tfdf

from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

[2] Download and prepare the Dataset

이전 실습에서 사용했던 하위 단어 인코딩 세트와 달리 처음부터 어휘를 구축하고 패딩된 시퀀스를 생성해야 한다.
Tokenizer 클래스와 pad_sequences() 메서드를 사용하여 이를 수행한다.

imdb, info = tfdf.load('imdb_reviews', with_info=True, as_supervised=True)

train_data, test_data = imdb['train'], imdb['test']

training_sentences = []
training_labels = []

testing_sentences= []
testing_labels = []

for s,l in train_data:
    training_sentences.append(s.numpy().decode('utf8'))
    training_labels.append(l.numpy())
    
for s,l in test_data:
    testing_sentences.append(s.numpy().decode('utf8'))
    testing_labels.append(l.numpy())
    
training_labels_final = np.array(training_labels)
testing_labels_final = np.array(testing_labels)
tokenizer = Tokenizer(num_words=10000, oov_token='<OOV>')

tokenizer.fit_on_texts(training_sentences)
word_index = tokenizer.word_index

train_sequences = tokenizer.texts_to_sequences(training_sentences)
padded_train = pad_sequences(train_sequences, truncating='post', maxlen=120)

test_sequences = tokenizer.texts_to_sequences(testing_sentences)
padded_test = pad_sequences(test_sequences, truncating='post', maxlen=120)

[3] Plot Utility

모델을 정의하기 전에, 학습 후 정확도와 손실 내역을 쉽게 시각화할 수 있도록 시각화 하는 함수를 먼저 정의한다.

import matplotlib.pyplot as plt

# Plot Utility
def plot_graphs(history, string):
  plt.plot(history.history[string])
  plt.plot(history.history['val_'+string])
  plt.xlabel("Epochs")
  plt.ylabel(string)
  plt.legend([string, 'val_'+string])
  plt.show()

[4] Model build - (1) Flatten 레이어

  • 첫 번째 모델은 Flatten 레이어를 사용하는 것의 가장 큰 장점은 훈련 속도가 매우 빠르다는 것이다.

model_flatten = tf.keras.models.Sequential([
    tf.keras.layers.Embedding(10000, 16, input_length=120),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(6, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model_flatten.compile(loss='binary_crossentropy',
                      metrics=['accuracy'],
                      optimizer='adam')

model_flatten.summary()

history_flatten = model_flatten.fit(padded_train, training_labels_final,
                            epochs=10,
                            validation_data = (padded_test, testing_labels_final))

plot_graphs(history_flatten, 'accuracy')
plot_graphs(history_flatten, 'loss')

[4] Model build - (2) LSTM 레이어

  • 다음으로는 LSTM을 사용해본다. LSTM은 훈련 속도가 느리지만 토큰 순서가 중요한 애플리케이션에 유용하다.
model = tf.keras.models.Sequential([
    tf.keras.layers.Embedding(tokenizer.vocab_size, 64),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, return_sequences=True)),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

model.summary()

history = model.fit(train_dataset, 
                    epochs=10,
                    validation_data = test_dataset)

import matplotlib.pyplot as plt

# Plot utility
def plot_graphs(history, string):
  plt.plot(history.history[string])
  plt.plot(history.history['val_'+string])
  plt.xlabel("Epochs")
  plt.ylabel(string)
  plt.legend([string, 'val_'+string])
  plt.show()

# Plot the accuracy and results 
plot_graphs(history, "accuracy")
plot_graphs(history, "loss")

[4] Model build - (3) GRU 레이어

  • Gated Recurrent Unit(GRU)은 일반적으로 LSTM의 간단한 버전이다. 순서가 중요하지만 더 빠른 결과를 원하고 정확도가 어느 정도 희생될 수 있는 응용 분야에 사용한다. 모델 요약을 보면 LSTM보다 약간 작고 훈련 속도도 몇 초 더 빠르다는 것을 알 수 있다.
# model 3 - GRU

model_gru = tf.keras.models.Sequential([
    tf.keras.layers.Embedding(10000, 16, input_length=120),
    tf.keras.layers.Bidirectional(tf.keras.layers.GRU(32)),
    tf.keras.layers.Dense(6, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model_gru.compile(loss='binary_crossentropy',
                  metrics=['accuracy'],
                  optimizer='adam')

model_gru.summary()

history_gru = model_gru.fit(padded_train, training_labels_final,
                            epochs=10,
                            validation_data = (padded_test, testing_labels_final))

plot_graphs(history_gru, 'accuracy')
plot_graphs(history_gru, 'loss')

[4] Model build - (4) Convolution 레이어

  • 마지막으로 컨볼루션 레이어를 사용하여 데이터세트에서 특징을 추출한다.
    결과를 DEnse 레이어에 전달하기 전에 GlobalAveragePooling1d 레이어를 추가하여 결과를 줄인다. Flatten을 사용한 모델과 마찬가지로 이 모델도 LSTM 및 GRU와 같은 RNN 레이어를 사용하는 모델보다 훨씬 빠르게 학습된다.
# model 4 - Convolution

model_conv = tf.keras.models.Sequential([
    tf.keras.layers.Embedding(10000, 16, input_length=120),
    tf.keras.layers.Conv1D(filters=128, kernel_size=5, activation='relu'),
    tf.keras.layers.GlobalMaxPooling1D(),
    tf.keras.layers.Dense(6, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model_conv.compile(loss='binary_crossentropy',
                   metrics=['accuracy'],
                   optimizer='adam')

model_conv.summary()

history_conv = model_conv.fit(padded_train, training_labels_final,
                              epochs=10,
                              validation_data = (padded_test, testing_labels_final))

plot_graphs(history_conv, 'accuracy')
plot_graphs(history_conv, 'loss')

profile
꿈꾸는 것도 개발처럼 깊게

0개의 댓글