Step 4 딥러닝으로 비선형 문제 해결

다층 퍼셉트론(MLP)과 PyTorch 초기화 설정

1. 해결의 시점: 1986년, "다시 봄이 오다"

1986년, 데이브 루멜하트(David Rumelhart)제프리 힌튼(Geoffrey Hinton), 로널드 윌리엄스(Ronald Williams)가 공동 발표한 논문 "Learning representations by back-propagating errors"가 그 기점입니다.

❄️ 인공지능의 겨울 (AI Winter)

1969년, 마빈 민스키와 시모어 페퍼트는 "Perceptrons"라는 책에서 단층 퍼셉트론이 XOR 문제를 풀 수 없다는 것을 수학적으로 증명했습니다. 이 발견은 당시 인공지능 연구에 엄청난 타격을 주었습니다.

"인공신경망은 죽었다"는 분위기가 퍼졌고, 연구 자금은 끊겼으며, 많은 연구자들이 이 분야를 떠났습니다. 이 시기를 "AI의 첫 번째 겨울(First AI Winter)"이라고 부릅니다.

💡 왜 이렇게 오래 걸렸을까?

사실 역전파의 기본 아이디어는 1970년대에 이미 존재했습니다. 그런데 왜 1986년까지 기다려야 했을까요?

루멜하트, 힌튼, 윌리엄스의 1986년 논문은 역전파를 명확하고 실용적으로 설명했고, 실험 결과도 함께 제시하여 "이게 진짜 된다!"는 것을 증명했습니다. 이것이 AI의 봄을 다시 가져온 결정적 계기였습니다.

2. 은닉층(Hidden Layer)의 마법

단층 퍼셉트론은 직선 하나만 그을 수 있었지만, 은닉층을 추가하면 공간을 왜곡시키거나 직선을 여러 개 긋는 효과를 냅니다. 데이터가 은닉층을 통과하면서, 직선 하나로는 절대 나눌 수 없던 XOR 데이터의 좌표 평면이 선형적으로 분리 가능한 새로운 형태로 변환됩니다.

🧠 퍼셉트론의 진화: 단층 → 다층

단층 퍼셉트론(SLP, Single Layer Perceptron):
• 은닉층이 1개
• 단순한 비선형 분류 가능
• XOR 같은 복잡한 문제는 해결 가능하지만 한계 있음

다층 퍼셉트론(MLP, Multi-Layer Perceptron):
• 은닉층이 2개 이상
• 복잡한 비선형 패턴 학습 가능 ✅
• 은닉층이 많을수록 더욱 추상적이고 복잡한 특징 학습 가능
• 딥러닝(Deep Learning)의 기초

💡 참고: 은닉층이 아예 없는 구조(입력층 → 출력층)는 퍼셉트론(Perceptron)이라 부르며, 선형 분류만 가능합니다.

📊 신경망 구조 비교

단층 퍼셉트론 (SLP)

x₁ 입력층 x₂ h₁ h₂ 은닉층 (1개) y 출력층 ✅ XOR 가능

은닉층 1개 → 비선형 분류 가능

다층 퍼셉트론 (MLP)

x₁ 입력층 x₂ h₁ h₂ 은닉층1 h₃ h₄ h₅ 은닉층2 y 출력층 ✅ 복잡한 패턴 학습

은닉층 2개 이상 → 딥러닝의 시작

🎨 은닉층의 역할

은닉층은 데이터를 새로운 표현 공간(representation space)으로 변환합니다:

💡 핵심: 은닉층이 없으면 아무리 층을 쌓아도 결국 하나의 직선밖에 못 그립니다. 은닉층과 활성화 함수가 있어야 곡선 형태의 복잡한 결정 경계를 만들 수 있습니다!

⚡ 활성화 함수: 신경망의 "마법 재료"

활성화 함수가 왜 필요할까요? 간단한 예시로 이해해봅시다.

활성화 함수가 없다면?
입력층 → 은닉층 → 출력층 과정이 모두 선형 연산(곱하기와 더하기)만 한다면...
아무리 층을 많이 쌓아도 결국 하나의 거대한 선형 연산이 됩니다!

수학적으로: $y = W_3(W_2(W_1x))$ 는 결국 $y = Wx$ 형태로 단순화됩니다.
→ 복잡한 층들이 의미가 없어집니다! 😱

활성화 함수를 넣으면?
각 층마다 비선형 변환을 해주면, 층을 쌓을수록 정말로 복잡한 패턴을 표현할 수 있게 됩니다.

Sigmoid 함수

x σ(x) 1 0

