도순씨의 코딩일지

딥러닝 :: 순환 신경망(RNN) 본문

순환 신경망(RNN)은 여러 개의 데이터가 순서대로 입력되었을 때 앞서 입력받은 데이터를 잠시 기억해 놓는 방법이다. 그리고 기억된 데이터가 얼마나 중요한지를 판단하여 별도의 가중치를 줘서 다음 데이터로 넘어간다. 모든 입력값에 대해 이러한 작업을 하기 때문에 계속 순환하는 것처럼 보인다. 따라서 순환 신경망이라고 부른다.

 

하지만 RNN의 특성상 일반 신경망보다 기울기 소실 문제가 더 많이 발생한다. 이를 해결하기 위해서 만들어진 방법이 LSTM(Long Short Term Memory)이다. 반복되기 직전에 다음 층으로 기억된 값을 넘겨야하는지 결정하는 단계를 추가한다. 

 

LSTM을 이용하여 로이터 뉴스 카테고리를 분류해보도록 하자. 케라스를 통해 로이터 뉴스의 데이터를 가져올 수 있다.

1
from keras.datasets import reuters
cs

 

학습셋과 테스트셋을 나누어준다.

1
(X_train, Y_train), (X_test, Y_test) = reuters.load_data(num_words = 1000, test_split = 0.2)
cs

 

불러온 데이터들을 확인하기 위핸 코드는 다음과 같다.

 

@ 코드

1
2
3
4
5
6
# 데이터 확인하기
category = numpy.max(Y_train) + 1
print(category, '카테고리')
print(len(X_train), '학습용 뉴스 기사')
print(len(X_test), '테스트용 뉴스 기사')
print(X_train[0])
cs

 

@ 실행 결과

1
2
3
4
46 카테고리
8982 학습용 뉴스 기사
2246 테스트용 뉴스 기사
[1, 2, 2, 8, 43, 10, 447, 5, 25, 207, 270, 5, 2, 111, 16, 369, 186, 90, 67, 7, 89, 5, 19, 102, 6, 19, 124, 15, 90, 67, 84, 22, 482, 26, 7, 48, 4, 49, 8, 864, 39, 209, 154, 6, 151, 6, 83, 11, 15, 22, 155, 11, 15, 7, 48, 9, 2, 2, 504, 6, 258, 6, 272, 11, 15, 22, 134, 44, 11, 15, 16, 8, 197, 2, 90, 67, 52, 29, 209, 30, 32, 132, 6, 109, 15, 17, 12]
cs

4번째 라인을 통해서 데이터 안에서 해당 단어가 몇 번이나 나타나는지에 따라 번호를 붙였음을 알 수 있다.

 

빈도가 높은 단어만 불러와 사용하기 위해 데이터 전처리 함수 sequence를 사용한다.

1
2
3
4
5
from keras.preprocessing import sequence
 
# 데이터 전처리
x_train = sequence.pad_sequences(X_train, maxlen = 100)
x_test = sequence.pad_sequences(X_test, maxlen = 100)
cs

maxlen = 100은 단어 수를 100개로 맞추는 것이다.

 

다음으로 원 핫 코딩처리를 한다.

1
2
y_train = np_utils.to_categorical(Y_train)
y_test = np_utils.to_categorical(Y_test)
cs

 

딥러닝의 구조는 다음과 같이 만든다.

1
2
3
4
5
# 모델의 설정
model = Sequential()
model.add(Embedding(1000100))
model.add(LSTM(100, activation = 'tanh'))
model.add(Dense(46, activation = 'softmax'))
cs

Embedding과 LSTM 층이 새로 추가되었다. Embedding 층은 데이터 전처리 과정을 통해 입력된 값을 받아 다음 층이 알아들 수 있는 형태로 변환한다. 형태는 Embedding('불러온 단어의 총 개수', '기사당 단어 수') 형식이다. LSTM은 앞서 설명했듯이 RNN에서 기억 값에 대한 가중치를 제어한다. LSTM(기사당 단어 수, 기타 옵션)의 형태로 적용된다.

 

1
2
3
4
5
6
7
8
# 모델의 컴파일
model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
 
# 모델의 실행
history = model.fit(x_train, y_train, batch_size=100, epochs = 20, validation_data = (x_test, y_test))
 
# 텍스트 정확도 출력
print("\n Test Accuracy: %.4f" %(model.evaluate(x_test, y_test)[1]))
cs

 

전체 코드는 다음과 같다.

 

@ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from keras.datasets import reuters
from keras.preprocessing import sequence
 
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, LSTM, Embedding
 
import numpy
import tensorflow as tf
import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'
 
# 불러온 데이터를 학습셋과 테스트 셋으로 나누기
(X_train, Y_train), (X_test, Y_test) = reuters.load_data(num_words = 1000, test_split = 0.2)
 
# 데이터 전처리
x_train = sequence.pad_sequences(X_train, maxlen = 100)
x_test = sequence.pad_sequences(X_test, maxlen = 100)
 
y_train = np_utils.to_categorical(Y_train)
y_test = np_utils.to_categorical(Y_test)
 
# 모델의 설정
model = Sequential()
model.add(Embedding(1000100))
model.add(LSTM(100, activation = 'tanh'))
model.add(Dense(46, activation = 'softmax'))
 
# 모델의 컴파일
model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
 
# 모델의 실행
history = model.fit(x_train, y_train, batch_size=100, epochs = 20, validation_data = (x_test, y_test))
 
# 텍스트 정확도 출력
print("\n Test Accuracy: %.4f" %(model.evaluate(x_test, y_test)[1]))
cs

 

@ 실행 결과

1
 Test Accuracy: 0.7150
cs

 

 

* 출처

조태호, 모두의 딥러닝(2017), 길벗

Comments