순환 신경망(Recurrent Neural Network)은 은닉 계층 안에 하나 이상의 순환 계층을 갖는 신경망을 의미합니다.
순환 신경망은 다른 네트워크들과 입력을 받는 방식에서 다릅니다. 순서가 있는 데이터에 주로 사용되며, 해당 데이터를 입력으로, 하나의 네트워크를 통해서 순서대로 출력을 얻습니다.
순서가 있는 데이터는 소리, 언어, 날씨, 주가 등의 데이터처럼 시간의 변화에 함께 변화하면서 그 영향을 받는 데이터를 의미합니다.
순환 계층
시계열 데이터 처리에 알맞게 고안된 퍼셉트론 계층입니다.
가중치와 편향을 각 시간대 데이터에 반복해서 사용합니다.
순환 벡터를 사용하여 정보를 전달합니다.
RNN의 구조
RNN은 되먹임 구조를 가지고 있습니다. 레이어의 출력을 다시 입력으로 받아서 사용하는 것으로서, 이전의 데이터가 함께 결과에 영향을 미칩니다.
RNN은 입력과 출력의 길이에 제한이 없다는 특징이 있습니다. 구조를 바꾸면 다양한 형태, 스타일의 네트워크를 형성할 수 있습니다.
기본적으로 Fully connected 구조를 가지고 있습니다.
RNN 파라미터
RNN은 모든 시간대에 동일한 변수를 사용합니다.
units 파라미터는 RNN 신경망에 존재하는 뉴런의 개수입니다.
return_sequences
RNN 계산 과정에 있는 hidden state를 출력할 것인지에 대한 값을 의미합니다.
해당 값은 다층으로 이루어진 RNN 또는 one-to-many, many-to-many 출력을 위해서 사용됩니다.
위의 그림과 같이 False의 경우, 마지막 출력값 하나를 출력합니다. True의 경우, 모든 과정의 출력 값을 출력합니다.
return_state
LSTM 레이어에서 주로 사용되는 값으로, cell_state를 출력할 것인지를 결정하는 값입니다.
activation
활성화 함수를 선언하는 변수입니다. tanh, relu 등과 같은 함수를 사용할 수 있습니다.
SimpleRNN 레이어
SimpleRNN 구조
가장 간단한 형태의 RNN 레이어입니다. 구조는 아래의 그림과 같습니다.
위의 그림에서 x를 입력, h를 출력이라고 했을 때, 각각의 x와 h는 순서가 있는 수열이라고 볼 수 있습니다.
SimpleRNN in Tensorflow 2.0
tf.keras.layers.SimpleRNN에서 import가 가능합니다.
model = tf.keras.Sequential([ tf.keras.layers.SimpleRNN(units=1, activation='tanh', return_sequences=True, return_state=True) ])
SimpleRNN 네트워크 예제
[0.0 0.1 0.2 0.3]이라는 0.1씩 늘어나는 수열을 줄 때, 이후의 값들도 예측을 하는 네트워크를 만들어보겠습니다.
Test 환경X에 0, 0.1, 0.2, 0.3 같은 수열들을 0.1씩 증가하면서 나열해줍니다. 해당 수열의 답인 Y는 0.4부터 0.1씩 증가하면서 들어가게 됩니다.
X = [] Y = [] for i in range(6): lst = list(range(i,i+4)) X.append(list(map(lambda c: [c/10], lst))) Y.append((i+4)/10) X = np.array(X) Y = np.array(Y) print(X) print(Y)
모델 만들기 & 학습모델은 Sequential에 SimpleRNN과 Dense레이어를 하나씩 추가해 주었고, input_shape는 4 time-step마다 하나의 답이라서 [4,1]을 선언하였습니다.위와 같은 학습을 반복하여서 MSE값을 낮추는 훈련을 하게 됩니다.
model = tf.keras.Sequential([tf.keras.layers.SimpleRNN(units=10,return_sequences=False,input_shape=[4,1]),tf.keras.layers.Dense(1)])model.compile(optimizer='adam', loss='mse')history = model.fit(X, Y, epochs=100, verbose=0)
예측기존의 훈련 데이터 세트를 넣어서 예측을 해보겠습니다.위와 같이, 답에 가깝게 예측이 되는 것이 확인이 됩니다. 이제는 새로운 데이터를 넣어서 예측해봅시다.위의 데이터를 넣어서 원하는 결과는 1.2에 가까운 수입니다.그러나 위와 같은 결과를 얻었습니다. 훈련 데이터를 증가시켜서 해당 결과를 개선시킬 수 있습니다.
GRU는 LSTM과 비슷한 역할을 하지만, 더 간단한 구조로 이루어져 있어서 계산상으로 효율적입니다. 이것은 기존의 LSTM에서 사용되는 셀 상태 계산(은닉 상태 업데이트)을 줄였습니다. 또한 특정 문제에서는 LSTM보다 더 적합한 레이어입니다.
GRU 구조
GRU는 LSTM에서의 셀 상태(cell state) 역할의 c가 없습니다. cell state의 역할을 다음의 출력 h에서 그 역할을 함께 합니다.
GRU에서는 Update Gate, Reset Gate 두 가지만 존재합니다. 또한 사용되는 활성화 함수는 sigmoid 2번과 tanh 1번 사용됩니다.
좀 더 자세히 살펴보겠습니다.
위의 그림처럼 GRU레이어는 Reset Gate, Update Gate들로 이루어져 있습니다. 각 게이트들은 sigmoid layer와 pointwise곱 연산을 통해서 값을 제어합니다.
Reset Gate
Reset Gate는 과거의 데이터를 리셋시키는 것을 목적으로 하는 게이트입니다. sigmoid연산을 통해 과거의 데이터를 얼마나 리셋시킬지에 대한 값인 r(0과 1 사이)을 출력합니다.
Update Gate
과거와 현재의 정보 업데이트 비율을 결정하는 게이트입니다.
출력 값 u는 현시점에서의 가져가야 할 데이터 양을 결정하는 값입니다. 1-u는 잊어버려야 할 데이터 양이라고 생각하면 됩니다.
데이터 선정
데이터를 이제 선정하는 단계입니다. 과거의 출력 값 데이터를 그대로 이용하지 않고, 리셋 데이터로 출력한 값을 이용하여 pointwise 곱 연산을 합니다.
연산 결과를 tanh 함수를 한번 거치게 합니다.
출력 값 계산
u는 데이터 중 얼마나 가져갈 것인지를, 1-u는 얼마나 잊을 것인지를 의미합니다.
tanh를 거친 h~는 현시점에서 리셋된 데이터를 의미하며 해당 데이터중 가져갈 것을 연산합니다.
이전의 h에서 얼마나 잊을지를 연산하여 이것들을 모두 합한 값이 출력 값이 됩니다.
GRU in Tensorflow 2.0
LSTM과 같이 클래스명만 GRU로 바꾸어주면 됩니다.
model = tf.keras.Sequential([
tf.keras.layers.GRU(units=30,
return_sequences=True,
input_shape=[100,2]),
tf.keras.layers.GRU(units=30),
tf.keras.layers.Dense(1)
])
model.compile(optimizer='adam', loss='mse')
history = model.fit(X, Y, epochs=100, verbose=0)
임베딩 레이어(Embedding Layer)
임베딩 레이어는 주로 자연어 처리에서 사용되며, 자연어를 수치화된 정보로 바꾸기 위한 레이어입니다.
임베딩이란?
임베딩은 값, 텍스트 내의 단어들을 밀집 벡터(dense vector)로 만드는 것을 말합니다.
단어를 의미론적 기하 공간에 매칭 시킬 수 있도록 수치 및 벡터화시키는 것을 의미합니다.
밀집 벡터는 대부분의 값이 실수이고, 저차원 적인 벡터를 의미합니다. 원-핫 벡터와 같은 희소 벡터(0 또는 1로 이루어진 벡터)와 달리 훈련 데이터로부터 학습을 하는 벡터입니다.
자연어 처리를 위한 전처리
RNN은 자연어 처리에 좋은 신경망입니다. 하지만, 신경망은 기본적으로 숫자로 이루어진 가중치와 편향들로 구성되어있습니다. 이를 위해 우리는 자연어를 의미가 있는 숫자 벡터로 바꾸어주어야 합니다.
tf.keras.preprocessing.text.Tokenizer()
토큰화와 정수 인코딩을 위해서 제공되는 클래스입니다.위와 같이 'I love Deep Learning'이라는 문장을 토크 나이저에 적용시키고 'I like Deep Learning'이라는 문장을 sequence로 변환시키면 아래와 같은 결과가 나옵니다.해당 토크 나이저는 i-1, love-2, deep-3, learning-4로 index가 지정되었고, 두 번째 문장에서는 1, 3, 4에 해당되는 단어들만 찾은 것을 알 수 있습니다.
t = tf.keras.preprocessing.text.Tokenizer() fit_text = "I love Deep Learning" t.fit_on_texts([fit_text]) test_text = "I like Deep Learning" sequences = t.texts_to_sequences([test_text])[0] print("sequences : ",sequences) # great는 단어 집합(vocabulary)에 없으므로 출력되지 않는다. print("word_index : ",t.word_index) # 단어 집합(vocabulary) 출력