본문 바로가기
C.W.K.
Stream
Lesson 02 of 08 · published

선형, 편향, MLP

~12 min · linear, mlp, bias

Level 0텐서 탐구자
0 XP0/62 lessons0/13 achievements
0/120 XP to next level120 XP to go0% complete

nn.Linear: 가장 중요한 계층

nn.Linear(in_features, out_features)는 아핀 변환 y = x W^T + b를 적용해. 가중치 행렬의 모양은 (out_features, in_features)이고 편향은 (out_features,)야. Transformer의 FFN 블록, 분류기 헤드, 임베딩 투영처럼 대부분의 모델에서 매개변수의 약 90%가 이 계층에 들어 있어.

기본 초기화

nn.Linear는 기본적으로 가중치를 Kaiming 균등 분포로 초기화하고, 편향은 입력 팬인에 맞춰 범위를 조정한 균등 분포로 초기화해. 보통은 이 값을 바꿀 필요가 없지만 기본 초기화가 있다는 사실을 알아 두면 '왜 모델이 학습되지 않지?'라는 문제를 진단하기 쉬워져.

MLP의 전형적인 구조

다층 퍼셉트론은 Linear → 활성화 → Linear → 활성화 → ... → Linear 순서로 쌓아. 현대적인 변형은 정규화를 위해 드롭아웃을 넣거나, 안정성을 위해 LayerNorm을 넣거나, 매우 깊은 신경망에 건너뛰기 연결을 더해. 이 구조는 널리 쓰여. 모든 Transformer FFN 블록도 중간에 보통 GELU 같은 비선형성을 둔 2계층 MLP야.

Code

nn.Linear 기본·python
import torch
import torch.nn as nn

# 20 inputs → 10 outputs
linear = nn.Linear(20, 10)
print(linear.weight.shape)   # torch.Size([10, 20])  — out_features × in_features
print(linear.bias.shape)     # torch.Size([10])

x = torch.randn(32, 20)      # batch=32, features=20
y = linear(x)
print(y.shape)               # torch.Size([32, 10])

# Without bias (rare but useful in some Transformer variants)
linear_nb = nn.Linear(20, 10, bias=False)
print(linear_nb.bias)        # None
MLP 짓기: 기준 방식·python
import torch
import torch.nn as nn

class MLP(nn.Module):
    def __init__(self, in_dim, hidden, out_dim, p_drop=0.1):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(in_dim, hidden),
            nn.GELU(),                # transformer-flavor; ReLU works too
            nn.Dropout(p_drop),
            nn.Linear(hidden, hidden),
            nn.GELU(),
            nn.Dropout(p_drop),
            nn.Linear(hidden, out_dim),
        )

    def forward(self, x):
        return self.net(x)

model = MLP(784, 256, 10)
print(f"Params: {sum(p.numel() for p in model.parameters()):,}")
# Params: 269,322
사용자 정의 초기화: 기본값이 원하는 거 아닐 때·python
import torch
import torch.nn as nn
import math

class MLP(nn.Module):
    def __init__(self, in_dim, hidden, out_dim):
        super().__init__()
        self.fc1 = nn.Linear(in_dim, hidden)
        self.fc2 = nn.Linear(hidden, out_dim)
        self.act = nn.GELU()
        self._init_weights()

    def _init_weights(self):
        # Custom Xavier init — useful when you want a specific behavior
        for m in self.modules():
            if isinstance(m, nn.Linear):
                nn.init.xavier_normal_(m.weight)
                if m.bias is not None:
                    nn.init.zeros_(m.bias)

    def forward(self, x):
        return self.fc2(self.act(self.fc1(x)))

External links

Exercise

은닉 차원 목록을 인자로 받는 MLP 클래스를 만들어 봐. 예를 들어 MLP([784, 256, 128, 10])이 선형 계층 세 개짜리 신경망을 만들게 해. 계층은 nn.ModuleList에 보관하고, 무작위 배치를 넣어 출력 모양이 예상과 같은지 확인해.

Progress

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

댓글 0

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

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