← --library
이과 · 21이과

인공지능 및 생성형 AI

AI & Generative AI

단계1단계2단계3단계4단계5

2단계: 이미지가 '보인다'는 것, 언어가 '흐른다'는 것 — CNN, RNN, Transformer의 세계


I. 이론적 기초 — 왜 MLP로는 부족한가?

1단계에서 우리는 신경망의 기본 구조인 퍼셉트론과 역전파를 배웠다. 가중치(weight)가 어떻게 손실 함수(loss function)를 최소화하는 방향으로 경사하강법(gradient descent)을 통해 업데이트되는지를 이해했다. 이제 자연스럽게 다음 질문이 생긴다: "그냥 MLP를 더 크게 만들면 이미지도 인식하고 언어도 번역할 수 있지 않나?"

실제로 수치를 계산해보자. 28×28 픽셀 흑백 이미지 하나를 MLP에 넣으려면 784개의 숫자로 펼쳐서(flatten) 입력층에 넣어야 한다. 224×224 컬러 이미지라면 224×224×3 = 150,528개의 숫자가 된다. 이걸 첫 번째 은닉층 1,000개 노드와 완전히 연결(fully connected)하면 벌써 1억 5천만 개의 가중치가 필요하다. 파라미터 폭발 문제는 그나마 감당할 수 있다. 진짜 치명적인 문제는 따로 있다.

그것은 공간 정보의 상실이다. 고양이 사진을 예로 들어보자. 고양이의 귀가 왼쪽 위에 있든 오른쪽 위에 있든, MLP는 단순히 픽셀 번호 1번, 2번, 3번...으로만 인식한다. 서로 인접한 픽셀들이 "가까이 있다"는 사실 자체를 MLP는 모른다. 결국 고양이 사진을 가로로 조금 이동시키면 MLP는 완전히 다른 입력이라고 인식해버린다. 이것이 이동 불변성(translation invariance) 문제다.

언어도 마찬가지다. "I love you"라는 문장을 번역하려면 'I', 'love', 'you'가 각각 어떤 순서로 어떤 관계를 맺는지를 파악해야 한다. 그런데 MLP에 단어들을 순서 없이 넣으면 "you love I"도 같은 문장이 돼버린다. 순서(order)와 맥락(context)이 사라지는 것이다.

이 두 가지 근본적 한계 — 공간 지역성의 무시, 시간적 순서의 무시 — 를 극복하기 위해 전혀 다른 철학으로 설계된 구조들이 등장했다. CNN은 공간 지역성을 존중하고, RNN/LSTM은 시간 순서를 존중하며, Transformer는 "그냥 모든 관계를 한 번에 다 보면 어떨까?"라는 발상으로 둘 다를 넘어서려 했다. 이 세 가지 혁명을 차례로 깊이 파헤쳐보자.


II. CNN — 이미지를 '눈'처럼 처리하는 법

합성곱 연산: 필터가 이미지를 훑는다

**합성곱(Convolution)**은 이름이 무섭지만 실제로는 단순하다. 종이 위에 5×5 격자의 숫자들이 있다고 하자. 이것이 입력 이미지다. 여기에 3×3 크기의 **필터(filter, 또는 kernel)**를 왼쪽 위부터 한 칸씩 슬라이딩하며 놓는다. 필터가 놓인 자리의 9개 숫자와 필터의 9개 숫자를 각각 곱한 후 전부 더한다. 이 숫자 하나가 출력의 한 칸이 된다. 필터를 오른쪽으로 한 칸 밀고, 또 곱하고 더한다. 이 과정이 끝나면 **특성 맵(feature map)**이라 불리는 출력이 만들어진다.

이때 핵심은 "필터의 숫자들이 무엇이냐"이다. 이것이 바로 학습 대상, 즉 **가중치(weight)**다. 1단계에서 배웠듯 역전파를 통해 이 필터의 값들이 조금씩 업데이트된다. 초기에는 랜덤값이지만, 수만 번 학습을 반복하면 어떤 필터는 수평선 경계(edge)를 감지하고, 어떤 필터는 수직선을, 어떤 필터는 특정 색상 패턴을 감지하도록 자연스럽게 특화된다.

