본문 바로가기
  • 데이터에 가치를 더하다, 서영석입니다.
공부하는 습관을 들이자/Deep Learning (NLP,LLM)

[딥러닝 자연어처리] 9-1. (01) 순환 신경망 (Recurrent Neural Network)

by 꿀먹은데이터 2023. 12. 25.

딥러닝을 이용한 자연어처리 입문 #9-1. (01) 순환 신경망

(1) 순환 신경망 (Recurrent Neural Network)

  • 피드포워드 신경망의 한계점: 입력의 길이가 고정되어 있음
  • 이를 해결하기 위한 방법으로 순환 신경망이 사용됨
  • RNN: 은닉층의 노드에서 활성화 함수를 통해 나온 결과값을 출력층 방향으로도 보내면서, 다시 은닉층 노드의 다음 계산의 입력으로 보냄
  • 셀(cell): RNN 은닉층에서 활성화 함수를 통해 결과를 내보내는 역할을 하는 노드
  • 은닉 상태(hidden state): 메모리 셀이 출력층 방향 또는 다음 시점인 자신에게 보내는 값

RNN은 입력과 출력의 길이를 다르게 설계하여 다양한 용도로 사용할 수 있음

 

(2) 케라스(Keras)로 RNN 구현하기

from tensorflow.keras.layers import SimpleRNN

model.add(SimpleRNN(hidden_units))

# 추가 인자를 사용할 때
model.add(SimpleRNN(hidden_units, input_shape=(timesteps, input_dim)))

# 다른 표기
model.add(SimpleRNN(hidden_units, input_length=M, input_dim=N))

[return_sequences = True를 설정했을 때와 그렇지 않았을 때의 차이]

return_sequences = True를 선택하면 메모리 셀이 모든 시점에 대해서 은닉 상태값을 출력하며, 그렇지 않을 경우에는 하나의 은닉 상태값만을 출력함

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

model = Sequential()
model.add(SimpleRNN(3,input_shape(2,10)))

model.summary()

model = Sequential()
model.add(SimpleRNN(3,batch_input_shape(8,2,10),return_sequences=True))
model.summary()

(3) 파이썬으로 RNN 구현하기

import numpy as np
timesteps = 10
input_dim = 4
hidden_units = 8

#입력에 해당되는 2D 텐서
inputs = np.random.random((timesteps,input_dim))

#초기 은닉 상태는 0(벡터)로 초기화
hidden_State_t = np.zeros((hidden_units,))
print('초기 은닉 상태 :',hidden_state_t)

Wx = np.random.random((hidden_units, input_dim)) # (8, 4)크기의 2D 텐서 생성 입력에 대한 가중치 
Wh = np.random.random((hidden_units, hidden_units)) # (8, 8)크기의 2D 텐서 생성. 은닉 상태에 대한 가중치 
b = np.random.random((hidden_units,)) # (8,)크기의 1D 텐서 생성 이 값은 편향(bias). 
print( '가중치 Wx의 크기(shape) :' ,np.shape(Wx)) 
print('가중치 Wh의 크기(shape) :' ,np.shape(Wh)) 
print('편향의 크기(shape) :' ,np.shape(b))

total_hidden_states = [] 
# 각 시점 별 입력값. 
for input_t in inputs: 
# Wx * Xt + Wh * Ht-1 + b(bias) 
output_t = np.tanh(np.dot(Wx,input_t) + np.dot(Wh,hidden_state_t) + b) 
# 각 시점 t별 메모리 셀의 출력의 크기는 (timestep t, output_dim) 
# 각 시점의 은닉 상태의 값을 계속해서 누적 
total_hidden_states.append(16st/put_t_t)) 
hidden_state_t = output_t 
# 출력 시 값을 깔끔하게 해주는 용도. 
total_hidden_states = np.stack(total_hidden_states, axis = 0) 
# (timesteps, output_dim) 
print(' 모든 시점의 은닉 상태 :') 
print(total_hidden_states)

(4) 깊은 순환 신경망

model = Sequential() 
model.add(SimpleRMW(hidden_units, input length=10, input dim=5, return_sequences=True)) 
model.add(SimpleRNN(hidden_ units, return_sequences=True))