[PyTorch] 순환 신경망(Recurrent Neural Network, RNN)
Posted: Updated:
AI 스터디를 하며 ‘파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습’ 교재를 정리한 글입니다.
순환 신경망(Recurrent Neural Network, RNN)
순서가 있는 연속적 데이터(Sequence data)를 처리하기 위한 인공 신경망의 한 종류
이전에 처리한 데이터를 다음 단계에 활용하고 현재 입력 데이터와 함께 모델 내부에서 과거의 상태를 기억해 현재 상태 예측
시계열 데이터, 자연어 처리, 음성 인식 및 기타 시퀀스 데이터에 사용
셀(Cell)
각 시점의 데이터를 입력으로 받아 은닉 상태와 출력값을 계산하는 노드
연속형 데이터를 순서대로 입력받아 처리하며 각 시점마다 은닉 상태(Hidden state) 형태로 저장
이전 시점의 은닉 상태 $h_{t-1}$를 입력으로 받고 현재 시점의 은닉 상태 $h_t$ 계산
은닉 상태
\[h_t = \sigma_h(h_{t-1}, x_t)\] \[h_t = \sigma_h(W_{hh} h_{t-1} + W_{xh} x_t + b_h)\]$\sigma_h$ : 은닉 상태 계산을 위한 활성화 함수로 시점 $t-1$의 은닉 상태 $h_{t-1}$와 입력값 $x_t$를 입력받아 현재 시점의 은닉 상태 $h_t$ 계산
$W_{hh}$ : 이전 시점의 은닉 상태 $h_{t-1}$에 대한 가중치
$W_{xh}$ : 입력값 $x_t$에 대한 가중치
$b_h$: 은닉 상태 $h_t$의 편향
출력값
\[y_t = \sigma_y(h_t)\] \[y_t = \sigma_y(W_{hy} h_t + b_y)\]$\sigma_y$ : 출력값 계산을 위한 활성화 함수로 현재 시점의 은닉 상태 $h_t$를 입력으로 받고 출력값 $y_t$를 계산
$W_{hy}$ : 현재 시점의 은닉 상태 $h_t$에 대한 가중치
$b_y$: 출력값 $y_t$에 대한 편향
일대다 구조(One-to-Many)
하나의 입력 시퀀스에 대해 여러 개의 출력값을 생성하는 순환 신경망 구조
자연어 처리 분야: 문장을 입력받아 각 단어의 품사 예측, 입력 시퀀스는 문장, 출력 시퀀스는 각 단어 품사
이미지 캡셔닝(Image Captioning): 이미지 데이터를 입력받아 설명 출력, 입력 시퀀스는 이미지, 출력값은 설명 문장
다대일 구조(Many-to-One)
여러 개의 입력 시퀀스에 대해 하나의 출력값을 생성하는 순환 신경망 구조
감성 분류(Sentiment Analysis): 특정 문장의 감정(긍정, 부정) 예측, 입력 시퀀스는 문장, 출력 값은 해당 문장의 감정
문장 분류: 입력 시퀀스가 어떤 범주에 속하는지 구분
자연어 추론(Natural Language Inference): 두 문장 간 관계 추론
다대다 구조(Many-to-Many)
입력 시퀀스와 출력 시퀀스의 길이가 여러 개인 경우
번역기: 입력 문장에 대해 번역된 출력 문장 생성
음성 인식기: 음성 신호를 입력받아 문장 출력
시퀀스-시퀀스(Seq2Seq)
입력 시퀀스와 출력 시퀀스 길이가 일치하지 않으면 패딩을 추가하거나 잘라내는 등 전처리 필요
인코더(Encoder): 입력 시퀀스 처리, 고정 크기 벡터 출력
디코더(Decoder): 인코더의 벡터를 입력으로 받아 출력 시퀀스 생성
양방향 순환 신경망(Bidirectional Recurrent Neural Network, BiRNN)
기본적인 순환 신경망에서 시간 방향을 양방향으로 처리
이후 시점($t+1$)의 은닉 상태도 함께 이용
다중 순환 신경망(Stacked Recurrent Neural Network)
여러 개의 순환 신경망을 연결해 구성한 모델로 각 순환 신경망이 서로 다른 정보 처리
각 층에서 출력값이 다음 층으로 전달되어 처리
층이 깊어질수록 복잡한 패턴을 학습할 수 있지만, 학습 시간이 오래 걸리고 기울기 소실 문제가 발생할 수 있음
순환 신경망 클래스
rnn = torch.nn.RNN(
input_size, # 입력값 x: 입력 특성 크기
hidden_size, # h: 은닉 상태 크기
num_layers=1, # 계층 수: 2 이상이면 다중 순환 신경망
nonlinearity="tanh", # 활성화 함수: sigma 종류로 tanh, relu 적용 가능
bias=False, # 편향 사용 유무
batch_first=True, # 배치 우선: 입력 배치 크기를 첫 번째 차원으로 사용할지 여부
dropout=0, # 과대적합 방지를 위한 드롭아웃 확률
bidirectional=False # 양방향으로 처리할지 여부
)
양방향 다층 신경망
import torch
from torch import nn
input_size = 128
ouput_size = 256
num_layers = 3
bidirectional = True
model = nn.RNN( # 입력값, 초기 은닉 상태로 순방향 연산 수행 후 출력값, 최종 은닉 상태 반환
input_size=input_size,
hidden_size=ouput_size,
num_layers=num_layers,
nonlinearity="tanh",
batch_first=True,
bidirectional=bidirectional,
)
batch_size = 4
sequence_len = 6
inputs = torch.randn(batch_size, sequence_len, input_size) # [배치 크기, 시퀀스, 입력 특성 크기]
h_0 = torch.rand(num_layers * (int(bidirectional) + 1), batch_size, ouput_size)
outputs, hidden = model(inputs, h_0)
print(outputs.shape)
print(hidden.shape)
출력
torch.Size([4, 6, 512])
torch.Size([6, 4, 256])
댓글남기기