여기서 중요한 통찰이 있다. 같은 필터가 이미지 전체를 훑는다. 왼쪽 위에서 수평선을 감지한 그 필터가 오른쪽 아래에서도 수평선을 감지한다. 이것을 **가중치 공유(weight sharing)**라고 한다. 덕분에 파라미터 수가 극적으로 줄고, 고양이 귀가 어디 있든 같은 필터가 감지해준다 — 이동 불변성 문제가 해결된다.

[노트 기록] 중요 하이퍼파라미터:

  • 스트라이드(stride): 필터를 몇 칸씩 이동할지. 클수록 출력이 작아짐
  • 패딩(padding): 입력 가장자리에 0을 채워 출력 크기를 유지
  • 출력 크기 공식: ⌊(입력 크기 − 필터 크기 + 2×패딩) / 스트라이드⌋ + 1

실제로 계산해보자. 28×28 입력에 3×3 필터, 스트라이드 1, 패딩 0이면: ⌊(28−3+0)/1⌋+1 = 26×26이 된다. 스스로 패딩을 1로 바꾸면 어떻게 되는지 계산해보라.

풀링과 계층적 특징 추출

합성곱 층 다음에는 보통 풀링(pooling) 층이 온다. 가장 흔한 **맥스 풀링(max pooling)**은 2×2 영역에서 가장 큰 값만 남기고 나머지를 버린다. 왜 버리는가? 이유는 두 가지다. 계산량을 줄이고, 작은 위치 변화에 더 강건하게 만들기 위해서다. 수평선이 한 픽셀 위로 올라가도, 그 주변의 최대값은 바뀌지 않을 가능성이 높으니까.

이제 CNN의 전체 그림이 보인다. 합성곱 → 활성화 함수(ReLU) → 풀링의 블록을 여러 번 쌓는다. **얕은 층(early layers)**에서 필터들은 에지(edge), 코너, 색상 같은 저수준(low-level) 특징을 감지한다. **깊은 층(deeper layers)**에서는 이 저수준 특징들이 조합되어 고수준(high-level) 특징 — 눈, 코, 귀, 얼굴 전체 — 을 감지하게 된다. 이것이 **계층적 특징 추출(hierarchical feature extraction)**의 핵심이다. 마지막에는 특성 맵을 펼쳐(flatten) 완전 연결층(FC layer)에 넣고, 소프트맥스(softmax) 함수로 각 클래스의 확률을 출력한다 — 1단계에서 배운 로지스틱 회귀의 다중 클래스 버전이다.

아키텍처의 진화: LeNet에서 ResNet까지

[노트 기록] 주요 CNN 아키텍처 계보: LeNet(1998) → AlexNet(2012, ImageNet 혁명) → VGG(2014) → GoogLeNet/Inception(2014) → ResNet(2015) → EfficientNet(2019)

LeNet-5(LeCun, 1998)는 최초의 실용적 CNN으로, MNIST 손글씨 숫자 인식에 쓰였다. 합성곱 2개, 풀링 2개, FC 3개라는 단순 구조였으며, 1단계에서 직접 구현한 MLP 분류기보다 훨씬 적은 파라미터로 더 높은 성능을 냈다. AlexNet(Krizhevsky et al., 2012)이 진짜 혁명이었다. ImageNet 대회(ILSVRC 2012)에서 기존 방법들보다 10% 이상 낮은 오류율을 달성하며 딥러닝 시대의 서막을 열었고, GPU 병렬 학습, 드롭아웃(dropout), ReLU 활성화 함수를 적극 활용했다.

