Ⅰ. ELMo의 최종 임베딩 생성 방법: 계층별 표현의 가중합
ELMo의 강력함은 단순히 마지막 LSTM 계층의 결과만 사용하는 것이 아니라, 모델의 모든 계층(layer)에 담긴 정보를 종합하여 사용하는 데 있습니다.
ELMo는 보통 여러 층(e.g., 2-layer)의 양방향 LSTM으로 구성됩니다. 각 계층은 서로 다른 수준의 의미 정보를 학습합니다.
- 초기 입력 계층 (Character CNN): 단어의 표면적인 형태(morphology) 정보.
- 첫 번째 LSTM 계층: 주로 품사(POS)와 같은 문법적인(syntactic) 정보.
- 두 번째 (상위) LSTM 계층: 문맥에 따른 단어의 의미(semantic) 정보.
ELMo는 이 모든 계층의 표현(representation)들을 그냥 합치거나 이어 붙이는 것이 아니라, **가중합(weighted sum)**하여 최종 임베딩 벡터를 생성합니다.
가중합(weighted sum)은 각 요소의 **중요도(가중치)**를 반영하여 값을 합산하는 방식입니다. 그냥 모두 더하는 게 아니라, "어떤 것은 더 중요하게, 어떤 것은 덜 중요하게" 여기며 더하는 거죠.
쉬운 예시: 최종 성적 계산 📝
대학교에서 최종 성적을 계산할 때를 생각해 보세요.
- 중간고사: 30% 반영
- 기말고사: 50% 반영
- 과제: 20% 반영
만약 당신의 점수가 중간고사 80점, 기말고사 100점, 과제 90점이라면, 최종 성적은 단순히 (80 + 100 + 90) / 3 으로 계산되지 않아요. 각 항목의 **중요도(반영 비율)**를 곱해서 더해야 하죠.
최종 성적 = (80점 × 0.3) + (100점 × 0.5) + (90점 × 0.2) = 24 + 50 + 18 = 92점
여기서 **반영 비율(30%, 50%, 20%)**이 바로 **가중치(weight)**이고, 이렇게 계산하는 방식이 가중합입니다. 기말고사가 가장 중요하기 때문에 가장 높은 가중치가 부여되었어요.
ELMo에서의 가중합 🤖
ELMo도 똑같은 원리를 적용합니다. ELMo는 단어의 임베딩을 만들 때 여러 재료(각 계층의 정보)를 가지고 있어요.
- 재료 1 (입력층): 단어의 철자/형태 정보 (-ing, -ed 등)
- 재료 2 (1층 LSTM): 단어의 문법/품사 정보 (명사, 동사 등)
- 재료 3 (2층 LSTM): 단어의 문맥적 의미 정보 (먹는 사과 vs 회사 애플)
ELMo는 이 재료들을 그냥 섞는 게 아니라, 풀고자 하는 문제에 따라 어떤 재료가 더 중요한지 스스로 학습해서 가중치를 다르게 부여합니다.
- 만약 품사 판별 문제를 푼다면, 모델은 **'재료 2(문법 정보)'**가 가장 중요하다고 판단해 이 계층에 가장 높은 가중치를 부여할 거예요.
- 만약 문장의 의미를 파악하는 문제를 푼다면, **'재료 3(문맥적 의미)'**에 가장 높은 가중치를 부여해서 최종 임베딩을 만들죠.
결론적으로, ELMo가 가중합을 한다는 건 각 계층(형태, 문법, 의미)의 정보 중에서 현재 푸는 문제에 더 중요한 정보에 높은 가중치를 곱해, 최종적으로 가장 유용한 맞춤형 임베딩 벡터를 만들어낸다는 뜻입니다.
- : 번째 단어에 대한 번째 계층의 표현 벡터 (j=0은 초기 입력층, j>0은 LSTM 은닉 상태)
- : 각 계층의 중요도를 나타내는 소프트맥스 정규화 가중치. 이 가중치는 풀고자 하는 특정 과제(task)에 맞게 학습됩니다. 예를 들어, 품사 판별 과제에서는 첫 번째 LSTM 계층의 가중치가 높아지고, 의미 파악 과제에서는 두 번째 LSTM 계층의 가중치가 높아질 수 있습니다.
- : 전체 벡터의 크기를 조절하는 스케일링 파라미터.
결론적으로, ELMo는 특정 과제(Task)에 가장 유용한 정보가 담긴 계층에 더 높은 가중치를 부여하여, 각 계층의 정보를 동적으로 조합함으로써 문맥을 반영한 풍부한 임베딩 벡터를 생성합니다.
Ⅱ. BERT의 등장: NLP의 새로운 시대 🚀
ELMo가 동적 임베딩의 가능성을 열었지만, BERT(Bidirectional Encoder Representations from Transformers)는 그 패러다임을 완전히 바꾸어 놓았습니다.
BERT의 핵심 아이디어는 다음 세 가지로 요약됩니다.
1. 토큰화: WordPiece (Subword 기반)
- FastText나 ELMo의 Character CNN처럼, BERT 역시 단어를 더 작은 단위로 쪼개는 Subword 방식을 사용합니다.
- WordPiece는 자주 함께 등장하는 글자들을 하나의 단위로 묶는 통계적 방법입니다. 예를 들어 embedding은 em + ##bed + ##ding처럼 의미 있는 단위로 분리됩니다. (##는 단어의 중간 부분임을 표시)
- 이를 통해 OOV 문제를 해결하고 단어의 형태론적 정보를 효율적으로 처리합니다.
2. 양방향 문맥 반영: Transformer 구조 사용
이것이 ELMo와 BERT의 가장 결정적인 차이점입니다.
- ELMo의 한계 (Shallow Bidirectionality): ELMo는 순방향 LSTM과 역방향 LSTM을 독립적으로 학습한 뒤, 그 결과를 단순히 이어 붙였습니다(concatenate). 이는 진정한 의미의 양방향 소통이 아니라, 왼쪽 문맥 따로, 오른쪽 문맥 따로 본 것에 가깝습니다.
- BERT의 혁신 (Deep Bidirectionality): BERT는 RNN을 버리고 Transformer의 인코더(Encoder) 구조를 채택했습니다. Transformer의 핵심인 셀프 어텐션(Self-attention) 메커니즘은 처음부터 문장 내의 모든 단어가 서로의 관계를 동시에 참고하도록 합니다. 즉, 특정 단어의 의미를 파악할 때 왼쪽과 오른쪽 문맥을 동시에, 그리고 모델의 모든 계층에서 깊게 고려합니다. 이것이 바로 '진정한 양방향성(Deep Bidirectionality)'입니다.
3. 대규모 사전학습 (Pre-training) → 태스크별 미세조정 (Fine-tuning)
BERT는 모델 활용 방식을 표준화했습니다.
- 사전학습 (Pre-training): 먼저 엄청난 양의 텍스트 데이터(e.g., 위키피디아, 책)를 사용하여 BERT 모델이 '언어 자체'를 이해하도록 학습시킵니다. 이때 BERT는 두 가지 독창적인 과제를 수행합니다 (다음 시간에 배울 Masked Language Model, Next Sentence Prediction).
- 미세조정 (Fine-tuning): 이렇게 언어에 대한 일반적인 이해를 마친 모델을 가져와, 우리가 실제로 풀고 싶은 특정 과제(e.g., 감성 분석, 질의응답)에 맞는 소량의 데이터로 추가 학습을 진행합니다. 이 과정을 통해 모델은 특정 과제에 맞게 빠르고 쉽게 최적화됩니다.
결론적으로, BERT는 WordPiece 토큰화, Transformer를 통한 진정한 양방향 문맥 이해, 그리고 Pre-training & Fine-tuning이라는 강력한 패러다임을 제시하며 이후 등장하는 대부분의 NLP 모델의 표준을 정립했습니다.
BERT (Bidirectional Encoder Representations from Transformers) 완전 정복
BERT는 ELMo의 '사전 학습된 언어 모델'이라는 아이디어를 계승했지만, Transformer라는 강력한 아키텍처를 도입하여 '진정한 양방향성'을 구현하고, '사전학습-미세조정' 패러다임을 확립하며 NLP의 새로운 표준을 제시했습니다.
1. BERT의 입력 임베딩: 세 가지 정보의 총합
BERT는 단어의 의미를 파악하기 위해 단순히 단어 자체의 의미뿐만 아니라, 그 단어가 어느 문장에 속해 있는지, 그리고 문장 내 어느 위치에 있는지에 대한 정보까지 모두 입력으로 사용합니다. BERT의 최종 입력 임베딩은 이 세 가지 임베딩의 총합으로 구성됩니다.
- 토큰 임베딩 (Token Embeddings)
- 역할: 각 단어(Subword) 자체의 의미를 나타내는 벡터입니다.
- 방식: WordPiece라는 Subword 토크나이저를 사용합니다. playing은 play + ##ing로 분리되어 각각의 토큰 임베딩을 갖게 됩니다. 이는 OOV 문제를 해결하는 데 효과적입니다.
- 세그먼트 임베딩 (Segment Embeddings)
- 역할: 입력된 텍스트가 첫 번째 문장인지, 두 번째 문장인지를 구분해주는 역할을 합니다.
- 방식: 문장 두 개를 입력받는 과제(e.g., 질의응답, 문장 관계 추론)를 위해 설계되었습니다. 모든 첫 번째 문장 토큰들에는 임베딩을, 모든 두 번째 문장 토큰들에는 임베딩을 더해줍니다.
- 포지션 임베딩 (Position Embeddings)
- 역할: 단어의 위치(순서) 정보를 알려주는 벡터입니다.
- 필요성: Transformer는 RNN과 달리 순환 구조가 없어서, 그대로 사용하면 단어의 순서를 인지하지 못합니다. "A가 B를 때렸다"와 "B가 A를 때렸다"를 구별하지 못하게 되는 것입니다. 따라서 각 위치(0번, 1번, 2번...)에 고유한 위치 벡터를 학습시켜 더해줌으로써 모델이 단어의 순서를 이해하게 만듭니다.
결론: BERT는 **단어의 의미(Token) + 문장 구분(Segment) + 위치 정보(Position)**를 모두 합친 풍부한 정보를 바탕으로 문맥을 파악하기 시작합니다.
2. BERT의 핵심 구조: Transformer와 진정한 양방향성
BERT의 심장은 Transformer의 인코더(Encoder) 부분입니다. 이 구조가 ELMo를 뛰어넘는 '진정한 양방향성(Deep Bidirectionality)'을 가능하게 합니다.
- ELMo와의 비교: ELMo는 순방향 LSTM과 역방향 LSTM을 따로따로 학습한 후 결과를 단순히 이어 붙였습니다. 이는 마치 왼쪽 문맥을 보는 눈과 오른쪽 문맥을 보는 눈이 서로 소통하지 않는 것과 같습니다.
- BERT의 방식: Transformer의 **셀프 어텐션(Self-attention)**은 문장 내 한 단어를 처리할 때, 처음부터 문장 내의 모든 단어(왼쪽, 오른쪽 모두)를 동시에 참고합니다. "I love you"에서 "love"의 의미를 파악하기 위해 "I"와 "you"의 정보를 동시에, 그리고 모든 12개의 레이어(12-layers)를 통과하는 내내 깊게 고려합니다. 이것이 바로 진정한 양방향 소통입니다.
3. BERT의 학습 전략: Pre-training → Fine-tuning
BERT는 특정 과제를 푸는 법을 직접 배우기 전에, 먼저 '언어' 자체에 대한 깊은 이해를 하는 사전학습(Pre-training) 단계를 거칩니다.
- 사전학습 과제 1: Masked Language Model (MLM)
- 목표: 진정한 양방향 문맥 학습.
- 방식: 기존 언어 모델처럼 다음 단어를 예측하면, 예측하려는 단어의 오른쪽 문맥을 볼 수 없게 됩니다. 이 문제를 해결하기 위해 BERT는 문장의 단어 중 일부(15%)를 [MASK] 토큰으로 무작위로 가립니다. 그리고 주변의 양방향 문맥을 모두 이용하여 [MASK]에 들어갈 원래 단어가 무엇인지 맞추도록 학습합니다. 마치 빈칸 추론 문제를 푸는 것과 같습니다.
- 사전학습 과제 2: Next Sentence Prediction (NSP)
- 목표: 문장 간의 관계 이해.
- 방식: 두 문장을 [SEP] 토큰으로 이어 붙여 입력으로 준 뒤, 두 번째 문장이 실제로 첫 번째 문장 바로 다음에 오는 문장인지(IsNext), 아니면 전혀 관련 없는 문장인지(NotNext)를 맞추도록 학습합니다. 이는 질의응답(QA)이나 자연어 추론(NLI)처럼 두 문장의 관계 파악이 중요한 과제를 잘 풀기 위함입니다.
- 미세조정 (Fine-tuning):
- 이렇게 사전학습을 통해 언어에 대한 통찰력을 얻은 BERT 모델 위에, 풀고 싶은 특정 과제에 맞는 간단한 분류기(FFNN + Softmax)를 하나 추가합니다.
- 그리고 해당 과제의 데이터로 전체 모델을 아주 조금만(보통 2~4 epoch) 추가 학습시키면, 놀랍도록 높은 성능을 발휘합니다. 이것이 바로 Pre-training & Fine-tuning 패러다임입니다.
최종 요약 🎯
- 입력: 단어의 의미(Token) + 문장 구분(Segment) + 순서(Position) 정보를 모두 합쳐 사용한다.
- 구조: Transformer 인코더를 사용하여 문장 전체의 양방향 문맥을 동시에, 그리고 깊게 이해한다.
- 사전학습: **Masked LM (빈칸 맞히기)**과 **NSP (다음 문장 맞히기)**를 통해 언어 자체를 학습한다.
- 활용: 사전학습된 모델을 가져와 각 **과제에 맞게 미세조정(Fine-tuning)**하여 사용한다.
정적 임베딩의 한계와 동적 임베딩의 필요성 (제안 동기)
1. 문제점: "하나의 단어, 하나의 의미"의 한계
기존의 Word2Vec, GloVe, FastText와 같은 단어 임베딩 방식을 **정적 임베딩(Static Embedding)**이라고 부릅니다. 이 방식들의 가장 큰 문제점은 한 단어에 대해 단 하나의 고정된 벡터 값만을 할당한다는 것입니다.
하지만 실제 우리가 사용하는 언어에서 대부분의 단어는 여러 의미를 갖는 **다의어(Polysemy)**입니다.
- "I bought an **apple**." 🍎 에서는 과일을 의미합니다.
- "**Apple** released a new iPhone." 🏢 에서는 회사를 의미합니다.
정적 임베딩 모델은 이 두 "Apple"에 완전히 동일한 벡터를 부여합니다. 결과적으로 이 벡터는 '과일'과 '회사'의 의미가 어중간하게 섞인, 그 어떤 문맥에도 완벽하게 들어맞지 않는 평균적인 의미를 갖게 됩니다.
슬라이드의 한국어 예시는 이 문제를 더 명확하게 보여줍니다.
- "나는 **눈**이 좋다. 그래서 멀리 있는 것도 잘 보인다." 👀 에서는 **신체 부위(eye)**를 의미합니다.
- "나는 **눈**이 좋다. 그래서 겨울이 좋다." ❄️ 에서는 **날씨(snow)**를 의미합니다.
이처럼 단어의 의미는 전적으로 **문맥(context)**에 의해 결정되지만, 정적 임베딩은 이 문맥을 반영하지 못하는 치명적인 한계를 가집니다.
2. 해결책: "의미는 문맥이 결정한다"
이러한 한계를 극복하기 위해 등장한 것이 바로 **동적 임베딩(Dynamic/Contextualized Embedding)**입니다. 핵심 아이디어는 슬라이드에 명시된 그대로입니다.
"동일한 단어라도 문맥에 따라 그 의미가 달라질 수 있으니, 벡터 공간에서도 다르게 표현되어야 한다!"
이를 위해 모델의 작동 방식을 근본적으로 바꿨습니다.
- 입력: 단어 하나가 아닌, 문장 전체 (토큰의 집합)
- 처리 방식: 단어의 벡터를 미리 정해두는 것이 아니라, 문장이 입력되었을 때 주변 단어들과의 관계를 실시간으로 계산하여 해당 단어의 벡터를 동적으로 생성합니다.
- 결과: 이제 "Apple"이라는 단어는 문맥에 따라 완전히 다른 벡터 값을 갖게 됩니다. 'fruit'과 함께 쓰인 "apple"의 벡터는 'pear', 'orange'와 가까운 곳에 위치하고, 'iPhone'과 함께 쓰인 "Apple"의 벡터는 'Google', 'Microsoft'와 가까운 곳에 위치하게 됩니다.
슬라이드의 오른쪽 그림은 단어 임베딩이 의미를 벡터 공간에 표현하는 방식을 보여줍니다. 정적 임베딩이 king, queen, man, woman의 관계를 학습했다면, 동적 임베딩은 이 개념을 확장하여 같은 단어라도 다른 의미를 가질 때 벡터 공간의 다른 지점에 위치시키는 것을 목표로 합니다.
'코딩공부 > 자연어처리' 카테고리의 다른 글
| 내가 시험공부하려고 만든 자연어처리-n-gram (0) | 2025.10.09 |
|---|---|
| 내가 시험공부하려고 만든 자연어처리-언어모델 (0) | 2025.10.09 |
| 내가 시험공부하려고 만든 자연어처리-유도 바이어스(Inductive Bias,RNN,Transformer) (0) | 2025.10.09 |
| 내가 시험공부하려고 만든 자연어처리-동적임베딩의 필요성 (0) | 2025.10.09 |
| 내가 시험공부하려고 만든 자연어처리-FastText (1) | 2025.10.09 |









