Data Science/Deep Learning
[Deep Learning from Scratch 2] chapter 6.2. 게이트가 추가된 RNN_GRU
sunnyshiny
2023. 4. 26. 15:22
728x90
GRU(Gated Recurrent Unit)¶
- LSTM은 매개변수가 많아서 계산이 오래걸리는 단점
- GRU는 게이트를 사용한다는 개념은 유지한채 매개변수를 줄여 계산시간을 줄임
- LSTM은 은닉상태와 기억셀이라는 2개의 선을 사용 GRU는 은닉상태만 사용
GRU계산 그래프¶
$$z = \sigma(x_tW_x^z +h_{t-1}W_h^z+b^z)\\ r = \sigma(x_tW_x^r +h_{t-1}W_h^r+b^r) \\ \tilde{h}= tanh(x_tW_x +(r\odot h_{t-1})W_h+b) \\ h_t = (1-z) \odot h_{t-1} + z \odot \tilde{h} $$
- GRU는 기억 셀은 없고 시간방향으로 전파하는 것은 은닉 셀 h 뿐임
- r(reset), z(update) 라는 2개의 게이트를 사용
- reset gate는 과거의 은닉 상태를 얼마나 무시할지 정함(만일 r이 0 이면 새로운 은닉상태 $\tilde{h}$는 입력 $x_t$만으로 결정 즉, 과거의 은닉상태는 완전히 무시 됨
- update gate는 은닉상태를 갱신하는 게이트(LSTM이 forget gate와 input gate를 모두 담당)
- forget gate의 역할은 $(1-z) \odot h_{t-1} $ 과거의 은닉 상태에서 잊어야할 정보를 삭제
- input gate의 역할은 $z \odot \tilde{h} $이며 새로추가된 정보에 input gate가중치를 부여 GRU 는 LSTM을 더 단순하게 만듬, 계산비용을 줄이고 매개변수 수도 줄일수 있음
- GRU는 데이터 셋이 작거나 모델 설계시 반복시도를 많이 해야할 경우 적합
In [1]:
from IPython.display import Image
Image(filename='LSTM3-var-GRU.png')
Out[1]:
GRU 구현¶
In [ ]:
class GRU:
def __init__(self, Wx, Wh):
self.Wx, self.Wh = Wx, Wh
self.dWx, self.dWh = None, None
self.cache = None
def forward(self, x, h_prev):
H, H3 = self.Wh,shape
Wxz , Wxr, Wx = self.Wx[:, :H], self.Wx[:, H:2*H], self.Wx[:, 2*H:]
Whz , Whr, Wh = self.Wh[:, :H], self.Wh[:, H:2*H], self.Wh[:, 2*H:]
z = sigmoid(np.dot(x, Wxz) + np.dot(h_prev, Whz))
r = sigmoid(np.dot(x, Wxr) + np.dot(h_prev, Whr))
h_hat = np.tanh(np.dot(x, Wx) + np.dot(r*h_prev), Wh)
h_next = (1-z) * h_prev + z * h_hat
self.cache = (x, h_prev, z, r, h_hat)
def backward(self, dh_next):
H, H3 = self.Wh.shape
Wxz , Wxr, Wx = self.Wx[:, :H], self.Wx[:, H:2*H], self.Wx[:, 2*H:]
Whz , Whr, Wh = self.Wh[:, :H], self.Wh[:, H:2*H], self.Wh[:, 2*H:]
x, h_prev, z, r, h_hat = self.cache
dh_hat = dh_next * z
dh_prev = dh_next * (1-z)
#tanh
728x90