출력: 0~1 사이
부드러운 S자 곡선

ReLU 함수

x ReLU(x) x 0

출력: max(0, x)
음수는 0, 양수는 그대로

🎯 직관적 이해:
선형 함수: 직선 도로 - 아무리 이어붙여도 직선
비선형 함수: 구불구불한 산길 - 이어붙이면 복잡한 경로 생성

신경망이 복잡한 패턴을 학습하려면 "구불구불함"이 필요합니다. 활성화 함수가 바로 이 "구불구불함"을 만들어줍니다!

대표적인 활성화 함수:

3. MLP는 어떻게 학습하는가?

MLP가 구조적으로 복잡한 문제를 풀 수 있다는 것을 알았습니다. 그런데 중요한 질문이 남았습니다: "이 수많은 가중치를 어떻게 최적의 값으로 설정하는가?"

바로 여기서 경사하강법(Gradient Descent)역전파(Backpropagation)가 등장합니다. 이 두 개념은 MLP 학습의 양대 축입니다.

🎯 경사하강법 (Gradient Descent): "어디로 갈 것인가?"

경사하강법은 오차를 최소화하는 학습의 전략입니다.

시작 최적점 (최소 오차) 가중치 (Weight) 오차 (Loss)

경사를 따라 한 걸음씩 내려가면서 오차를 최소화합니다

비유: 안개 낀 산에서 가장 낮은 곳을 찾아가는 방법
1️⃣ 현재 위치에서 경사(기울기)를 측정합니다
2️⃣ 경사가 내려가는 방향으로 한 걸음 움직입니다
3️⃣ 다시 경사를 측정하고, 또 내려갑니다
4️⃣ 더 이상 내려갈 곳이 없을 때까지 반복합니다

신경망에서 "산"은 오차 함수(Loss Function)이고, "현재 위치"는 가중치들의 조합입니다. 경사하강법은 오차가 최소가 되는 가중치 조합을 찾아갑니다.

🔄 역전파 (Backpropagation): "경사를 어떻게 구할 것인가?"

역전파는 경사하강법에 필요한 기울기를 계산하는 알고리즘입니다.

입력층 은닉층 출력층 오차 순전파 역전파 순전파로 오차 계산 → 역전파로 기울기 계산

문제: MLP는 층이 여러 개라 각 가중치가 최종 오차에 얼마나 영향을 미치는지 알기 어렵습니다.

해결: 역전파는 출력층부터 거꾸로 올라가면서, 연쇄 법칙(Chain Rule)을 이용해 모든 가중치의 기울기를 효율적으로 계산합니다.

💡 비유: 최종 성적(오차)이 나빴을 때, "어느 과목 점수(가중치) 때문인가?"를 역순으로 추적하는 것과 같습니다. 기말고사 → 중간고사 → 과제 점수 순으로 거슬러 올라가며 각 요소가 얼마나 기여했는지 파악합니다.

🔗 경사하강법 + 역전파 = MLP 학습

1. 순전파(Forward Pass): 입력 → 은닉층 → 출력 → 오차 계산
2. 역전파(Backward Pass): 각 가중치의 기울기 계산
3. 경사하강법(Gradient Descent): 기울기를 이용해 가중치 업데이트
4. 반복: 1~3 과정을 수천 번 반복하여 오차 최소화

결론: 경사하강법은 "전략"이고, 역전파는 그 전략을 실행하기 위한 "계산 도구"입니다. 이 둘이 합쳐져야 MLP가 실제로 학습할 수 있습니다!

4. 역전파(Backpropagation) 알고리즘 상세

앞서 역전파가 "기울기를 계산하는 도구"라고 했습니다. 이제 그 원리를 좀 더 깊이 들여다봅시다. 역전파는 결과값의 오차를 뒤에서부터 앞으로 거꾸로 전파하며 각 가중치를 최적화합니다. 수학적으로는 미분의 연쇄 법칙(Chain Rule)을 활용합니다.

💡 쉬운 비유: 산에서 길을 잃었을 때

여러분이 안개 낀 산속에서 가장 낮은 곳(최소 오차)을 찾아가야 한다고 상상해보세요. 경사(기울기)를 따라 한 걸음씩 내려가면 되는데, 문제는 지금 서 있는 곳의 경사가 어디서 비롯되었는지 알아야 한다는 것입니다.

역전파는 마치 "이 경사는 어느 방향에서 왔나?"를 거슬러 올라가며 추적하는 것과 같습니다. 출력층의 오차부터 시작해서, 은닉층, 입력층 순으로 거꾸로 가면서 각 가중치가 얼마나 잘못된 방향으로 기여했는지를 계산합니다.

