Seq2Seq(Sequence-to-Sequence)는 입력 시퀀스를 출력 시퀀스로 변환하는 딥러닝 모델로써, 번역을 위해 등장한 모델이었다.
인코더(Encoder)와 디코더(Decoder)로 이루어진 Seq2Seq는 입력 시퀀스를 RNN Networks (ex. RNN, GRU, LSTM 등)로 이루어진 인코더가 고정된 크기의 벡터 표현(Context Vector)으로 변환한다. 그 후, 디코더가 이전 출력과 컨텍스트 벡터를 기반으로 출력 시퀀스를 생성한다. 디코더 또한 일반적으로 RNN Networks가 사용된다.
아래의 영상은 Seq2Seq에 동작 방식을 보여주고 있다.
Bahdanau et al. (2014)와 Luong et al. (2015)가 제안한 Attention Mechanism은 입력 시퀀스 전체를 참조하여 중요한 부분에 집중할 수 있도록 설계하였다. 이를 통해, 단일 컨텍스트 벡터에 의존하지 않고 입력의 각 부분을 적절히 활용할 수 있게 되었다.
입력 시퀀스의 각 요소에 가중치(Attention Score)를 할당하여, 중요한 요소에 더 높은 가중치를 부여한다.
Attention Score
Attention Weight
Context Vector
Self-Attention은 Attention Mechanism의 특수한 형태로, 입력 시퀀스 내부에서 단어 간의 관계를 학습한다.
입력 시퀀스의 각 단어가 Query, Key, Value 역할을 모두 수행한다.
Query, Key, Value
Attention Score
Attention Weight
Softmax를 통해 정규화
Context Vector
import torch
import torch.nn as nn
import torch.optim as optim
# 인코더 정의
class EncoderRNN(nn.Module):
def __init__(self, input_size, hidden_size):
super(EncoderRNN, self).__init__()
self.embedding = nn.Embedding(input_size, hidden_size)
self.rnn = nn.GRU(hidden_size, hidden_size, batch_first=True)
def forward(self, x):
embedded = self.embedding(x)
outputs, hidden = self.rnn(embedded)
return hidden
# 디코더 정의
class DecoderRNN(nn.Module):
def __init__(self, hidden_size, output_size):
super(DecoderRNN, self).__init__()
self.embedding = nn.Embedding(output_size, hidden_size)
self.rnn = nn.GRU(hidden_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x, hidden):
embedded = self.embedding(x)
outputs, hidden = self.rnn(embedded, hidden)
predictions = self.fc(outputs)
return predictions, hidden
# 하이퍼파라미터
input_size = 10 # 입력 단어 사전 크기
output_size = 10 # 출력 단어 사전 크기
hidden_size = 128
# 모델 초기화
encoder = EncoderRNN(input_size, hidden_size)
decoder = DecoderRNN(hidden_size, output_size)
# 입력 데이터 (더미 데이터)
x = torch.tensor([[1, 2, 3, 4]]) # 입력 시퀀스 (단어 인덱스)
y = torch.tensor([[1, 2, 3, 0]]) # 출력 시퀀스 (단어 인덱스)
# 인코더로 컨텍스트 벡터 생성
hidden = encoder(x)
# 디코더로 출력 시퀀스 생성
output, hidden = decoder(y[:, :-1], hidden) # Teacher Forcing
print(output.shape) # (Batch, Seq, Output Size)