Just Fighting

LSTM 개념 정리 및 실습 본문

ML & DL

LSTM 개념 정리 및 실습

yennle 2022. 7. 24. 20:40
728x90

https://wikidocs.net/22888

 

2) 장단기 메모리(Long Short-Term Memory, LSTM)

바닐라 아이스크림이 가장 기본적인 맛을 가진 아이스크림인 것처럼, 앞서 배운 RNN을 가장 단순한 형태의 RNN이라고 하여 바닐라 RNN(Vanilla RNN)이라고 합니다 ...

wikidocs.net

 

 

LSTM (Long Short Term Memory)

- 바닐라 RNN(가장 단순한 형태의 RNN)은 출력 결과가 이전의 계산 결과에 의존하지만 짧은 시퀀스에만 효과를 보임

- 바닐라 RNN의 시점이 길어질수록 앞의 정보가 뒤로 충분히 전달되지 못하는 현상 발생 >> "장기 의존성 문제"

 

- LSTM은 은닉층의 메모리 셀에 입력게이트, 망각게이트, 출력게이트를 추가해 불필요한 기억을 지우고 기억해야할 것을 정함.

- 3개의 게이트에는 공통적으로 시그모이드 함수가 존재하고, 시그모이드 함수를 지난 결과인 0, 1의 값으로 게이트를 조절

 

 

입력 게이트

- 현재 정보를 기억하기 위한 게이트

- $i_t$ : 시점 t의 $x$값에 가중치를 곱한 값과 시점 t-1의 은닉상태에 가중치를 곱한 값을 더해 시그모이드 함수에 넣은 값

- $g_t$ : 시점 t의 $x$값에 가중치를 곱한 값과 시점 t-1의 은닉상태에 가중치를 곱한 값을 더해 하이퍼볼릭탄젠트 함수에 넣은 값

- 두개의 값을 이용해 기억할 정보의 양을 정한다.

 

 

 

삭제 게이트

- 기억을 삭제하기 위한 게이트

- $f_t$ : 시점 t의 $x$값과 t-1의 은닉상태에 각각 가중치를 곱해서 합한 뒤 시그모이드 함수를 지난 값

- $f_t$의 값이 0과 1사이의 값이 나오는데, 이 값이 곧 삭제 과정을 거친 정보의 양이 된다.

- 0에 가까울수록 정보가 많이 삭제된 것이고, 1에 가까울수록 정보를 온전히 기억한다.

 

 

 

셀 상태

- 입력게이트에서 선택된 기억을 삭제 게이트의 결과값과 더한 값이 '시점 t의 셀 상태'라고 함.

- 삭제 게이트의 출력값이 0이 된다면 오직 입력게이트의 결과만이 현재 시점의 셀 상태 값을 결정함

   => 삭제 게이트가 완전히 닫히고, 입력게이트를 연 상태를 의미

- 입력 게이트의 값이 0이며, 현재 시점의 셀 상태는 오직 이전 시점의 셀 상태의 값에만 의존

- 즉, 삭제 게이트는 이전 시점의 입력을 얼마나 반영할지를 의미, 입력 게이트는 현재 시점의 입력을 얼마나 반영할지 결정

 

 

출력 게이트와 은닉 상태

- $o_t$ : 시점 t의 $x$값과 시점 t-1의 은닉상태가 각각 가중치를 곱해서 합한 뒤 시그모이드 함수를 지난 값

- $o_t$는 시점 t의 은닉상태를 결정하는 일에 쓰임

- $h_t$ : 셀 상태 값이 하이퍼볼릭탄젠트 함수를 지나 -1과 1사이의 값이 되고, 해당 값은 $o_t$ 값과 연산되면서

        값이 걸러지는 효과가 발생해 은닉상태가 됨.

- 은닉상태 값은 또한 출력층으로도 향함.

 

 

 

 

 

https://wikidocs.net/106473

 

4) 케라스의 SimpleRNN과 LSTM 이해하기

케라스의 SimpleRNN과 LSTM을 이해해봅니다. #1. 임의의 입력 생성하기 ``` import numpy as np import tensorflow as tf fr ...

wikidocs.net

 

케라스의 LSTM