① 수학적 원리: 연쇄 법칙 (Chain Rule)

가중치($w$)가 오차($E$)에 미치는 영향(기울기)을 구하기 위해 출력층부터 입력층까지 미분을 곱해나갑니다.

$$\frac{\partial E}{\partial w} = \frac{\partial E}{\partial \text{output}} \times \frac{\partial \text{output}}{\partial \text{net}} \times \frac{\partial \text{net}}{\partial w}$$

쉽게 풀어보면:
∂E/∂output: "출력값이 조금 바뀌면 오차가 얼마나 바뀌나?"
∂output/∂net: "활성화 함수 입력이 바뀌면 출력이 얼마나 바뀌나?"
∂net/∂w: "가중치가 바뀌면 활성화 함수 입력이 얼마나 바뀌나?"

이 세 개를 곱하면 → "가중치가 조금 바뀌면 최종 오차가 얼마나 바뀌나?"를 알 수 있습니다!

🔍 단계별 역전파 과정

Step 1. 순전파 (Forward Pass)
→ 입력 데이터를 넣어서 예측값을 계산하고 오차를 구합니다.

Step 2. 출력층 기울기 계산
→ "이 오차는 출력층 가중치 때문에 얼마나 생긴 거야?"

Step 3. 은닉층 기울기 계산
→ "그 출력층 오차는 또 은닉층 가중치 때문에 얼마나 생긴 거야?"
→ 연쇄 법칙으로 앞 층의 기울기 × 현재 층의 기울기를 계산

Step 4. 입력층까지 반복
→ 모든 층의 가중치가 오차에 기여한 정도를 파악 완료!

5. 미분: 역전파의 핵심 도구

역전파에서 가장 중요한 수학적 도구는 바로 미분(Derivative)입니다. 미분은 "어떤 값이 조금 변할 때, 다른 값이 얼마나 변하는가?"를 측정하는 도구입니다.

📐 미분의 직관적 이해

자동차가 달리고 있을 때, 속도는 시간에 대한 위치의 미분입니다. "1초가 지나면 내 위치가 얼마나 변하는가?" → 이것이 속도죠.

신경망에서도 똑같습니다:
• "가중치를 0.01만큼 올리면 오차가 얼마나 변하는가?" → 이것이 기울기(gradient)
• 기울기가 크면 → 이 가중치가 오차에 큰 영향을 미친다
• 기울기가 작으면 → 이 가중치는 오차에 별 영향이 없다

🧮 간단한 미분 예시

함수 $f(x) = x^2$가 있다고 가정해봅시다.

$$\frac{df}{dx} = 2x$$
x=1 기울기=2 x=2 기울기=4 y = x² x y

x가 커질수록 접선의 기울기(미분값)도 커집니다

의미:
• $x = 1$일 때 기울기는 $2 \times 1 = 2$
→ x를 0.1 증가시키면 $f(x)$는 약 $2 \times 0.1 = 0.2$ 증가
• $x = 2$일 때 기울기는 $2 \times 2 = 4$
→ x를 0.1 증가시키면 $f(x)$는 약 $4 \times 0.1 = 0.4$ 증가
• $x = 3$일 때 기울기는 $2 \times 3 = 6$
→ x를 0.1 증가시키면 $f(x)$는 약 $6 \times 0.1 = 0.6$ 증가

🎯 신경망에 적용하면:
만약 가중치가 3이고, 기울기가 6이라면?
→ "가중치를 조금만 줄이면 오차가 빠르게 줄어들겠구나!"
→ 경사하강법: 가중치를 6 × 학습률만큼 빼줍니다.

만약 가중치가 0.1이고, 기울기가 0.001이라면?
→ "이 가중치는 오차에 거의 영향이 없네?"
→ 조금만 조정하거나, 다른 가중치에 집중합니다.

신경망은 수백, 수천 개의 가중치에 대해 이런 미분을 동시에 계산하여 모든 가중치를 최적의 방향으로 조금씩 움직입니다.

🔗 연쇄 법칙(Chain Rule): 여러 함수를 이어붙였을 때

신경망은 여러 층이 이어져 있습니다. 입력 → 은닉층1 → 은닉층2 → 출력
각 층마다 함수가 적용되므로, 함수의 합성(composition)이 일어납니다.

예시로 이해하기:
"온도가 올라가면 → 아이스크림 판매가 늘어나고 → 이익이 증가한다"

질문: "온도가 1도 올라가면 이익이 얼마나 증가하나?"

