lstm 14. 순환신경망

행동하는 개발자·2022년 12월 19일
0

RNN

목록 보기
13/14

출력층 방향으로만 활성화 함수를 지나는 신경망을 피드 포워드 신경망이라고 한다. 하지만 rnn은 은닉층의 노드에서 활성화 함수를 통해 나온 결과값을 출력층 방향으로도 보내면서 다시 은닉층 노드의 다음 계산의 입력으로 보내는 특징을 갖고 있다.

rnn에서 은닉층에서 활섬화 함수를 통해 결과를 내보내는 역할을 하는 노드를 셀이라고 한다. 이 셀은 이전의 값을 기억하려고 하는 일종의 메모리 역할을 수행하므로 이를 메모리 셀 또는 rnn 셀이라고 표현한다.

메모리 셀이 출력층 방향 또는 다음 시점인 t+1의 자신에게 보내는 값을 은닉 상태라고 한다. t 시점의 메모리셀은 t-1 시점의 메모리 셀이 보낸 은닉 상태값을 t 시점의 은닉 상태 계산을 위한 입력값으로 사용한다.

rnn은 입력과 출력의 길이를 다르게 설계할 수 있으므로 다양한 용도로 사용할 수 있다.

  • 다대 일 구조의 모델

  • 다대 다 구조의 모델

예제

from tensorflow.keras.layers import SimpleRNN

model.add(SimpleRNN(hidden_units))

hidden_units = 은닉 상태의 크기를 정의. 메모리 셀이 다음 시점의 메모리 셀과 출력층으로 보내는 값의 크기와도 동일. RNN의 용량을 늘린다고 보면 된다. 보통 128, 256, 512, 1024의 값을 가진다.

timesteps = 입력 시퀀스의 길이.
input_dim = 입력의 크기

전결합층을 출력 층으로 사용하였을 경우, 인공 신경망 그림과 은닉층까지만 표현한 그림의 차이.

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import SimpleRNN

model = Sequential()
model.add(SimpleRNN(3, input_shape=(2,10)))
# model.add(SimpleRNN(3, input_length=2, input_dim=10))와 동일함.
model.summary()

결과값
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
simple_rnn_1 (SimpleRNN)     (None, 3)                 42        
=================================================================
Total params: 42
Trainable params: 42
Non-trainable params: 0
_________________________________________________________________

DEEP RNN

model = Sequential()
model.add(SimpleRNN(hidden_units, input_length=10, input_dim=5, return_sequences=True))
model.add(SimpleRNN(hidden_units, return_sequences=True))

앞서 RNN도 다수의 은닉층을 가질 수 있다고 언급한 바 있습니다. 위의 그림은 순환 신경망에서 은닉층이 1개 더 추가되어 은닉층이 2개인 DEEP RNN의 모습을 보여줍니다.

양방향 RNN

운동을 열심히 하는 것은 [        ]을 늘리는데 효과적이다.

1) 근육
2) 지방
3) 스트레스

양방향 순환 신경망은 시점 t에서의 출력값을 예측할 때 이전 시점의 입력뿐만 아니라 이후 시점의 입력 또한 예측에 기여할 수 있다는 아이디어에 기반한다.

위의 문장에서도 운동을 열심히 하는 것은 까지는 빈칸을 채우려고 하기에 정보가 부족하다. 미래 시점의 입력에 힌트가 있는 경우가 많기 때문에 고안된 것이 바로 양방향 rnn이다.

양방향 rnn은 하나의 출력값을 예측하기 위해 기본적으롤 두 개의 메모리 셀을 사용한다. 첫 번재 메모리 셀은 앞에서 배운 것처럼 앞 시점의 은닉 상태를 전달받아 현재의 은닉 상태를 계산한다. 위의 그림에서는 주황색 메모리 셀에 해당한다. 두번째 메모리 셀은 앞에서 배운 것과는 다르다. 앞 시점의 은닉 상태가 아니라 뒤 시점의 은닉 상태를 전달 받아 현재의 은닉 상태를 계산한다. 입력 시퀀스를 반대 방향으로 읽는 것이다.

from tensorflow.keras.layers import Bidirectional

timesteps = 10
input_dim = 5

model = Sequential()
model.add(Bidirectional(SimpleRNN(hidden_units, return_sequences=True), input_shape=(timesteps, input_dim)))
def BuildNN():
    model = keras.models.Sequential([
        keras.layers.Input(shape=(60, 13)),
        keras.layers.LSTM(1024, return_sequences=True, name='LSTM_0'),
        keras.layers.LSTM(512, return_sequences=True, name='LSTM_1'),
        keras.layers.LSTM(256, return_sequences=True, name='LSTM_2'),
        keras.layers.LSTM(128, return_sequences=True, name='LSTM_3'),
        keras.layers.Flatten(),
        keras.layers.Dense(64, activation="swish"),
        keras.layers.Dense(1, activation="sigmoid")
    ])
    

결과값

hidden cell을 포함한 hidden layer를 여러 층 쌓아서 모델을 만들 수 있다. LSTM의 첫번째 layer에는 input_size를 넣어줘야 하고, 두 번째, layer부터는 이전 layer의 아웃풋 사이즈가 input_size가 된다.

일반적으로 성능 향상에 hidden units의 개수를 늘리기보다, 더 많은 hidden layer를 쌓는게 효과적이라고 한다.

input_shape의 length는 60으로 변하지 않지만 특징의 개수가 num_unit의 개수에 따라 변한다.

unit을 늘리는 건 데이터의 차원을 늘리는 것을 뜻하고 이는 모델이 데이터를 더 잘 설명할 수 있게 만든다. layer를 늘리는 건 더 복잡한 모델을 만드는 것이고, 이는 모델이 더 많은 패턴을 학습할 수 있음을 뜻한다. unit, layer를 늘리면서 성능을 향상시킬 수 있지만, 오버피팅이 발생할 수 있다.

출처: https://wikidocs.net/22886

출처: https://jiwonkoh.tistory.com/188

profile
끊임없이 뭔가를 남기는 사람

0개의 댓글