AI/딥러닝

GRU(Gated Recurrent Unit) 정리

daeunnniii 2024. 3. 17. 16:42
728x90
반응형

GRU (Gated Recurrent Unit)

  • GRU는 Gate 메커니즘이 적용된 RNN 프레임워크의 일종으로 LSTM에 영감을 받았고, LSTM보다 조금 더 간단한 구조를 가지고 있음.
  • 대한민국의 조경현 박사님이 제안한 방법.
  • GRU는 LSTM과 마찬가지로 Gate 개념 사용. GRU의 핵심은 아래 두가지이다.
  • (1) LSTM의 forget gate와 input gate를 통합하여 하나의 'update gate'를 만든다.
    • GRU는 크게 reset gateupdate gate로 나뉨.
  • (2) Cell State와 Hidden State를 통합한다.
    • GRU는 memory cell을 사용하지 않음.
  • GRU는 LSTM에 비하여 파라미터수가 적기 때문에 연산 비용이 적게 들고, 구조도 더 간단하지만, 성능에서도 LSTM과 비슷한 결과를 낸다.

 

GRU 연산 과정

  • [1] Reset gate, r(t): 과거의 정보를 얼마나 잊어야하는지를 결정한다.
    • 직전 시점의 은닉층의 값과 현시점의 정보에 가중치를 곱하여 $ r_t $를 얻는다.

 

 

  • [2] Update gate, z(t): LSTM의 forget gate와 input gate를 결합한 gate로 이전 상태와 현재 상태를 얼마만큼의 비율로 반영할지 결정한다.
    • Update gate에서는 sigmoid로 출력된 결과 $ u_t $는 현시점의 정보의 양을 결정하고, 1에서 뺀 값 $ (1-u_t) $는 직전 시점의 은닉층의 정보에 곱해주며, 각각이 LSTM의 input gate와 forget gate와 유사하다.

 

  • [3] Candidate
    • 현 시점의 정보 후보군을 계산하는 단계이다. 핵심은 과거 은닉층의 정보를 그대로 이용하지 않고 리셋 게이트의 결과를 곱하여 이용한다.

  • [4] 은닉층 계산
    • 마지막으로 update gate 결과와 candidate 결과를 결합하여 현시점의 은닉층을 계산하는 단계이다.
    • sigmoid 함수의 결과는 현시점 결과의 정보의 양을 결정하고, 1-sigmoid 함수의 결과는 과거 시점의 정보 양을 결정한다.

Pytorch를 활용한 GRU 구현

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
 
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
import torch.optim as optim
 
import matplotlib.pyplot as plt
from tqdm import trange
 
# 데이터 불러오기
'''
생략
'''
# GRU 모델 구현
class GRU(nn.Module):
     
    def __init__(self, input_size, hidden_size, sequence_length, num_layers, device):
        super(GRU, self).__init__()
        self.device = device
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.gru = nn.GRU(input_size, hidden_size, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_size*sequence_length, 1)
         
    def forward(self, x):
        h0 = torch.zeros(self.num_layers, x.size()[0], self.hidden_size).to(self.device)
        out, _ = self.gru(x, h0)
        out = out.reshape(out.shape[0], -1) # <- state 추가
        out = self.fc(out)
        return out
 
model = GRU(input_size=input_size,
                   hidden_size=hidden_size,
                   sequence_length=sequence_length,
                   num_layers=num_layers, device=device)   
 
model = model.to(device)
 
criterion = nn.MSELoss()
 
lr = 1e-3
num_epochs = 100
optimizer = optim.Adam(model.parameters(), lr=lr)
 
# 모델 학습
loss_graph = []
n = len(train_loader)
pbar = trange(num_epochs)
 
for epoch in pbar:
    running_loss = 0.0
     
    for data in train_loader:
         
        seq, target = data # 배치 데이터
        out = model(seq)
        loss = criterion(out, target)
         
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
     
    l = running_loss/n
    loss_graph.append(l)
    pbar.set_postfix({'epoch': epoch+1, 'loss' : l})
 
# loss 시각화
plt.figure(figsize=(16,8))
plt.plot(loss_graph)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.show()

 

LSTM & GRU 비교

LSTM GRU
Control the exposure of memory content (cell state) Expose the entire cell state to other units in the network
gate 수 3개(forget, input, output) gate 수 2개(reset, update)
Has separate input and forget gates Performs both of these operations together via update gate
More parameters Fewer parameters

 

참고:

https://yjjo.tistory.com/18

https://ctkim.tistory.com/

728x90
반응형