ResNet(He et al., 2015)은 더 흥미로운 문제를 해결한다. 네트워크를 100층 이상으로 깊게 쌓으면 오히려 성능이 떨어지는 **퇴화 문제(degradation problem)**가 있었다. ResNet은 **스킵 연결(skip connection, 또는 residual connection)**로 이를 돌파했다. 층의 출력 F(x)를 학습하는 대신, 입력 x를 그대로 더한 F(x) + x를 출력한다. 최악의 경우 F(x)가 0이 되어 입력을 그대로 통과시키는 항등 함수(identity function)를 학습할 수 있어, 더 깊은 층을 쌓아도 성능이 저하되지 않는다. 152층짜리 ResNet이 당시 인간 수준의 이미지 인식 정확도를 달성했다.

스스로 생각해보자: 왜 스킵 연결이 역전파(backpropagation)를 도울까? 1단계에서 배운 기울기 소실(vanishing gradient) 문제와 연결해서 생각해보라. 덧셈 연산의 미분값이 무엇인지 떠올리면 힌트가 보인다.


III. RNN, LSTM, GRU — 시간의 흐름을 기억하다

순환 구조의 직관

이미지는 2D 공간 구조를 가진다. 텍스트, 오디오, 주가 데이터는 **시간적 순서(temporal sequence)**를 가진다. "나는 밥을 먹었다"에서 '먹었다'의 의미는 앞의 '나는', '밥을'이 있어야 완성된다. MLP는 이 순서를 무시한다. 그래서 등장한 것이 **순환 신경망(Recurrent Neural Network, RNN)**이다.

RNN의 핵심 아이디어는 은닉층(hidden layer)이 이전 타임스텝의 자신의 출력을 다음 타임스텝의 입력으로 다시 받는다는 것이다.

[노트 기록] RNN 기본 수식: h_t = tanh(W_h · h_{t-1} + W_x · x_t + b) y_t = W_y · h_t + b_y h_t = 현재 은닉 상태, h_{t-1} = 이전 은닉 상태, x_t = 현재 입력 W_h와 W_x는 모든 타임스텝에서 공유 — CNN의 가중치 공유와 동일한 철학이다.

"오늘 날씨가 맑다"를 처리할 때: '오늘' → h₁ → '날씨가' → h₂ → '맑다' → h₃이 된다. h₃는 이론적으로 '오늘'의 정보까지 담고 있어야 한다. 그런데 실제로는 그렇지 않다.

기울기 소실: RNN의 아킬레스건

1단계에서 역전파를 배울 때, 기울기가 층을 거슬러 올라가면서 계속 곱해진다고 했다. RNN에서는 타임스텝이 곧 '층의 깊이'다. 100단어짜리 문장을 처리하면 역전파가 100번 일어나고, 기울기는 100번 곱해진다. tanh의 도함수는 최대 1 이하이므로 0.9를 100번 곱하면 0.9¹⁰⁰ ≈ 0.0000266... 사실상 0이다. 이것이 기울기 소실(vanishing gradient) 문제다. 초반 단어의 정보가 학습에 전혀 반영되지 않는 것이다. "나는 어제 학교에서 밥을 먹었다"에서 '나는'이 주어임을 '먹었다'에서 기억하려면, 이 먼 거리의 의존성 — 장기 의존성(long-term dependency) — 을 학습해야 하는데, 기본 RNN은 이것을 거의 하지 못한다.

LSTM: 게이트로 정보를 선택적으로 기억한다

LSTM(Long Short-Term Memory)(Hochreiter & Schmidhuber, 1997)은 이 문제를 해결하기 위해 등장했다. 핵심 아이디어는 "모든 것을 다 기억하려 하지 말고, 무엇을 기억하고 무엇을 잊을지를 신경망 스스로 학습하게 하자"이다.

LSTM은 은닉 상태 h_t에 더해 **셀 상태(cell state, C_t)**를 추가한다. 셀 상태는 일종의 '컨베이어 벨트'처럼 시간 흐름에 따라 정보를 비교적 손상 없이 전달한다. 그리고 세 개의 **게이트(gate)**가 이 흐름을 제어한다.

