C.W.K.
Stream
Lesson 03 of 08 · published

Single Linear Layer 의 한계

~18 min · linearity, xor, depth

Level 0Curious
0 XP0/73 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Linear map 의 composition 도 linear

Layer 1 이 y = W₁ x + b₁ 이고 layer 2 가 z = W₂ y + b₂ 면, z = W₂ W₁ x + (W₂ b₁ + b₂) — 그 자체로 x 의 single linear function. Linear layer 10 개 쌓으면 1 개와 정확히 같은 expressive power 야. 그래서 pure linear depth 는 낭비야 — single matrix 가 계산할 수 있는 걸 10 배 parameter 로 계산한 셈.

해결은 non-linearity. 모든 linear layer 쌍 사이에 non-linear activation (ReLU, GELU, tanh) 끼우면 composition 이 더 이상 linear 가 아냐. 이제 depth 가 의미를 가져 — 각 layer 가 input space 를 region 으로 자르고 흥미롭게 합쳐.

원칙: Non-linearity 없는 linear 는 낭비된 depth. Modern intuition: layer 는 항상 같이 다니는 두 operation — linear projection 과 non-linear gate.

XOR canonical 예시

XOR 은 single linear classifier 가 못 푸는 가장 작은 함수. Input 2 개, output 1 개, unit square 의 4 모서리: (0,0)→0, (0,1)→1, (1,0)→1, (1,1)→0. 1 들을 한 쪽, 0 들을 다른 쪽에 두는 직선이 없어. ReLU unit 2 개의 hidden layer 추가하면 trivially 풀려.

이게 depth 에 대해 말해주는 것

Depth 는 magic 이 아냐. Activation 이 spendable 하게 만드는 representational complexity budget 이야. 초기 layer 가 만드는 representation (edge, character n-gram) 이 mid-level 개념 (texture, syllable) 으로 합쳐지고, 그게 high-level 개념 (object, word) 으로 합쳐져. Activation 빼면 composition 이 collapse.

Code

XOR: linear fails, ReLU passes·python
import torch, torch.nn as nn

X = torch.tensor([[0,0],[0,1],[1,0],[1,1]], dtype=torch.float32)
y = torch.tensor([0., 1., 1., 0.])

class LinearOnly(nn.Module):
    def __init__(self):
        super().__init__()
        self.l1 = nn.Linear(2, 4); self.l2 = nn.Linear(4, 1)
    def forward(self, x):
        return self.l2(self.l1(x)).squeeze(-1)

class WithReLU(nn.Module):
    def __init__(self):
        super().__init__()
        self.l1 = nn.Linear(2, 4); self.l2 = nn.Linear(4, 1)
    def forward(self, x):
        return self.l2(torch.relu(self.l1(x))).squeeze(-1)

def train(model, steps=2000, lr=0.1):
    opt = torch.optim.SGD(model.parameters(), lr=lr)
    for _ in range(steps):
        opt.zero_grad()
        loss = ((model(X) - y) ** 2).mean()
        loss.backward(); opt.step()
    return loss.item()

print("LinearOnly final loss:", train(LinearOnly()))   # ~0.25
print("WithReLU   final loss:", train(WithReLU()))     # ~0.0

External links

Exercise

XOR 을 linearly separable 하게 만드는 두 방법 적어 봐: (1) derived feature 추가, (2) ReLU 있는 hidden layer 추가. 둘 다 구현해. 각각이 non-linearity 가 어디 살아야 하는지에 대해 다른 점을 말해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.