답: (온도→판매 변화율) × (판매→이익 변화율)
= "온도 1도당 판매 10개" × "판매 1개당 이익 500원"
= 온도 1도당 이익 5,000원 증가

이것이 바로 연쇄 법칙입니다! 중간 단계들의 변화율을 곱하면 전체 변화율을 알 수 있습니다.
신경망에서는 이걸 사용해서 "입력층 가중치가 최종 오차에 얼마나 영향을 주는가"를 계산합니다.

② 가중치 업데이트 (Weight Update)

역전파로 구한 기울기($\frac{\partial E}{\partial w}$)를 사용하여, 오차가 줄어드는 방향으로 가중치를 수정합니다.

$$w_{new} = w_{old} - \eta \times \frac{\partial E}{\partial w}$$

공식 해석:
• $w_{old}$: 현재 가중치 (지금 서 있는 위치)
• $\frac{\partial E}{\partial w}$: 기울기 (경사가 가파른 방향과 정도)
• $\eta$ (학습률): 한 번에 얼마나 움직일지 (보폭 크기)
• 마이너스(-) 부호: 오차가 줄어드는 방향으로 이동

예를 들어 기울기가 +5이고 학습률이 0.1이면, 가중치를 -0.5만큼 조정합니다.

💡 Tip: 학습률($\eta$)이 너무 크면 최적점을 지나쳐버리고, 너무 작으면 학습이 너무 느려집니다!

6. 옵티마이저(Optimizer): 학습의 운전사

역전파로 기울기를 구했다면, 이제 그 기울기를 어떻게 활용해서 가중치를 업데이트할지 결정해야 합니다. 이 역할을 하는 것이 바로 옵티마이저(Optimizer)입니다.

🚗 옵티마이저의 역할

옵티마이저는 산을 내려가는 운전 방식을 결정합니다:

💻 PyTorch에서 옵티마이저 사용하기

PyTorch에서는 옵티마이저를 다음과 같이 정의하고 사용합니다:

import torch.optim as optim

# 1. 옵티마이저 정의
optimizer = optim.Adam(model.parameters(), lr=0.01)

# 2. 학습 루프
for epoch in range(1000):
    # 순전파
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    
    # 기울기 초기화 (중요!)
    optimizer.zero_grad()
    
    # 역전파 (기울기 계산)
    loss.backward()
    
    # 가중치 업데이트
    optimizer.step()

핵심 3단계:
optimizer.zero_grad(): 이전 기울기를 지웁니다 (누적 방지)
loss.backward(): 역전파로 기울기를 계산합니다
optimizer.step(): 계산된 기울기로 가중치를 업데이트합니다

7. PyTorch 모델 설정 (Technical Spec)

🛠️ nn.Linear 초기화 방식

💡 왜 랜덤으로 초기화할까?
모든 가중치를 0으로 시작하면 모든 뉴런이 똑같이 행동합니다. 이러면 아무리 학습해도 다양한 특징을 배울 수 없어요.

왜 이 범위를 사용할까?
너무 크면 → 활성화 함수가 포화되어 학습 안됨 😵
너무 작으면 → 신호가 너무 약해져서 사라짐 😴
$\frac{1}{\sqrt{n}}$ 범위는 이 둘의 균형을 맞춰줍니다! ⚖️

🎛️ 학습률(Learning Rate): 가장 중요한 하이퍼파라미터

학습률은 신경망 학습에서 가장 중요한 설정값입니다. 한 번에 얼마나 크게 가중치를 변경할지 결정하죠.

학습률 너무 큼

진동하며 발산!

학습률 적당함

안정적 수렴! ✅

학습률 너무 작음

너무 느림! 🐢

🎯 적절한 학습률 찾기:
시작: 보통 0.001 (1e-3)부터 시작
너무 크면: Loss가 발산하거나 NaN 발생 → 줄이기
너무 작으면: 학습이 너무 느림 → 키우기
팁: 학습이 잘 안되면 학습률을 10배 줄이거나 10배 늘려보세요!

🚀 Optimizer 기본 학습률 (Default LR)

Optimizer 기본 lr 특징
SGD1e-3가장 기본적, 느리지만 안정적임
Adam1e-3속도와 방향을 모두 고려 (가장 대중적)
RMSprop1e-2기울기 제곱의 이동평균 사용

8. XOR 문제 해결 결과

PyTorch를 이용해 MLP를 학습시킨 결과입니다. 곡선 형태의 결정 경계가 만들어져 XOR 문제를 완벽하게 해결합니다.