[노트 기록] LSTM의 세 게이트 (모두 시그모이드 σ를 사용, 출력 0~1):

  1. 망각 게이트(forget gate): "이전 셀 상태에서 무엇을 지울까?" → f_t = σ(W_f·[h_{t-1}, x_t] + b_f)
  2. 입력 게이트(input gate): "새 정보 중 무엇을 저장할까?" → i_t = σ(W_i·[h_{t-1}, x_t] + b_i)
  3. 출력 게이트(output gate): "셀 상태 중 무엇을 출력할까?" → o_t = σ(W_o·[h_{t-1}, x_t] + b_o)

셀 상태 업데이트:t = tanh(W_c·[h{t-1}, x_t] + b_c) ← 새 후보값 C_t = f_t ⊙ C_{t-1} + i_t ⊙ C̃_t ← 핵심 수식 h_t = o_t ⊙ tanh(C_t)

게이트들은 1단계에서 로지스틱 회귀에 쓰였던 그 시그모이드(σ) 함수를 통과한다. 0에 가까우면 "닫힘(정보 차단)", 1에 가까우면 "열림(정보 통과)"이다. 직관적으로 설명하자면, 주어 "나는"을 읽을 때 입력 게이트가 열려 이 정보를 셀 상태에 저장한다. 이후 "어제", "학교에서", "밥을"을 읽을 때 망각 게이트는 주어 정보를 보존하는 법을 배운다. 그리고 술어 "먹었다"에 도달했을 때 출력 게이트가 열려 주어 정보를 활용한다. LSTM은 이 모든 선택을 데이터로부터 스스로 학습한다 — 사람이 설계한 것이 아니다.

GRU: LSTM을 간소화하다

GRU(Gated Recurrent Unit)(Cho et al., 2014)는 LSTM의 게이트 구조를 단순화했다. 셀 상태와 은닉 상태를 하나로 합치고, 게이트를 3개에서 2개(업데이트 게이트 z_t, 리셋 게이트 r_t)로 줄였다. 파라미터가 적어서 학습이 빠르고, 많은 실제 태스크에서 LSTM과 비슷하거나 때로 더 좋은 성능을 낸다.

[노트 기록] GRU vs LSTM 비교:

  • LSTM: 3개 게이트, 셀 상태+은닉 상태 분리, 더 표현력이 풍부
  • GRU: 2개 게이트, 은닉 상태 하나로 통일, 파라미터 적고 빠름
  • 실무: 작은 데이터셋→GRU, 큰 데이터셋+복잡한 태스크→LSTM

그런데 LSTM/GRU도 한계가 있다. 병렬화가 불가능하다. "나는 어제..."라는 문장을 처리할 때, '어제'를 처리하려면 '나는'을 먼저 처리해야 한다. 타임스텝이 순차적으로 처리되어야 하므로 GPU의 병렬 연산 능력을 제대로 활용할 수 없다. 그리고 아무리 LSTM이 장기 기억을 잘 한다지만, 수천 토큰 거리의 의존성을 정확히 포착하기는 여전히 어렵다. 이 두 가지 한계를 정면으로 돌파한 것이 바로 Transformer다.


IV. Transformer — "Attention Is All You Need"

어텐션 메커니즘의 직관

2017년, Vaswani et al.이 발표한 논문 제목이 "Attention Is All You Need"였다. 제목 자체가 선언이다: 순환 구조 없이도, 합성곱 없이도, 어텐션(attention)만으로 모든 것이 가능하다.

어텐션 아이디어의 직관은 검색 엔진으로 설명된다. 구글에서 검색할 때 우리는 **쿼리(query)**를 입력하고, 검색 엔진은 인터넷에 저장된 키(key)-값(value) 쌍 중 쿼리와 가장 관련 있는 것들을 가져온다. Transformer도 똑같다. 번역 "나는 학교에 간다 → I go to school"을 예로 들면: '간다'를 번역할 때 모델은 이 단어를 쿼리로 만들고, 입력 문장의 모든 단어("나는", "학교에", "간다")를 각각 로 만든다. 쿼리와 각 키의 유사도를 계산하여 소프트맥스로 **어텐션 스코어(attention score)**를 만든다. 이 스코어가 높은 단어들의 **값(value)**에 더 큰 가중치를 준다.

