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

김우빈·2022년 5월 29일
0

JUST BUILD DEEP_LEARNING

목록 보기
7/9

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

순환 신경망( RNN :Recurrent Neural Network)은 입력과 출력을 시퀀스 단위로 처리하는 시퀀스(Sequence) 모델입니다.
챗봇을 생각해보시면 편하실 겁니다.
입력은 챗봇에게 하고자 하는 단어의 시퀀스인 문장이고,
출력에 해당되는 챗봇의 대답 문장 또한 단어의 시퀀스입니다.
이와 같이 시퀀스들을 처리하기 위해 고안된 모델들을 시퀀스 모델이라고 합니다.
그 중 순환 신경망( RNN :Recurrent Neural Network)은 가장 기본적인 인공 신경망 시퀀스 모델입니다.
LSTM이나 GRU 또한 근본적으로 순환 신경망( RNN :Recurrent Neural Network)이라고 할 수 있습니다.

기존에 지정했던 신경망들은 전부 은닉층에서 활성화 함수를 지난 값은 오직 출력층 방향으로만 향했습니다.
이와 같은 신경망들을 피드 포워드 신경망(Feed Forward Neural Network)이라고 합니다.순환 신경망( RNN :Recurrent Neural Network)의 경우에는 은닉층의 노드에서 활성화 함수를 통해 나온 결과값을 출력층 방향으로도 보내면서, 다시 은닉층 노드의 다음 계산의 입력으로 보내는 특징을 갖고있습니다.

RNN층(Layer)를 구현하는 코드를 보면서 설명 드리겠습니다.

tensorflow에서의 사용법

from tensorflow.keras.layers import SimpleRNN
model.add(SimpleRNN(hidden_units))

순환 신경망( RNN :Recurrent Neural Network) 층은 (batch_size, timesteps, input_dim) 크기의 삼차원 텐서(3D tensor)를 입력으로 받습니다. batch_size는 한 번에 학습하는 데이터의 개수를 말합니다.

  • hidden_units = 은닉 상태의 크기를 정의합니다.
    메모리 셀이 다음 시점의 메모리 셀과 출력층으로 보내는 값의 크기이고,
    (output_dim)와도 동일하고, 순환 신경망( RNN :Recurrent Neural Network)의 용량(capacity)을 늘린다고 생각하시면 됩니다.
    중소형 모델의 경우 보통 128, 256, 512, 1024 등의 값을 줍니다.

  • timesteps = 입력 시퀀스의 길이(input_length)라고 표현합니다. 시점의 수를 정의합니다.

  • input_dim = 입력의 크기입니다. 이전의 input_dim과 같습니다.
    (입력노드: 입력되는 데이터의 차원)

tensorflow로 구현하기

#module import

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.utils import to_categorical
import numpy as np

#학습할 문장
sentence="알엔엔 으로 자연어 처리하기 어렵지 않아요 기본은 전부 같기때문이죠 그래서 제가 쉽게 설명드리려고 하는겁니다 왜냐하면 쉬우니까요" #학습할 문장

#시퀀스의 길이 설정
set_sentence=list(set(sentence))
sampledict={c:i for i,c in enumerate(set_sentence)}
sequencelength=20

#sequencelength에서 설정한 길이로 문장을 배치 단위로 잘라 학습 데이터 구성
datax=[]
datay=[]
for i in range(0,len(sentence)-sequencelength): 
    xstr=sentence[i:i+sequencelength]
    ystr=sentence[i+1:i+sequencelength+1]
    x1=[sampledict[c]for c in xstr]
    y1=[sampledict[c] for c in ystr]
    print("data",i,"input data:",xstr,"output data:",ystr)
    datax.append(x1)
    datay.append(y1)

#인덱싱
sampleindex=[sampledict[i] for i in sentence]

numberclass=len(sampledict)

#one-hot encoding
xdata_onehot=to_categorical(datax,numberclass)
ydata_onehot=to_categorical(datay,numberclass)


