👩‍💻LEARN : ML&Data/Book Study

[모두의 딥러닝]#5-18. 순환신경망 (RNN)

쟈니유 2023. 2. 24. 23:59
728x90

빙글빙글 돌아가는 나의 하루...나도 돈다..!


#5-18. 순환신경망 (RNN) 

 

1. 순환신경망이란 무엇인가

문장을 이해하기 위해서는 여러개의 단어의 순서를 고려하여 인식해야함. 즉 단어의 입력 순서도 고려해야 하는 부분이 됨.

이에 순환신경망은 앞서 입력받은 데이터를 기억해두고, 이 데이터의 중요도를 판단한 후 가중치를 주고 다음 데이터로 넘어감. 

 

e.g. '오늘 네이버 주가는 얼마야?' -> 오늘 // 네이버 // 주가 // 얼마야 ?? -> 앞에 입력된 값에 따라 뒤의 입력값에 영향을 줌 

 

2. 순환신경망과 LSTM(Long short term memory)

 

RNN의 한계 (한 층에서 반복을 많이 함 -> 일반 신경망 보다 기울기 소실이 많이 발생하고 해결하기 어려움)를 해결하기 위해

LSTM을 적용하여 반복되기 직전에 기억된 값을 넘길지 여부를 관리하는 단계를 추가하게 함 

 

e.g. 오늘 --LSTM --> 네이버 --LSTM --> 주가가 --LSTM --> 얼마야? 

 

3. 실습 

A. LSTM 활용 

목표 :로이터 뉴스 기사를 카테고리 별로 분류하는 것 

 

[A-1. 데이터 불러오기] 

패키지와 데이터를 불러오고 데이터를 확인해준다 

X_train[0]은 학습데이터에 있는 첫번째 기사인데, 이 기사의 단어들은 빈도수의 순위에 따라 번호가 붙어있음을 확인할 수 있다. 

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

#data : 로이터 데이터를 학습셋-테스트셋으로 분류해서 가져오기 

(X_train, y_train), (X_test, y_test) =reuters.load_data(num_words= 1000, test_split = 0.2) #num_words :빈도가 1000까지인 단어까지만 선택해오기 

# 목표인 카테고리 수를 넣어주기. y_train의 맥스를 찍었을때, 0부터 시작하므로 수를 계산하기 위해선 1을 더해줘야 함 
category = np.max(y_train) + 1

print(category, 'category')
print(len(X_train), 'The number of news for train')
print(len(X_test), 'The number of news for test')
print(X_train[0])

46 category

8982 The number of news for train

2246 The number of news for test

[1, 2, 2, 8, 43, 10, 447, 5, 25, 207, 270, 5, 2, 111, 16, 369, 186, 90, 67, 7, 89, 5,...

 

[A-2. 데이터 전처리]

기사마다 단어 수가 다르므로 이를 패딩으로 맞춰주고, 카테고리에 원핫인코딩을 적용해준다 

#padding

X_train = sequence.pad_sequences(X_train, maxlen = 100)
X_test = sequence.pad_sequences(X_test, maxlen = 100)

#onehotincoding

y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

 

[A-3. 모델링]

Embedding: 단어의 수만큼 생성된 벡터의 차원을 컴퓨터가 잘 습득할 수 있게 차원을 줄여주는것. 

Embedding(총 단어의 수, 축소하고 싶은 벡터 차원) 으로 하면 되는데 여기에선 왜 기사당 단어수로 하셨는지 이해는 잘 안간다. 

 

LSTM : 가중치 제어하는 역할인데 ....! 별 다른 인풋값이 없어서 잘 모르긴 하겠다.......

LSTM(앞에서 축소한 벡터 차원, 즉 앞의 아웃풋 값, 활성함수 종류) 를 넣으면 되고 여기에선 tahn을 사용했다. 

 

#모델링


model = Sequential()
model.add(Embedding(1000,100)) #1000 : 단어의 총 개수, 100 : 기사 당 단어 수 (maxlen)
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) #earlystopping checkpoint 중 체크포인트는 최적화 모델 만드는 용인데 지금은 최적호 ㅏ모델을 안만들기 때문에 얼리스탑만 했다. 


#실행
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]))

Test Accuracy : 0.7137

 

 

 

----

 

근데 이거 보다보니... 책 예제에 잘못된(?) 설명이 있는 경우가 가끔 잇따..

이거 좀 더 다른 문헌을 찾아보고 정확하게 이해하는 것이 필요할 듯 

 

아래 내용은 나중에 자연어 처리 더 공부한 다음에 정리합쉬다...

 

B. LSTM에 CNN 적용하기

 

C. Attention 신경망 사용해보기