[노트 기록] Self-Attention 핵심 수식: Attention(Q, K, V) = softmax(Q·K^T / √d_k) · V

  • Q = 쿼리 행렬, K = 키 행렬, V = 값 행렬
  • d_k = 키 벡터의 차원 (√d_k로 나누는 것은 내적값이 너무 커지는 것을 방지)
  • Q, K, V는 모두 입력에 서로 다른 가중치 행렬 W_Q, W_K, W_V를 곱해 만든다

**셀프 어텐션(self-attention)**은 입력 시퀀스가 자기 자신에 어텐션을 수행하는 것이다. "나는 학교에 간다"에서 '학교에'가 '나는'과 얼마나 관련 있는지, '간다'와 얼마나 관련 있는지를 동시에 계산한다. 이것이 바로 병렬화가 가능한 이유다. 순서대로 처리할 필요 없이 모든 단어 쌍의 관계를 한 번의 행렬 연산으로 계산할 수 있다.

스스로 생각해보자: √d_k로 나누지 않으면 어떤 문제가 생길까? 소프트맥스의 성질과 내적값의 크기를 연결해서 생각해보라.

멀티-헤드 어텐션과 포지셔널 인코딩

**멀티-헤드 어텐션(multi-head attention)**은 셀프 어텐션을 여러 번(h번) 병렬로 수행하는 것이다. 왜 여러 번인가? 하나의 어텐션 헤드는 하나의 관점만을 포착할 수 있다. 여러 헤드를 사용하면 동사-주어 관계, 형용사-명사 관계, 대명사-지시 대상 관계 등 다양한 관점을 동시에 포착할 수 있다. 각 헤드의 출력을 이어붙여(concatenate) 최종 출력을 만든다.

그런데 셀프 어텐션은 단어 간의 관계만 계산하지, 순서 정보를 전혀 담지 않는다. "나는 너를 좋아한다"와 "너는 나를 좋아한다"를 구별할 수가 없다! 이를 해결하는 것이 **포지셔널 인코딩(positional encoding)**이다. 각 위치에 고유한 벡터를 더해 위치 정보를 주입한다.

[노트 기록] 포지셔널 인코딩 (원논문 사인/코사인 공식): PE(pos, 2i) = sin(pos / 10000^(2i/d_model)) PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

인코더-디코더 구조와 현대 모델들

Transformer의 전체 구조는 **인코더(Encoder)**와 **디코더(Decoder)**로 이루어진다. 번역 태스크라면 인코더는 입력 언어 문장을 처리하고, 디코더는 출력 언어 단어를 순차적으로 생성한다. 각 인코더 블록은 멀티-헤드 셀프 어텐션 → 피드포워드(FF) 네트워크로 이루어지고, **잔차 연결(residual connection) — ResNet에서 본 그것이다 — 과 레이어 정규화(layer normalization)**가 안정적 학습을 돕는다. 아키텍처 철학이 CNN에서 Transformer까지 일관되게 흐르고 있음을 주목하라.

이 구조에서 파생된 현대 모델들을 이해하는 것이 학습목표 ③의 핵심이다. BERT(Devlin et al., 2018)는 인코더만 사용한다. 입력 문장을 양방향(bidirectional)으로 이해하는 것이 목표로, 문장의 일부 단어를 가리고(Masked Language Model, MLM) 맞추는 방식으로 사전 학습(pre-training)된다. GPT(Radford et al., OpenAI)는 디코더만 사용하며, 다음 단어를 예측하는 방식(Causal Language Model)으로 사전 학습된다. GPT-1 → GPT-2 → GPT-3 → GPT-4로 이어지며 모델 크기가 커질수록 새롭고 놀라운 능력들이 창발(emergence)한다. Vision Transformer(ViT)(Dosovitskiy et al., 2020)는 이미지에 Transformer를 적용했다. 224×224 이미지를 16×16 패치 196개로 나누고 각 패치를 단어처럼 처리하여, 충분히 큰 데이터셋에서 ResNet을 능가했다. CNN과 Transformer의 경계가 허물어지고 있는 것이다.

