Step 14 Transformer: 학습가능 임베딩

Self-Attention과 Multi-Head - 처음부터 학습 (소형 구조)

1. RNN/LSTM의 근본적 한계

Attention으로 많이 개선했지만, RNN/LSTM은 순차 처리라는 태생적 한계가 있습니다. 이게 왜 문제일까요?

❌ RNN/LSTM의 문제

순차 처리의 한계 RNN/LSTM: 순차 처리 (느림) t=0 t=1 t=2 → → → 한 번에 하나씩만 처리 Transformer: 병렬 처리 (빠름) 모두 동시에 처리! GPU 활용

2. Transformer: "Attention Is All You Need"

2017년 Google이 발표한 Transformer는 RNN을 완전히 버리고 Self-Attention만으로 모든 걸 해결합니다!

🚀 Transformer의 핵심 아이디어

Self-Attention:
각 단어가 문장 내 모든 단어를 한 번에 보고 관계를 파악!

예시: "The cat sat on the mat"
• "cat"은 "sat"과 관계가 깊음 (주어-동사)
• "sat"은 "mat"과 관계가 깊음 (동사-목적어)
• 모든 관계를 동시에 계산!

Self-Attention 메커니즘 The cat sat on mat "cat"의 시점 Query, Key, Value Query (Q): "나는 누구와 관련있지?" (질문) Key (K): "나는 이런 특징을 가졌어" (대답) Value (V): "내 실제 정보는 이거야" (내용) Attention(Q, K, V) = softmax(QK^T / √d_k) · V

3. Multi-Head Attention

Transformer는 Self-Attention을 여러 개 병렬로 돌립니다. 각 헤드가 다른 관점을 학습하죠!

🎭 Multi-Head Attention

Multi-Head Attention Input Embedding Head 1 주어-동사 관계 Head 2 동사-목적어 관계 Head 3 수식어-명사 관계 Head 4 위치 관계 등등... Concat & Linear

각 헤드의 역할:
• Head 1: 문법적 관계 (주어-동사)
• Head 2: 의미적 관계 (동사-목적어)
• Head 3: 수식 관계 (형용사-명사)
• Head 4: 위치/순서 정보
• ...

→ 다양한 관점을 동시에 학습!

4. Transformer Encoder 구조

분류 태스크에서는 Transformer의 Encoder만 사용합니다.

🏗️ 모델 아키텍처

Transformer Encoder for Classification Token Embedding + Positional Encoding Transformer Encoder × N Multi-Head Self-Attention Feed-Forward Network Mean Pooling or [CLS] Token
import torch
import torch.nn as nn

class TransformerClassifier(nn.Module):
    def __init__(self, vocab_size, d_model=128, nhead=2, num_layers=2, num_classes=4):
        super().__init__()
        
        # 학습가능 임베딩 (처음부터 학습!)
        self.embedding = nn.Embedding(vocab_size, d_model)
        self.pos_encoder = PositionalEncoding(d_model)
        
        # Transformer Encoder (소형: 2층, 2헤드)
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=d_model,
            nhead=nhead,
            dim_feedforward=d_model * 4,
            batch_first=True
        )
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers)
        
        # 분류 헤드
        self.fc = nn.Linear(d_model, num_classes)
    
    def forward(self, x):
        # Padding mask 생성
        padding_mask = (x == 0)
        
        # Embedding + Positional Encoding
        x = self.pos_encoder(self.embedding(x))
        
        # Transformer Encoder
        x = self.transformer(x, src_key_padding_mask=padding_mask)
        
        # Mean pooling (또는 [CLS] 토큰 사용)
        x = x.mean(dim=1)
        
        return self.fc(x)

model = TransformerClassifier(vocab_size=20000, d_model=128, nhead=2)

⚠️ 의도적으로 낮은 성능

이 Transformer는 소형 구조 + 처음부터 학습입니다:

설정:
• d_model = 128 (매우 작음, BERT는 768)
• num_heads = 2 (매우 적음, BERT는 12)
• num_layers = 2 (매우 얕음, BERT는 12)
• 임베딩 처음부터 학습 (사전학습 X)

예상 성능: 약 88-90% (Attention보다 낮음!)

이건 의도적입니다. Transformer 구조를 이해하고,
다음 Step에서 사전학습 모델을 쓰면 얼마나 좋아지는지 체감하기 위함이에요! 🎯

🚀 다음은 최종 보스!

Transformer 구조를 배웠습니다! 이제 마지막 단계예요.

지금까지:
• Step 9: MLP (원핫) → 88%
• Step 10: CNN (TF-IDF) → 90%
• Step 11: RNN (Word2Vec freeze) → 91%
• Step 12: LSTM (GloVe freeze) → 92%
• Step 13: Attention (FastText fine-tune) → 94%
• Step 14: Transformer (학습가능 임베딩) → 89% ⬇️

Step 15: RoBERTa (사전학습 + 파인튜닝) → 96%+ 🏆
사전학습의 위력을 체감해봅시다!