실제로 SimpleRNN을 사용하는 경우는 거의 없고, LSTM과 GRU를 사용함.

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import SimpleRNN, LSTM, Bidirectional
# 3D 텐서. 밖에 대괄호 하나 더 추가함.
train_X = [[[0.1, 4.2, 1.5, 1.1, 2.8], [1.0, 3.1, 2.5, 0.7, 1.1], [0.3, 2.1, 1.5, 2.1, 0.1], [2.2, 1.4, 0.5, 0.9, 1.1]]]
train_X = np.array(train_X, dtype=np.float32)
print(train_X.shape)

 

 

은닉 상태의 크기 3, return_sequences=False, return_state=True 일 경우에는

마지막 은닉 상태와 셀 상태를 리턴한다.

lstm = LSTM(3, return_sequences=False, return_state=True)   # 은닉 상태의 크기 3, return_sequences=False, return_state=True
hidden_state, last_state, last_cell_state = lstm(train_X)

# 마지막 은닉상태와 셀 상태
# return_state = True 인 경우에는 셀 상태까지 반환
print('hidden state : {}, shape: {}'.format(hidden_state, hidden_state.shape))
print('last hidden state : {}, shape: {}'.format(last_state, last_state.shape))
print('last cell state : {}, shape: {}'.format(last_cell_state, last_cell_state.shape))

 

은닉 상태의 크기 3, return_sequences=True, return_state=True 일 경우에는

모든 시점의 은닉 상태와 셀 상태를 리턴한다.

lstm = LSTM(3, return_sequences=True, return_state=True)   # 은닉 상태의 크기 3, return_sequences=True, return_state=True
hidden_state, last_state, last_cell_state = lstm(train_X)

# 모든 시점의 은닉상태와 셀 상태
print('hidden state : {}, shape: {}'.format(hidden_state, hidden_state.shape))
print('last hidden state : {}, shape: {}'.format(last_state, last_state.shape))
print('last cell state : {}, shape: {}'.format(last_cell_state, last_cell_state.shape))

 

 

양방향 LSTM

양방향 LSTM의 출력값을 확인해보자.

return_state = True인 경우에는 아래 코드에서 확인할 수 있듯이 5개의 값을 리턴한다.

 

return_sequences = False인 경우에는 정방향 LSTM의 마지막 시점의 은닉상태와

역방향 LSTM의 첫번째 시점의 은닉상태가 연결된 채 반환된다.

# 은닉상태 값 고정
# return_sequences가 True인 경우와 False 인 경우를 비교하기 위함.
k_init = tf.keras.initializers.Constant(value=0.1)
b_init = tf.keras.initializers.Constant(value=0)
r_init = tf.keras.initializers.Constant(value=0.1)
# return_sequences=False
bilstm = Bidirectional(LSTM(3, return_sequences=False, return_state=True,
                        kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init))
hidden_states, forward_h, forward_c, backward_h, backward_c = bilstm(train_X)

print('hidden states : {}, shape: {}'.format(hidden_states, hidden_states.shape))
print('forward state : {}, shape: {}'.format(forward_h, forward_h.shape))
print('backward state : {}, shape: {}'.format(backward_h, backward_h.shape))

 

return_sequences=True일 경우에는 모든 시점의 은닉상태가 출력된다.

이때는 역방향 LSTM의 첫번째 시점의 은닉상태와 정방향 LSTM의 첫번째 시점의 은닉상태가 연결된 것을 확인할 수 있다.

# return_sequences=True
bilstm = Bidirectional(LSTM(3, return_sequences=True, return_state=True,
                        kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init))
hidden_states, forward_h, forward_c, backward_h, backward_c = bilstm(train_X)

print('hidden states : {}, shape: {}'.format(hidden_states, hidden_states.shape))
print('forward state : {}, shape: {}'.format(forward_h, forward_h.shape))
print('backward state : {}, shape: {}'.format(backward_h, backward_h.shape))

 

728x90

'ML & DL' 카테고리의 다른 글

GRU 개념정리  (0) 2022.07.24
SimpleRNN 이해하기  (0) 2022.07.24
RNN 개념정리  (0) 2022.07.24
[PySpark] 나이브 베이즈 실습  (0) 2022.06.09
[개념 정리] 나이브 베이즈 (Naive Bayes)  (0) 2022.06.08
Comments