[노트 기록] 현대 모델 분류:

  • 인코더 전용: BERT, RoBERTa → 이해(분류, NER, QA)에 특화
  • 디코더 전용: GPT 시리즈, LLaMA → 생성(텍스트 생성)에 특화
  • 인코더-디코더: T5, BART, 원래 Transformer → 번역, 요약에 특화

V. 프로젝트 — 문제를 풀어보자

지금까지 배운 CNN, LSTM, Transformer의 원리를 실제 코드와 구현으로 연결할 시간이다. 아래 세 가지 프로젝트를 주어진 조건 안에서 직접 풀어보라. 정답은 없다 — 네가 설계하고, 구현하고, 실험하는 과정 자체가 목표다. 각 프로젝트는 약 12~15분 분량이다.


프로젝트 A: CNN 특성 맵 시각화 실험 (~15분)

배경: CIFAR-10 데이터셋(비행기, 자동차, 새, 고양이 등 10개 클래스, 32×32 컬러 이미지)을 사용한다.

문제 1. 아래 조건으로 간단한 CNN을 PyTorch로 설계하라. 합성곱 층 3개(채널 수: 32 → 64 → 128), 각 합성곱 층 뒤에 BatchNorm → ReLU → MaxPool(2×2) 적용, 마지막 FC 층으로 10개 클래스 분류. 각 층의 출력 텐서 크기(shape)를 직접 계산하여 주석으로 기록하라. 입력은 (batch, 3, 32, 32)로 시작한다.

문제 2. 학습된 모델의 첫 번째 합성곱 층 필터 32개를 matplotlib으로 시각화하라. 각 필터는 3×3 크기다. 어떤 시각적 패턴들이 보이는가? 에지(edge) 감지, 색상 감지로 분류되는 필터를 각각 최소 2개씩 지목하고, 그 필터가 왜 그런 역할을 하는지 수치(필터 값의 부호 패턴)로 설명하라.

문제 3. 동일한 고양이 이미지를 수평으로 5픽셀 이동시킨 버전을 만들어, 두 이미지의 첫 번째 층 특성 맵을 비교하라. 풀링 층 적용 전과 후 각각의 L2 거리를 계산하고 비교하라. 이동 불변성이 풀링을 통해 얼마나 달성되는지 수치로 보고하라.


프로젝트 B: LSTM vs GRU vs 기본 RNN 비교 실험 (~15분)

배경: 네이버 영화 리뷰 데이터셋(NSMC, 긍정/부정 이진 분류)을 사용한다.

문제 1. 다음 세 가지 모델을 구현하고 같은 데이터로 학습시켜라. (a) 기본 RNN: 1단, hidden_size=128 / (b) LSTM: 2단, hidden_size=128, dropout=0.3 / (c) GRU: 2단, hidden_size=128, dropout=0.3. 학습 곡선(train loss, val loss, val accuracy)을 세 모델을 같은 그래프에 그려 비교하라.

문제 2. 기울기 소실 문제를 실험으로 확인하라. 기본 RNN과 LSTM에서 역전파 시 각 타임스텝의 그래디언트 놈(gradient norm)을 기록하라. 타임스텝이 멀어질수록(즉, 문장 앞쪽으로 갈수록) 기울기가 어떻게 변하는가? 두 모델의 차이를 그래프로 시각화하고, LSTM의 어떤 구조적 특성이 이 차이를 만드는지 설명하라.

