Attention, 메커니즘

SSO·2024년 10월 22일

Attention 메커니즘이란?

  • Attention 메커니즘은 시퀀스 데이터 중에서 중요한 부분에 더 많은 가중치를 두어 정보를 효율적으로 처리하는 기법이다.
    • 가중치는 일정 범위 내에서 해야한다. 극적으로 작거나 극적으로 높아서는 안된다.
  • 주로 자연어 처리(NLP)와 시계열 데이터에서 사용되며, 기계 번역, 요약, 질의응답 시스템 등 다양한 분야에서 뛰어난 성능을 발휘한다.

동작 방식

  1. 개요
    • Attention 메커니즘은 입력 시퀀스의 각 요소에 대해 중요도를 계산한다. 계산된 중요도는 가중치로 바뀌어, 각각의 요소에 적용된다.
    • 이를 통해 중요한 정보에 집중하고, 불필요한 정보를 무시할 수 있습니다.
    • Attention 메커니즘은 주로 세 가지 주요 구성 요소로 이루어진다.: Query(질문), Key(키), Value(최종요약)
  2. Attention score(중요도) 계산
    • Attention score는 Query와 Key 간의 유사도를 측정하여 중요도를 계산한다.
    • 유사도는 dot product(내적) 등을 사용하여 계산할 수 있습니다. dot product은 선형대수의 개념이기에, 각각을 곱한다고 생각하면 된다.
    • score(Q,K)=QKT\text{score}(Q, K) = Q \cdot K^T
  3. Softmax를 통한 가중치 계산
    • 계산된 Attention socre는 Softmax 함수를 통해 확률 분포로 변환된다.
    • 확률은 0과 1 사이 값이다.
    • 이를 통해 가중치의 합이 1이 되도록한다.
    • αi=exp(score(Q,Ki))jexp(score(Q,Kj))\alpha_i = \frac{\exp(\text{score}(Q, K_i))}{\sum_{j} \exp(\text{score}(Q, K_j))}
  4. Softmax를 통한 가중치 계산
    • Softmax를 통해 score가 가중치로 변환하고, 가중치를 Value에 곱하여 최종 Attention 출력을 계산한다.
    • Attention(Q,K,V)=iαiVi\text{Attention}(Q, K, V) = \sum_{i} \alpha_i V_i

Attention 종류(Self-Attention과 Multi-Head Attention)

1. Self-Attention

  • Self-Attention은 시퀀스 내의 각 요소가 서로를 참조하는 메커니즘입니다. 입력 시퀀스의 모든 요소가 Query, Key, Value로 사용된다.

  • 이를 통해 각 요소가 시퀀스 내 다른 요소들과의 관계를 학습할 수 있다.

  • 예를 들어, 문장 내에서 단어 간의 관계를 학습하여 번역이나 요약에 활용할 수 있다.

  • <Self-Attention 메커니즘의 구현> Scaled Dot-Product Attention

import torch
import torch.nn.functional as F

def scaled_dot_product_attention(Q, K, V):
    d_k = Q.size(-1)  # Key의 차원 수
    scores = torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k, dtype=torch.float32))  # 유사도 계산 및 스케일링
    attn_weights = F.softmax(scores, dim=-1)  # Softmax를 통한 가중치 계산
    output = torch.matmul(attn_weights, V)  # 가중합을 통한 최종 출력 계산
    return output, attn_weights

 2. Multi-Head Attention

  • Multi-Head Attention은 여러 개의 Self-Attention을 병렬로 수행하는 메커니즘이다.

  • 각 헤드는 서로 다른 부분의 정보를 학습하며, 이를 통해 모델이 다양한 관점에서 데이터를 처리할 수 있다.

  • <Multi-Head Attention 메커니즘의 구현>

class MultiHeadAttention(nn.Module):
    def __init__(self, embed_size, heads):
        super(MultiHeadAttention, self).__init__()
        self.embed_size = embed_size
        self.heads = heads
        self.head_dim = embed_size // heads

        assert (
            self.head_dim * heads == embed_size
        ), "Embedding size needs to be divisible by heads"

        self.values = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.keys = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.queries = nn.Linear(self.head_dim, self.head_dim, bias=False)
        self.fc_out = nn.Linear(heads * self.head_dim, embed_size)

    def forward(self, values, keys, query, mask=None):
        N = query.shape[0]
        value_len, key_len, query_len = values.shape[1], keys.shape[1], query.shape[1]

        # Linear transformations
        values = self.values(values).view(N, value_len, self.heads, self.head_dim)
        keys = self.keys(keys).view(N, key_len, self.heads, self.head_dim)
        queries = self.queries(query).view(N, query_len, self.heads, self.head_dim)

        # Scaled dot-product attention
        out, _ = scaled_dot_product_attention(queries, keys, values)

        out = out.view(N, query_len, self.heads * self.head_dim)
        out = self.fc_out(out)
        return out



가중치를 두어 보다 중요한 정보만 중심으로 정리하는 데이터 처리 기법을 배우게 되었다. 정보를 요약할 때 유용하게 쓰일 것 같다.

profile
개발자로 한걸음씩!

0개의 댓글