We-Co

[We-Co] Bidirectional RNN 예제 - MDB Movie Review 본문

Python/Tensorflow

[We-Co] Bidirectional RNN 예제 - MDB Movie Review

위기의코딩맨 2021. 10. 2. 00:55
반응형

안녕하세요. 위기의코딩맨입니다.

오늘은 Bidirectional RNN예제를 한번 풀어보도록 하겠습니다.

예제는 MDB에 영화 리뷰를 학습하여 긍정리뷰, 부정 리뷰를 판단하는 학습을 진행하도록 하겠습니다.

 

Bidirectional RNN은 자연어처리에 적합한 구조를 갖고있습니다.

"파란 바다에 배가 떠있다"의 문자로 예를 들어보겠습니다.

"파란 바다에 O가 떠있다"로 O를 예측하기 위해서는

"파란->"바다"로 O를 유추하는 것보다

"파란"->"바다"-> O<-"떠있다" 

"떠있다" 문자도 같이 사용하여 O를 유추하는 방법을 의미합니다.

앞, 뒤 문자열을 고려한다고 생각하시면 됩니다. 

Bidirectional RNN 구조

[ 예제 ]

import tensorflow as tf

import tensorflow_datasets as tfds 

import matplotlib.pyplot as plt

 

먼저, 사용할 패키지들을 import를 진행해줍니다.

 

 

Dataset_, Info_ = tfds.load('imdb_reviews/subwords8k', with_info=True, as_supervised=True)

Train_Dataset, Test_Dataset = Dataset_['train'], Dataset_['test'

Encoder_ = Info_.features['text'].encoder

print('Size : {}'.format(Encoder_.vocab_size)) 

 

tfds.load()를 통해서 imdb 영화 리뷰에 데이터를 다운받고 Dataset_에 저장합니다.

그리고 Train Data와 Test Data를 따로 나누어 저장하고, Info Data를 Encoding하여 저장합니다.

사이즈를 확인해보니 8185의 사이즈가 출력됩니다.

 

 

Sample_String = "Hello WE-CO"

Encode_String = Encoder_.encode(Sample_String)

Original_String = Encoder_.decode(Encode_String) 

print(Encode_String)

print(Original_String) 

for index in Encode_String:

  print('{} ----> {}'.format(index, Encoder_.decode([index]))) 

 

먼저, Encoding의 방식을 한번 살펴보면 "Hello WE-Co"의 데이터로 인코딩하고 그 데이터를 확인해보도록 하겠습니다.

[4025, 222, 6306, 7974, 2341]

Hello WE-CO 

4025 ----> Hell

222 ----> o

6306 ----> WE

7974 ----> -

2341 ----> CO

해당 문자열들의 Encoding Data내용과 원래 문자열을 나타냅니다.

 

 

Buffer_Size = 10000

Batch_Size = 64 

Train_Dataset = Train_Dataset.shuffle(Buffer_Size)

Train_Dataset = Train_Dataset.padded_batch(Batch_Size)

Test_Dataset = Test_Dataset.padded_batch(Batch_Size)

Buffer 사이즈를 정하고, Batch 사이즈를 정하고 적용을하고

padded_batch()를 적용해줍니다. 이 작업은 학습 데이터에서 가장 큰 문자열 사이즈를 기준으로

나머지 학습 데이터들을 기준에 맞춰 부족한 부분을 0으로 채워주는 작업을 진행합니다.

 

for x, y in Train_Dataset.take(1):

  print(x)

  print(y) 

tf.Tensor( [[ 62 32 217 ... 0 0 0] [ 156 37 270 ... 0 0 0] [ 12 1479 7 ... 0 0 0] ... [ 62 27 9 ... 0 0 0] [3742 2128 3773 ... 0 0 0] [ 62 1387 1033 ... 0 0 0]], shape=(64, 965), dtype=int64)

tf.Tensor( [0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 1 1 1 0 1 0 0 0 0 1 0 0 0 1 1 0 0 1 0 1 1], shape=(64,), dtype=int64)

확인해보면 뒤에 ..000으로 되어 있는부분이 부족한 부분 0으로 채워진것을 의미합니다.

그리고 y는 0,1 값으로 채워져있는데 0이면 부정 1이면 긍정으로 나타나있습니다.

 

# Bidirectional 모델을 선언

model = tf.keras.Sequential([

    tf.keras.layers.Embedding(Encoder_.vocab_size, 64),

    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),

    tf.keras.layers.Dense(64, activation='relu'),

    tf.keras.layers.Dense(1)

    ])

처음 8185의 one-hot-Encoding Data를 64차원 Embedding으로 넘기고

Bidirectional로 Layer를 적용하고 LSTM 64차원으로 넘깁니다.

64차원으로 또 넘기고 마지막에 1이면 긍정, 0이면 부정인 아웃풋 레이어를 적용합니다.

 

 

 

Learning_Rate = 1e-4

Epochs = 10

Steps = 30

 

model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), 

              optimizer=tf.keras.optimizers.Adam(Learning_Rate),

              metrics=['accuracy'])

history = model.fit(Train_Dataset, epochs=Epochs, validation_data=Test_Dataset, validation_steps= Steps)

 

Learning_Rate는 0.00001로 적용하고, Epochs는 10, Steps은 30으로 설정하고 학습을 진행했습니다.

 

학습중

Test_Loss, Test_Acc = model.evaluate(Test_Dataset) 

391/391 [==============================] - 50s 128ms/step - loss: 0.4355 - accuracy: 0.8588 

테스트 데이터를 통해서 85%정도의 정확도를 갖고 있는것을 확인했습니다.

 

 

def Sample_Predic(Sample_String):

  encoded_sample_pred_text = Encoder_.encode(Sample_String) 

  encoded_sample_pred_text = tf.cast(encoded_sample_pred_text, tf.float32)

  predictions = model.predict(tf.expand_dims(encoded_sample_pred_text, 0))

  return(predictions)

제가 입력한 데이터가 부정인지 긍정인지 알아보도록

직접 모델에 적용하는 Sample_Predic()함수를 만들었습니다.

 

sample_pred_text = ('The movie was perfect')

predictions = Sample_Predic(sample_pred_text)

print(predictions)

[[1.0616964]]

0.5이상이 나오면 긍정적인 리뷰로 나타냅니다.

 

sample_pred_text = ('this movie was very worst')

predictions = Sampe_Predic(sample_pred_text)

print(predictions)

[[-0.71787643]]

부정적인 리뷰는 -숫자가 나오는 것을 확인하실 수 있습니다.

 

 

오늘은 Bidirectional RNN의 예제를 MDB Movie Review 데이터를 통해

한 번 풀어보았습니다.

 

반응형