문제 3. "이 영화는 처음에는 지루했지만 결말이 정말 감동적이었다"처럼 감성이 문장 내에서 반전되는 예문 5개를 직접 작성하고 세 모델에 입력하라. 어떤 모델이 이런 장거리 의존성을 더 잘 포착하는가? 그 이유를 LSTM 게이트 동작과 연결해 설명하라.


프로젝트 C: 미니 Transformer 번역 모델 구현 (~15분)

배경: 간단한 영어→프랑스어 번역 데이터셋(Multi30k 또는 Tatoeba)을 사용한다. 풀 스케일 GPT가 아닌, 원리를 이해하기 위한 미니 Transformer를 직접 구현한다.

문제 1. 아래 명세로 셀프 어텐션 블록을 PyTorch로 구현하라: d_model=256, n_heads=8, d_ff=512. 단일 인코더 블록: MultiHeadAttention → Add&Norm → FeedForward → Add&Norm. 포지셔널 인코딩을 사인/코사인 공식으로 직접 구현하라 (nn.Embedding 사용 금지). 학습 후 attention score 행렬을 heatmap으로 시각화하고, 어떤 단어 쌍이 높은 어텐션을 받는지 분석하라.

문제 2. 인코더 3블록 + 디코더 3블록 구조의 전체 Transformer를 조립하고 학습시켜라. 영어 문장 10개를 입력하고 번역 결과를 확인하라. BLEU score를 계산하고, 잘 번역된 문장과 실패한 문장을 분류하여 실패 원인을 언어학적으로 분석하라 (문장 길이? 어휘 희소성? 어순 차이?).

문제 3 (심화). 같은 데이터로 LSTM seq2seq 모델도 구현하고 Transformer와 비교하라. **비교 지표: BLEU score, 학습 시간(초), GPU 메모리 사용량(MB)**을 표로 정리하라. Transformer가 유리한 조건과 LSTM이 유리한 조건은 각각 무엇인가? 이 단계에서 배운 병렬화, 장기 의존성 개념을 근거로 논증하라.


VI. 평가 기준 안내

이 프로젝트들은 세 가지 기준으로 평가된다. **모델 성능(50점)**은 CIFAR-10 분류 정확도와 번역 BLEU score로 측정되지만, 단순히 높은 점수가 아니라 왜 그 점수가 나왔는지 분석했는가가 중요하다. **코드 품질(30점)**은 가독성, 모듈화, 주석의 적절성을 보는데 — 1단계에서 NumPy만으로 구현했던 역전파 코드처럼, 단순히 라이브러리를 가져다 쓰는 것이 아니라 핵심 연산을 이해하고 작성했는가가 핵심이다. **발표(20점)**는 "이 모델이 왜 이렇게 동작하는가"를 논리적으로 설명하는 능력이다. 수식을 암기하는 것이 아니라, ResNet의 스킵 연결이 기울기 소실을 막는 이유, LSTM 게이트가 장기 의존성을 가능하게 하는 이유, Transformer의 행렬 연산이 병렬화를 가능하게 하는 이유를 직접 이어서 설명할 수 있어야 한다.

전체 학습 과정을 돌아보면, 2단계에서 우리는 세 가지 근본적 질문에 답했다. 이미지의 공간 구조를 어떻게 효율적으로 처리하는가(CNN), 시간적 순서와 장기 의존성을 어떻게 포착하는가(LSTM/GRU), 그리고 순서와 관계를 동시에 병렬로 처리하는 최적의 방법은 무엇인가(Transformer). 3단계에서는 이 Transformer를 수십억 개의 파라미터로 키운 **대규모 언어 모델(LLM)**의 내부 구조를 분석하고, 이미 학습된 거대 모델을 특정 도메인에 효율적으로 적응시키는 파인튜닝 기법(LoRA, QLoRA)을 배울 것이다. Transformer를 지금 깊이 이해했다면, 그 여정은 이미 절반 이상 온 것이다.

← 단계 1단계 3