Attention Mechanism

Seohyeon Park·2025년 3월 24일

Intro.

1. Seq2Seq

Seq2Seq(Sequence-to-Sequence)는 입력 시퀀스를 출력 시퀀스로 변환하는 딥러닝 모델로써, 번역을 위해 등장한 모델이었다.

인코더(Encoder)와 디코더(Decoder)로 이루어진 Seq2Seq는 입력 시퀀스를 RNN Networks (ex. RNN, GRU, LSTM 등)로 이루어진 인코더가 고정된 크기의 벡터 표현(Context Vector)으로 변환한다. 그 후, 디코더가 이전 출력과 컨텍스트 벡터를 기반으로 출력 시퀀스를 생성한다. 디코더 또한 일반적으로 RNN Networks가 사용된다.

아래의 영상은 Seq2Seq에 동작 방식을 보여주고 있다.

2. Seq2Seq의 한계

  • Seq2Seq는 입력 시퀀스와 출력 시퀀스가 다르더라도 처리가 가능하다는 것이 장점이지만, 하나의 컨텍스트 벡터를 사용하면서 정보의 소실을 야기했다.
  • RNN Networks를 기반으로 구성되다 보니, 긴 입력에 시퀀스에 대해서 초기 정보가 사라지는 장기 의존성 문제가 존재 했다.

3. Attention의 제안

Bahdanau et al. (2014)와 Luong et al. (2015)가 제안한 Attention Mechanism은 입력 시퀀스 전체를 참조하여 중요한 부분에 집중할 수 있도록 설계하였다. 이를 통해, 단일 컨텍스트 벡터에 의존하지 않고 입력의 각 부분을 적절히 활용할 수 있게 되었다.

Attention Mechanism 구조.

입력 시퀀스의 각 요소에 가중치(Attention Score)를 할당하여, 중요한 요소에 더 높은 가중치를 부여한다.

1. 구성 요소

  • Query (qq)
    • 출력 시퀀스를 생성하기 위해 사용하는 현재 상태 (보통 디코더의 은닉 상태)
    • 입력 데이터 중에서 어떤 정보가 중요한지 결정하기 위한 질문(Query) 역할
    • Key의 연관성을 계산하여 Attention Score를 생성
    • 기계 번역에서, 프랑스어 단어를 생성할 때 "je"를 생성하려면 Query는 "je"에 필요한 정보를 입력 시퀀스에서 찾는 역할
  • Key (kk)
    • 입력 시퀀스의 각 요소를 식별하는 고유한 특성을 나타내는 벡터 값
    • 입력 시퀀스의 각 단어(또는 요소)가 Key에 해당
    • 입력 문장 "I love machine learning"에서 Key는 각각의 단어("I", "love", "machine", "learning")를 표현
  • Value (vv)
    • 입력 시퀀스의 실제 정보를 포함하는 벡터로 Key와는 달리, Value는 입력의 특성(값)을 그대로 반영
    • Attention Score를 사용해 Value의 가중합을 계산하여 최종 출력(Context Vector)
    • Key가 Query와 유사하다면, 해당 Key에 대응하는 Value가 높은 가중치로 출력 벡터에 반영

2. 구성 요소간 관계

  1. Attention Score

    score(q,ki)=qTkiscore(q,k_i)=q^Tk_i
    • Query와 Key 간의 유사도를 측정하여 Attention Score를 계산
    • 대표적인 유사도 계산 방식: 내적(dot product), Cosine Similarity 등
  2. Attention Weight

    αi=softmax(score(qi,ki))=exp(score(qI,ki))jexp(score(q,kj))\alpha_i=softmax(score(q_i,k_i))=\frac{exp(score(q_I,k_i))}{\sum_jexp(score(q,k_j))}
    • Attention Score를 정규화하여 확률 분포 형태로 변환, Softmax 적용
  3. Context Vector

    c=iαivic=\sum_i\alpha_iv_i
    • Attention Weight를 Value에 곱하여 입력의 중요한 정보를 추출

3. Self Attention

Self-Attention은 Attention Mechanism의 특수한 형태로, 입력 시퀀스 내부에서 단어 간의 관계를 학습한다.

입력 시퀀스의 각 단어가 Query, Key, Value 역할을 모두 수행한다.

  1. Query, Key, Value

    Q=XWQ,K=XWK,V=XWVQ=XW_Q,\quad K=XW_K,\quad V=XW_V
  2. Attention Score

    score=QKTdk,dk=keydimscore=\frac{QK^T}{\sqrt{d_k}},\quad d_k=key\,dim
  3. Attention Weight

    Softmax를 통해 정규화

  4. Context Vector

    c=softmax(QKTdk)Vc=softmax(\frac{QK^T}{\sqrt{d_k}})V

Seq2Seq with Attention 예시.

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)

Reference.

profile
카페에서 한줄 한줄

0개의 댓글