Data Analyst KIM

[Deep Learning] RNN,LSTM의 개념 및 로이터 뉴스 카테고리 분류하기 본문

데이터 분석/ML&DL&NLP

[Deep Learning] RNN,LSTM의 개념 및 로이터 뉴스 카테고리 분류하기

김두연 2023. 10. 26. 15:03
반응형

순환 신경망(RNN, Recurrent Neural Network)

  • 연속된 데이터가순서대로 입력되었을때 앞서 입력받은데이터를 잠시 기억해 놓는 방법
  • 기억된 데이터 당 중요도 가중치를 주면서다음 데이터로 넘어감
  • 모든 입력 값에 이 작업을 순서대로실행. 다음 층으로넘어가기 전 같은 층을 맴도는 것처럼보임

 

LSTM(Long Short Term Memory)  → RNN의 기울기 소실 문제 보완을위해 나온 방법

  • 한 층에서반복되기 직전에 다음 층으로 기억된 값을 넘길지 관리하는단계를 하나 더 추가하는것

 


1. LSTM을 이용한 로이터 뉴스 카테고리 분류하기

  • 입력된 문장의 의미를 파악하는 것은 모든 단어를 종합하여 하나의 카테고리로 분류하는 작업
  • 로이터 뉴스를 읽고 어떤 의미를 지니는지 카테고리 분류
    • 로이터 뉴스 데이터 : 11,228개 뉴스 기사,46개 카테고리

 

  1. 라이브러리 불러오기
  2. train / test 나누기 & num_words=1000으로 단어 설정
  3. sequence의 pad_sequences(..,maxlen=100)으로 단어 수를 맞춤
  4. 원-핫 인코딩 처리
  5. 모델 구조 및 옵션 설정
  6. 모델 실행 및 정확도 출력
  7. train / test 오차 저장 및 그래프 시각화
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, Embedding
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.preprocessing import sequence
from tensorflow.keras.datasets import reuters       # 로이터 뉴스 데이터셋 불러오기
from tensorflow.keras.callbacks import EarlyStopping

import numpy as np
import matplotlib.pyplot as plt

# train / test로 나누고 num_words로 1000개의 단어만 사용
(X_train, y_train), (X_test, y_test) = reuters.load_data(num_words=1000, test_split=0.2)

# 데이터 확인
category = np.max(y_train) + 1
# print(category, '카테고리')
# print(len(X_train), '학습용 뉴스 기사')
# print(len(X_test), '테스트용 뉴스 기사')
# print(X_train[0])

# 단어의 수를 맞춤
X_train = sequence.pad_sequences(X_train, maxlen=100)
X_test = sequence.pad_sequences(X_test, maxlen=100)

# 원-핫 인코딩 처리
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

# 모델의 구조를 설정
model = Sequential()
model.add(Embedding(1000, 100))
model.add(LSTM(100, activation='tanh'))
model.add(Dense(46, activation='softmax'))

# 모델의 실행 옵션 설정
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# 학습의 조기 중단 설정
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=5)

# 모델 실행
history = model.fit(X_train, y_train, batch_size=20, epochs=200, validation_data=(X_test, y_test), callbacks=[early_stopping_callback])

# 테스트 정확도 출력
print("\n Test Accuracy: %.4f" % (model.evaluate(X_test, y_test)[1]))

# 학습셋과 테스트셋의 오차를 저장
y_vloss = history.history['val_loss']
y_loss = history.history['loss']

# 그래프로 표현
x_len = np.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c="red", label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c="blue", label='Trainset_loss')

# 그래프에 그리드를 주고 레이블 표시
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

 


2. LSTM과 CNN의 조합을 이용한 영화 리뷰 분류하기

  • 인터넷 영화 데이터베이스(Internet Movie Database, IMDB)는영화와 관련된 정보를 매우 폭넓은 데이터가 저장됨
  • 로이터 뉴스 데이터와 마찬가지로각 단어에 대한 전처리를 마친 상태
  • 데이터셋에서 나타나는 빈도에 따라 번호가 정해지므로 빈도가 높은 데이터를 불러와 학습 가능
  • 클래스가 긍정,부정두 가지라 원-핫 인코딩 없음

 

  1. 라이브러리 불러오기
  2. seed 값 설정 & train,test 지정
  3. 데이터 전처리
  4. 모델 구조 및 옵션(컴파일) 설정
  5. 모델 실행 및 정확도 출력
  6. train / test 오차 저장 및 그래프 시각화
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Embedding, LSTM, Conv1D, MaxPooling1D
from tensorflow.keras.datasets import imdb
from tensorflow.keras.preprocessing import sequence
from tensorflow.keras.callbacks import EarlyStopping

import numpy as np
import matplotlib.pyplot as plt

# 데이터를 불러와 학습셋, 테스트셋으로 나눔
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=5000)

# 단어의 수 맞춤
X_train = sequence.pad_sequences(X_train, maxlen=500)
X_test = sequence.pad_sequences(X_test, maxlen=500)

# 모델의 구조 설정
model = Sequential()
model.add(Embedding(5000, 100))
model.add(Dropout(0.5))
model.add(Conv1D(64, 5, padding='valid', activation='relu',strides=1))
model.add(MaxPooling1D(pool_size=4))
model.add(LSTM(55))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.summary()

# 모델의 실행 옵션을 정함
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# 학습의 조기 중단을 설정
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=3)

# 모델을 실행
history = model.fit(X_train, y_train, batch_size=40, epochs=100, validation_split=0.25, callbacks=[early_stopping_callback])

# 테스트 정확도를 출력
print("\n Test Accuracy: %.4f" % (model.evaluate(X_test, y_test)[1]))

# 학습셋과 테스트셋의 오차를 저장
y_vloss = history.history['val_loss']
y_loss = history.history['loss']

# 그래프로 표현
x_len = np.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c="red", label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c="blue", label='Trainset_loss')

# 그래프에 그리드를 주고 레이블 표시
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

 

반응형