input = keras.Input(shape=(sequencelength,numberclass))
#RNN layer 구성, 학습 데이터 수가 늘었기 때문에 unit 값 100으로 설정
x = layers.SimpleRNN(units=100,return_sequences=True)(input) 
output= layers.TimeDistributed(layers.Dense(units=numberclass,activation='softmax'))(x)
model = keras.Model(inputs=input, outputs=output)
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
hist=model.fit(xdata_onehot, ydata_onehot, epochs=100)

소프트맥스함수(softmax function)를 활성화 함수(Activation Function)으로 하고, 손실함수(Loss function)를 다중분류 교차엔트로피(categorical crossentropy)로하는 문장 시퀀스를 순환하며 학습하는 자연어 학습 모델을 구현해보았습니다.

data 0 input data: 알엔엔 으로 자연어 처리하기 어렵지 output data: 엔엔 으로 자연어 처리하기 어렵지 않
data 1 input data: 엔엔 으로 자연어 처리하기 어렵지 않 output data: 엔 으로 자연어 처리하기 어렵지 않아
data 2 input data: 엔 으로 자연어 처리하기 어렵지 않아 output data: 으로 자연어 처리하기 어렵지 않아요
data 3 input data: 으로 자연어 처리하기 어렵지 않아요 output data: 으로 자연어 처리하기 어렵지 않아요
data 4 input data: 으로 자연어 처리하기 어렵지 않아요 output data: 로 자연어 처리하기 어렵지 않아요 기
data 5 input data: 로 자연어 처리하기 어렵지 않아요 기 output data: 자연어 처리하기 어렵지 않아요 기본

위와같이 입력데이터(input data), 출력데이터(out data)를 확인하실수있고, 입출력 데이터가 정해지면 지정해준 epoch만큼 반복하여 학습을 시작합니다.

Epoch 1/100
2/2 [==============================] - 1s 21ms/step - loss: 3.8596 - accuracy: 0.0412
Epoch 2/100
2/2 [==============================] - 0s 24ms/step - loss: 3.6890 - accuracy: 0.1059
Epoch 3/100
2/2 [==============================] - 0s 19ms/step - loss: 3.5263 - accuracy: 0.2069
Epoch 4/100
2/2 [==============================] - 0s 21ms/step - loss: 3.3781 - accuracy: 0.252
.
.
.
Epoch 97/100
2/2 [==============================] - 0s 18ms/step - loss: 0.2083 - accuracy: 0.9833
Epoch 98/100
2/2 [==============================] - 0s 18ms/step - loss: 0.2063 - accuracy: 0.9833
Epoch 99/100
2/2 [==============================] - 0s 19ms/step - loss: 0.2044 - accuracy: 0.9833
Epoch 100/100
2/2 [==============================] - 0s 20ms/step - loss: 0.2026 - accuracy: 0.9833

다음과 같이 손실값(loss value)과 정확도(accuracy)를 확인 하실 수 있습니다.

metrics=model.evaluate(xdata_onehot, ydata_onehot, verbose=2)
print("Train accuracy:", metrics[1])

위의 코드를 사용해 최종 훈련 정확도를 보실 수 있으며 그래프로 시각화 해보면,

fig, loss_ax = plt.subplots()
acc_ax = loss_ax.twinx()

loss_ax.plot(hist.history['loss'], 'y', label = 'train loss')
acc_ax.plot(hist.history['accuracy'], 'b', label = 'train accuracy')

loss_ax.set_xlabel('epoch')
loss_ax.set_ylabel('loss')
acc_ax.set_ylabel('accuracy')

loss_ax.legend(loc='upper left')
acc_ax.legend(loc='lower left')

plt.show()

다음과같이 그래프로 확인하실수있습니다.

마무리

오늘은 순환 신경망( RNN :Recurrent Neural Network)에 대해서 알아봤습니다.
순환 신경망( RNN :Recurrent Neural Network)은 시계열데이터 분석을통한 날씨예측이나, LSTM으로 자연어처리를하는데 특히 유용히 사용되는 레이어(층 : Layer)입니다. 다음게시글에선 LSTM(Long Short-Term Memory )에 대해서 다뤄보려고합니다. 긴 글 읽어주셔서 감사합니다.

profile
DeepLearning, MLOps

0개의 댓글