데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      Attention 메커니즘: 개념과 활용

      xipert 25.09.12
      2,217 5 1
      DEVOTEE 요약
      Attention 기법은 입력 데이터 중 중요한 정보에 더 높은 가중치를 부여해 모델이 효율적으로 문맥을 이해하도록 돕는 방식으로, 특히 RNN이나 LSTM의 장기 의존성 문제를 해결하며 NLP 분야에서 핵심 기술로 자리 잡았습니다. Query(질문), Key(단서), Value(답변)의 상호작용을 통해 중요도를 계산하고, 이를 기반으로 데이터를 처리하며, Self-Attention을 활용한 Transformer 모델은 병렬 처리 가능성과 뛰어난 성능으로 다양한 언어 모델(예: BERT, ChatGPT)에 기여하고 있습니다. 또한, Attention 메커니즘은 토큰화, 임베딩, 가중치 계산 등 단계별로 작동하며, Python 기반의 PyTorch와 TensorFlow로 구현 가능해 실제 코드로도 쉽게 사용됩니다.
      DEVOTEE 추천 블로그

      딥러닝과 자연어 처리(NLP)에서 빠질 수 없는 개념이 바로 Attention 기법입니다.

      입력데이터를 처리할 때, 모든 정보를 동일하게 바라보는 대신 더 중요한 정보에 집중할 수 있도록 하는 기법입니다.

      사람들이 긴 문장을 읽을 때, 핵심 키워드에 더 주의를 기울이는 방식과 유사한 방식이라고 보면 될 것 같습니다.


      1. Attention의 필요성

      기존의 RNN(Recurrent Neural Network)이나 LSTM(Long Short-Term Memory) 모델은 긴 시퀀스 데이터를 처리할 때, 앞부분의 정보가 점점 희미해지는 문제가 있었습니다.

      예를 들어, “나는 어제 친구와 영화를 봤는데, 그 영화는 정말 재미있었다”라는 문장에서 "재미있었다." 라는 표현을 이해하려면 앞의 "영화" 라는 단어와 연결해야 합니다.

      하지만 기존의 전통적인 모델은 앞의 단어를 잃어버리는 장기 의존성 문제(Long-Term Dependency)를 가지고 있었습니다.

      Attention 기법은 입력 시퀀스 전체를 살펴보면서, 현재 출력에 필요한 단어와 그렇지 않은 단어에 가중치를 매겨서 구합니다.

      즉, 모델이 “어떤 단어에 집중해야 할지” 스스로 학습하게 됩니다.

      Self-Attention과 Transformer의 등장

      특히 2017년 등장한 Transformer 모델은 Self-Attention을 기반으로 설계되어, RNN 없이도 병렬 처리가 가능해졌습니다.

      이로 인해 번역, 요약, 질의응답 등 다양한 NLP 작업에서 비약적인 성능 향상이 이루어졌습니다.

      지금 우리가 흔히 접하는 ChatGPT나 BERT 같은 모델도 모두 이 Attention 메커니즘을 활용합니다.

      Attention 기법의 이해

      간단히 말해, Attention은 **가중치 기반의 ‘집중도 점수’**를 계산하는 과정입니다.

      각 입력 토큰(token)이 현재 문맥에서 얼마나 중요한지 수치로 평가하고, 그 점수를 바탕으로 모델이 더 정확한 출력을 내놓습니다.

      이를 통해 문맥 이해력이 뛰어나고, 긴 문장도 효율적으로 다룰 수 있는 강력한 언어 모델이 가능해졌습니다.


      Attention 은 입력 정보에 더 큰 가중치를 두는 메커니즘 입니다.

      Attention 에 대한 정리와 간단한 예제를 만들었습니다.


      Attention 은 토큰 → 임베딩 → Q/K/V 값 변환 → 스코어 계산 → 가중치 계산 → 출력 순으로 작동하는 기법입니다.


      2. Attention 작동 방식

      Query (Q)(질문): “지금 내 입장에서 누구를 참고하면 좋지?”, “내가 지금 필요한 게 뭐지?”

      Key (K)(단서): “각 단어가 가진 힌트/특징”,“내가 가진 단서는 이런 거야.”

      Value (V)(정보): “그 단어를 참고하면 실제로 가져갈 정보”, “내가 줄 수 있는 실제 정보야.”


      Q로 K와 얼마나 잘 맞는지 점수(유사도)를 매기고, 그 점수로 V를 섞어 평균(가중치)을 만드는 게 Attention입니다.


      즉, Q는 질문, K는 질문과 맞출 단서, V는 최종 대답이라고 보면 될 것 같습니다.

      예시 ① 도서관에서 책 찾기

      Q (Query): “나는 지금 ‘역사’ 관련 책을 찾고 있어.”

      K (Key): “ ‘역사’라는 주제 태그가 달린 책이야.”

      V (Value): “내가 가진 실제 내용은 ‘조선시대 역사’야.”

      • Q가 ‘역사’라는 관심사를 던지면, K 중에서 맞는 걸 찾아서 V(책 내용)를 가져옵니다.

      예시 ② 친구에게 질문하기

      Q (Query): “오늘 저녁 뭐 먹을까?”

      K (Key): “나는 ‘피자’를 좋아하는 친구야.”

      V (Value): “내 대답은 ‘피자 먹자!’”

      • Q가 질문을 던지면, 친구들의 성향(K)과 가장 잘 맞는 Value(대답)가 선택됩니다.


      3. 흐름 설명

      1) 토큰을 정수로 바꾸기(토크나이징 & 인덱싱)

      • 텍스트를 모델이 처리할 수 있는 정수 시퀀스로 변환합니다.

      • 예시

        . 토큰: ["나는", "회사에", "간다."]

        . 단어사전(vocab) 매핑: {"나는":0, "회사에":1, "간다.":2}

        . 입력 시퀀스: [0, 1, 2]

      2) 임베딩(Embedding)으로 연속 벡터 만들기

      • 각 정수 토큰을 길이 d_model의 실수 벡터로 매핑합니다.(단어 임베딩)

      • Embedding(vocab_size=3, output_dim=4)

      • 입·출력 모양(Shape)

        . 입력: 길이 L=3(세 토큰)

        . 출력 임베딩: embeddings의 모양 (L=3, d_model=4)

        → 각 단어를 길이 4개 짜리 실수 벡터로 바꿈.

        embeddings 결과는 (L=3, d_model=4) 텐서로 변환됨.

      3) Q, K, V 계산 (선형 변환)

      . Q=EWq, K=EWk, V=EWv

      . 같은 임베딩을 서로 다른 가중치로 변환해 질문(Q)·단서(K)·답정보(V) 역할을 하게 함.

      . shape는 모두 (3, 4)

      4) 유사도 점수 계산 (Dot-Product)

      . score = QKᵀ , Shape (3,3)

      5) 스케일링 (Scaled Dot-Product Attention)

      . scores_scaled = ​image.png

      6) 가중치(확률)로 변환

      softmax를 사용하여 가중치 확률로 변환

      A = softmax(scores_scaled )

      7) 최종 출력 계산

      output = AV

      8) 각 단계별 Shape

      • 입력 토큰 수 L=3, 차원 d=4

        . E(임베딩) : (3,4)

        . Wq,Wk,Wv : (4,4)

        . Q,K,V : (3,4)

        . QKᵀ(score) : (3,3) <- 쿼리수, 키

        . softmax → attention weights A : (3, 3)

        . O=AV: (3, 4)

      [PyTorch 사용 예제]

      import torch
      import torch.nn as nn
      import torch.nn.functional as F
      
      
      def scaled_dot_product_attention(Q, K, V, mask=None):
          """
          Scaled Dot-Product Attention (직접 Softmax 계산 포함).
          Args:
              Q, K, V: (L, d_model)
              mask: (L, L) boolean tensor. True=마스킹 아웃
          """
          d_k = Q.size(-1)
          scores = Q @ K.transpose(-2, -1) / (d_k ** 0.5)  # (L,L)
      
          if mask is not None:
              scores = scores.masked_fill(mask, float("-inf"))
      
          weights = F.softmax(scores, dim=-1)  # (L,L)
          output = weights @ V                  # (L,d_model)
          return output, weights, scores
      
      
      def demo():
          tokens = ["나는", "회사에", "간다."]
          input_ids = torch.tensor(list(range(len(tokens))), dtype=torch.long)
          print("Tokens:", tokens)
          print("IDs   :", input_ids.tolist())
      
          vocab_size = len(tokens)
          d_model = 4
          torch.manual_seed(42)
          embedding = nn.Embedding(vocab_size, d_model)
          x = embedding(input_ids)  # (L,d_model)
          print("\n[임베딩]\n", x.detach())
      
          # Q, K, V 선형변환
          W_Q = nn.Linear(d_model, d_model, bias=False)
          W_K = nn.Linear(d_model, d_model, bias=False)
          W_V = nn.Linear(d_model, d_model, bias=False)
          Q, K, V = W_Q(x), W_K(x), W_V(x)
      
          out, attn, scores = scaled_dot_product_attention(Q, K, V)
          print("\n[Scores]\n", scores.detach())
          print("\n[Attention Weights]\n", attn.detach())
          print("\n[Output]\n", out.detach())
      
      
      if __name__ == "__main__":
          torch.set_printoptions(precision=6, sci_mode=False)
          demo()

      [결과]

      image.png


      [Tensorflow 사용 예제]

      from __future__ import annotations
      import numpy as np
      import tensorflow as tf
      
      def scaled_dot_product_attention(Q, K, V, mask=None):
          """
          Scaled Dot-Product Attention 계산.
          """
          d_k = tf.cast(tf.shape(K)[-1], tf.float32)
          scores = tf.matmul(Q, K, transpose_b=True) / tf.sqrt(d_k)  # (L,L)
      
          if mask is not None:
              mask = tf.cast(mask, tf.bool)
              very_neg = tf.constant(-1e9, dtype=scores.dtype)
              scores = tf.where(mask, scores, very_neg)
      
          weights = tf.nn.softmax(scores, axis=-1)  # (L,L)
          output = tf.matmul(weights, V)            # (L,d_k)
          return output, weights, scores
      
      def demo():
          tokens = ["나는", "회사에", "간다."]
          input_ids = list(range(len(tokens)))
          print("Tokens:", tokens)
          print("IDs   :", input_ids)
      
          vocab_size = len(tokens)
          d_model = 4
          tf.random.set_seed(42)
          embedding = tf.keras.layers.Embedding(vocab_size, d_model)
          x = embedding(tf.constant(input_ids, dtype=tf.int32))  # (L, d_model)
          print("\n[임베딩]\n", x.numpy())
      
          # Q, K, V
          W_Q = tf.keras.layers.Dense(d_model, use_bias=False)
          W_K = tf.keras.layers.Dense(d_model, use_bias=False)
          W_V = tf.keras.layers.Dense(d_model, use_bias=False)
          Q, K, V = W_Q(x), W_K(x), W_V(x)
      
          out, attn, scores = scaled_dot_product_attention(Q, K, V)
          print("\n[Scores]\n", scores.numpy())
          print("\n[Attention Weights]\n", attn.numpy())
          print("\n[Output]\n", out.numpy())
      
      if __name__ == "__main__":
          np.set_printoptions(precision=6, suppress=True)
          demo()

      [결과]

      image.png

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      xipert 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기