Python/Tensorflow

[Tensorflow] 파이썬 keras RNN/LSTM/GRU 구현 예제(IMDB 감성 분석)

jimmy_AI 2022. 6. 17. 22:57
반응형

텐서플로우 케라스 SimpleRNN, LSTM, GRU layer 쌓기 예시

파이썬의 텐서플로우 2.x 버전에서 keras 모듈을 활용하여 RNN 시리즈 모델들의 layer를

양방향, 다중층 등으로 쌓는 방법들을 다루어보도록 하겠습니다.

(데이터셋은 tensorflow에서 제공하는 IMDB 감정 분류 데이터셋을 활용하였습니다.)

 

 

데이터셋 로드, 전처리

tensorflow의 데이터셋 모듈에서 제공하는 IMDB 데이터셋을 불러오고

RNN 모델 적용을 위한 간단한 전처리를 진행해보겠습니다.

해당 과정의 코드는 아래 링크의 텐서플로우 공식 사이트 글을 참조하였습니다.

 

RNN을 사용한 텍스트 분류  |  TensorFlow Core

Google I/O는 끝입니다! TensorFlow 세션 확인하기 세션 보기 RNN을 사용한 텍스트 분류 이 텍스트 분류 튜토리얼은 감정 분석을 위해 IMDB 대형 영화 리뷰 데이터세트로 순환 신경망을 훈련합니다. 설정

www.tensorflow.org

# tfds import 실패시에는 !pip install -q tfds-nightly로 모듈 설치 후 재시도
import tensorflow_datasets as tfds

dataset, info = tfds.load('imdb_reviews/subwords8k', with_info=True,
                          as_supervised=True)
train_dataset, test_dataset = dataset['train'], dataset['test']

위의 데이터셋을 불러오는 코드 실행에는 수 분 가량이 소요될 수 있습니다.

 

문장 sequence의 길이가 각기 다를 수 있기에 각 배치 내에서 가장 긴 길이에 맞추어

남는 길이 만큼 padding을 해주는 전처리 과정을 진행해보도록 하겠습니다.

# 배치에서 가장 긴 길이로 padding
batch_size = 32
train_dataset = train_dataset.padded_batch(batch_size)
test_dataset = test_dataset.padded_batch(batch_size)

이제, 데이터셋의 라벨인 긍정/부정(1/0) 여부를 예측해보는 RNN 계열 모델을 구현해보겠습니다.

 

 

RNN 계열 모델 layer 쌓기 baseline 코드

위에서 불러온 데이터셋에서 RNN 종류의 모델 layer를 쌓는 기본적인 구조는

임베딩 지정 - RNN 파트 - fc layer 부분으로 나뉩니다.

 

fc layer의 세부적인 사항(dropout 적용 여부, 중간 layer 히든 유닛 개수, 활성 함수 종류 등)을

자유롭게 바꾸셔도 좋으나, 마지막 layer는 이진 분류를 위하여 유닛 = 1, sigmoid 활성 함수

지정해주신 뒤 사용하셔야 합니다.

 

저희가 다양한 형태로 변경을 시도할 부분은 가운데의 RNN 파트임을 참고해주세요.

세 파트의 구현부를 합친 코드의 예시는 다음과 같습니다.

from tensorflow.keras import models, layers

model = models.Sequential()
# RNN 적용을 위한 임베딩 지정
model.add(layers.Embedding(info.features['text'].encoder.vocab_size, batch_size))

### RNN 파트 시작점 ###

# 단일 SimpleRNN, 단일 방향 예시
model.add(layers.SimpleRNN(16)) # 유닛 개수 = 16 예시(변경 가능)

### RNN 파트 끝점 ###

# fc layer 부분(32 차원 변환 -> dropout -> 이진 분류 결과)
model.add(layers.Dense(32, activation = 'relu'))
model.add(layers.Dropout(0.2))
model.add(layers.Dense(1, activation = 'sigmoid')) # 이진 분류를 위한 마지막 layer 설정

# 선언 모델 학습 부분
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics = ['accuracy'])

history = model.fit(train_dataset, epochs = 3, batch_size = batch_size, verbose = 1, validation_data = test_dataset)

 

반응형

 

케라스에서 제공하는 Sequential 기능을 통하여 모델의 layer들을 순차적으로 쉽게 쌓을 수

있었으며, 선언 이후에는 학습을 진행하는 코드를 작성했습니다.

 

(optimizer, epochs 등 조건은 자유롭게 지정하면 되며, verbose = 1로 진행 상황을 출력 받고

validation_data를 지정하여 테스트 데이터셋의 정확도를 출력받을 수 있습니다.)

 

실행 결과 출력의 예시는 아래와 같습니다.(양방향 다중층 LSTM의 결과입니다.)

3 epochs 경과 후, 테스트 데이터의 정확도 성능은 약 82.86%로 측정되었습니다.

 

 

SimpleRNN, LSTM, GRU 양방향 및 다중층 적용 방법

윗 코드에서 RNN 파트 부분(### 주석 사이)을 자유롭게 바꾸면서

모델의 구조 및 bidirection/multi-layer 형태 등을 지정할 수 있습니다.

 

참고로, 세 RNN 계열 모델 layer 메소드들의 사용 방법은 거의 비슷합니다.

양방향 및 다중층 지정을 포함한 SimpleRNN, LSTM, GRU의 적용 코드 예시는 아래와 같습니다.

# 윗 코드의 ### 사이의 RNN 파트 부분에 원하는 형태 1개를 골라서 넣어주시면 됩니다.

# 단일 SimpleRNN, 양방향 예시
model.add(layers.Bidirectional(layers.SimpleRNN(16)))

# 이중층 SimpleRNN, 양방향 예시(RNN 파트의 마지막 layer가 아니라면 return_sequences=True 지정)
model.add(layers.Bidirectional(layers.SimpleRNN(16, return_sequences=True)))
model.add(layers.Bidirectional(layers.SimpleRNN(16)))

# 이중층 LSTM, 양방향 예시
model.add(layers.Bidirectional(layers.LSTM(16, return_sequences=True)))
model.add(layers.Bidirectional(layers.LSTM(16)))

# 이중층 GRU -> SimpleRNN, 단일 방향 예시
model.add(layers.GRU(16, return_sequences=True))
model.add(layers.SimpleRNN(16))

위의 코드 형태처럼 양방향인 경우에는 Bidirectional 메소드로 감싸주시면 되며,

다중층의 경우는 last layer가 아닌 부분에서 return_sequences 인자를 True로 지정하시면

적용이 가능합니다. 또한, 여러 형태의 RNN 구조를 각 층에서 사용한 형태의 혼합도 가능합니다.