< Simple RNN 단점 >
- 긴 문장(시퀀스)을 학습하기 어려움
- 시퀀스가 길 수록 초반의 정보는 점진적으로 희석(소멸)됨
즉, 멀리 떨어져있는 단어의 정보를 인식하는데 어려움이 있음
- 이러한 단점을 보완한 모델이 LSTM과 GRU
< LSTM(Long Shot Term Memory , 장기기억) >
- 단기기억을 오래 기억할 수 있도록 고안된 모델
- 많은 이전 정보를 기억해야 하기 때문에 훈련속도가 느리며,
시스템 저장 공간이 많이 필요함
< GRU(Gated Recurrent Unit , 게이트 반복 단위) >
- LSTM의 느린 속도를 개선하기 위해 고안된 모델
- 성능은 LSTM과 유사함
** SImple RNN , LSTM , GRU 모두 RMSprop 옵티마이저를 일반적으로 사용함
◇ 데이터 불러들이기
- IMDB 데이터 사용 , 말뭉치 500개
○ 라이브러리
import tensorflow as tf
from tensorflow import keras
# 영화 감상평에 대한 긍정/부정 데이터셋
from tensorflow.keras.datasets import imdb
○ 데이터 불러들이기
#데이터 불러들이기
# - IMDB 데이터 사용 , 말뭉치 500개 사용
(train_input , train_target), (test_input , test_target) = imdb.load_data(num_words=500)
print(train_input.shape , train_target.shape)
print(test_input.shape , test_target.shape)
(25000,) (25000,)
(25000,) (25000,)
◇ 훈련 : 검증 데이터로 분류하기 ( 8:2 )
from sklearn.model_selection import train_test_split
train_input,val_input,train_target,val_target = train_test_split(train_input,train_target,test_size=0.2,random_state=42)
print(train_input.shape , train_target.shape)
print(val_input.shape , val_target.shape)
print(test_input.shape , test_target.shape)
(20000,) (20000,)
(5000,) (5000,)
(25000,) (25000,)
◇ 정규화(텍스트 길이 맞추기)
- 훈련, 검증, 테스트 데이터 내의 각 문장의 길이를 100으로 통일(정규화)시키기
- 행렬을 기준으로 하는 훈련은 행렬이 동일해야한다.
- 100이라는 기준은 변경 가능 ( 빈도수 가장 높은 것 기준으로 설정함 )
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 훈련 독립변수 각 데이터 100개로 통일시키기
train_seq = pad_sequences(train_input,maxlen=100)
val_seq = pad_sequences(val_input,maxlen=100)
test_seq = pad_sequences(test_input,maxlen=100)
train_seq.shape, val_seq.shape, test_seq.shape
((20000, 100), (5000, 100), (25000, 100))
◇ LSTM 모델 훈련
① 모델 생성하기
from tensorflow.keras.models import Sequential
model = Sequential()
② 계층 추가하기
- 임베딩 계층 추가 : 말뭉치 500, 출력크기 16, 입력크기 100
- LSTM 계층 추가 : 출력크기 8
- 출력계층 추가
# 계층 생성 및 모델에 추가하기
model.add(keras.layers.Embedding(500,16,input_length=100))
model.add(keras.layers.LSTM(8))
model.add(keras.layers.Dense(1,activation='sigmoid'))
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding (Embedding) (None, 100, 16) 8000
lstm (LSTM) (None, 8) 800
dense (Dense) (None, 1) 9
=================================================================
Total params: 8,809
Trainable params: 8,809
Non-trainable params: 0
_________________________________________________________________
③ 모델 설정하기
- 학습율 : 0.0001
- 옵티마이저 : rmsprop
rmsprop = tf.keras.optimizers.RMSprop(learning_rate=0.0001)
model.compile(loss='binary_crossentropy',optimizer=rmsprop,metrics=['accuracy'])
④ 콜백함수 생성하기
- 자동 저장 위치 및 파일명 : ./model/best_LSTM_model.h5
- 자동 저장 및 자동 종료 콜백함수 정의하기
checkpoint_cb = tf.keras.callbacks.ModelCheckpoint(
"./model/best_LSTM_model.h5",
save_best_only=True
)
earlystop_cb = tf.keras.callbacks.EarlyStopping(
patience = 3, restore_best_weights=True
)
⑤ 모델 훈련시키기
model.fit(train_seq,train_target,epochs=100,batch_size=64,
validation_data = (val_seq,val_target),
callbacks=[checkpoint_cb,earlystop_cb])
Epoch 60/100
313/313 [==============================] - 5s 15ms/step - loss: 0.3977 - accuracy: 0.8203 - val_loss: 0.4280 - val_accuracy: 0.8038
▶ 60번 까지 훈련됨
⑥ 성능 평가하기
print(model.evaluate(train_seq,train_target))
print(model.evaluate(val_seq,val_target))
print(model.evaluate(test_seq,test_target))
625/625 [==============================] - 2s 3ms/step - loss: 0.3970 - accuracy: 0.8217
[0.39702126383781433, 0.8216500282287598]
157/157 [==============================] - 0s 3ms/step - loss: 0.4263 - accuracy: 0.8054
[0.42634081840515137, 0.805400013923645]
782/782 [==============================] - 3s 3ms/step - loss: 0.4238 - accuracy: 0.8044
[0.4237663149833679, 0.8043599724769592]
▶정확도 : 훈련 > 검증 > 테스트 이므로 과대적합, 과소적합이 일어나지않음
◇ LSTM 모델에 드롭아웃 속성(계층 아님) 적용하기
- LSTM 모델(계층)에 드롭아웃 속성 적용, 30% 훈련에서 제외
- 나머지 모두 위와 동일하게 처리하여 훈련, 검증 , 테스트 데이터에 대한 성능검증까지 진행하기
○ 드롭 아웃 속성 적용
model_do = Sequential()
model_do.add(keras.layers.Embedding(500,16,input_length=100))
model_do.add(keras.layers.LSTM(8,dropout=0.3))
model_do.add(keras.layers.Dense(1,activation='sigmoid'))
model_do.summary()
Model: "sequential_3"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_3 (Embedding) (None, 100, 16) 8000
lstm_3 (LSTM) (None, 8) 800
dense_3 (Dense) (None, 1) 9
=================================================================
Total params: 8,809
Trainable params: 8,809
Non-trainable params: 0
_________________________________________________________________
○ 성능 검증하기
625/625 [==============================] - 2s 3ms/step - loss: 0.4067 - accuracy: 0.8149
[0.4067215919494629, 0.8148999810218811]
157/157 [==============================] - 1s 3ms/step - loss: 0.4300 - accuracy: 0.8012
[0.4299856424331665, 0.8011999726295471]
782/782 [==============================] - 3s 3ms/step - loss: 0.4257 - accuracy: 0.8020
[0.4256991744041443, 0.8019599914550781]
▶ 성능이 검증결과 정확도는 비슷하지만 약간 감소함
◇ LSTM 2개 연결하기
- LSTM 2개를 연결할 때는 연속해서 LSTM 계층을 추가해야함
- 첫번째 LSTM 계층의 속성에는 return_sequences = True 속성을 추가해준다.
- 두번째 LSTM은 첫번째 LSTM의 훈련결과를 이어받아서 계속 훈련을 이어나간다.
model = Sequential()
model.add(keras.layers.Embedding(500,16,input_length=100))
# LSTM 계층 2개
model.add(keras.layers.LSTM(8,dropout=0.3,return_sequences=True))
model.add(keras.layers.LSTM(8,dropout=0.2))
model.add(keras.layers.Dense(1,activation='sigmoid'))
rmsprop = tf.keras.optimizers.RMSprop(learning_rate=0.0001)
model.compile(loss='binary_crossentropy',optimizer=rmsprop,metrics=['accuracy'])
checkpoint_cb = tf.keras.callbacks.ModelCheckpoint(
"./model/best_LSTM_model.h5",
save_best_only=True
)
earlystop_cb = tf.keras.callbacks.EarlyStopping(
patience = 3, restore_best_weights=True
)
history = model.fit(train_seq,train_target,epochs=100,batch_size=64,
validation_data = (val_seq,val_target),
callbacks=[checkpoint_cb,earlystop_cb])
Epoch 41/100
313/313 [==============================] - 9s 29ms/step - loss: 0.4195 - accuracy: 0.8081 - val_loss: 0.4345 - val_accuracy: 0.7964
print(model.evaluate(train_seq,train_target))
print(model.evaluate(val_seq,val_target))
print(model.evaluate(test_seq,test_target))
625/625 [==============================] - 5s 6ms/step - loss: 0.4090 - accuracy: 0.8130
[0.4090471565723419, 0.8130000233650208]
157/157 [==============================] - 1s 6ms/step - loss: 0.4341 - accuracy: 0.7960
[0.43414419889450073, 0.7960000038146973]
782/782 [==============================] - 5s 6ms/step - loss: 0.4316 - accuracy: 0.7962
[0.43158358335494995, 0.7961599826812744]
▶ 성능이 높아지지 않고 약간 낮아졌기 때문에 2개를 추가할 필요가 없다고 판단됨
◇ GRU 모델
model = Sequential()
model.add(keras.layers.Embedding(500,16,input_length=100))
# GRU 계층 추가
model.add(keras.layers.GRU(8))
model.add(keras.layers.Dense(1,activation='sigmoid'))
rmsprop = tf.keras.optimizers.RMSprop(learning_rate=0.0001)
model.compile(loss='binary_crossentropy',optimizer=rmsprop,metrics=['accuracy'])
checkpoint_cb = tf.keras.callbacks.ModelCheckpoint(
"./model/best_GRU_model.h5",
save_best_only=True
)
earlystop_cb = tf.keras.callbacks.EarlyStopping(
patience = 3, restore_best_weights=True
)
history = model.fit(train_seq,train_target,epochs=100,batch_size=64,
validation_data = (val_seq,val_target),
callbacks=[checkpoint_cb,earlystop_cb])
Epoch 33/100
313/313 [==============================] - 6s 20ms/step - loss: 0.4148 - accuracy: 0.8160 - val_loss: 0.4427 - val_accuracy: 0.7936
print(model.evaluate(train_seq,train_target))
print(model.evaluate(val_seq,val_target))
print(model.evaluate(test_seq,test_target))
625/625 [==============================] - 2s 4ms/step - loss: 0.4130 - accuracy: 0.8181
[0.4129924774169922, 0.818149983882904]
157/157 [==============================] - 1s 3ms/step - loss: 0.4425 - accuracy: 0.7926
[0.4424968659877777, 0.7925999760627747]
782/782 [==============================] - 3s 3ms/step - loss: 0.4379 - accuracy: 0.7967
[0.43787285685539246, 0.7966799736022949]
▶ LSTM 과 비교했을때 성능이 거의 비슷하지만 다소 낮게 나온 것을 확인할 수 있다.
'머신러닝&딥러닝' 카테고리의 다른 글
[딥러닝] 합성곱신경망(CNN)을 이용한 이미지 분류 (1) | 2024.01.08 |
---|---|
[딥러닝] RNN응용 규칙기반 챗봇 (0) | 2024.01.08 |
[딥러닝] 순환신경망(RNN) - 심플 순환신경망(Simple RNN) (1) | 2024.01.05 |
[딥러닝] 퍼셉트론 - 분류데이터 사용 (1) | 2024.01.05 |
[딥러닝] DNN 분류데이터 사용(실습) (4) | 2024.01.04 |