[실습] 제4장 모델 개발
PyTorch의 모든 신경망 모델은 torch.nn.Module을 상속한다. 반드시 구현해야 하는 두 요소는 계층을 정의하는 __init__()과 계산 과정을 정의하는 forward()다.
4.1 nn.Module
nn.Module은 PyTorch에서 신경망의 계층, 파라미터, 순전파 연산을 정의하고 관리하는 모든 모델의 기본 클래스다.
import torch.nn as nn
class MLP(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__() # or super(MLP, self).__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(p=0.3)
self.fc2 = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.dropout(x)
return self.fc2(x)
model = MLP(784, 256, 10)
print(model) # 모델 구조를 읽기 쉬운 형식으로 출력
중요:
forward()를 직접 호출하지 말고 항상model(x)를 호출한다. 이 방식은forward()를 실행하면서 등록된 후크도 함께 실행한다.__init__안에서super().__init__()를 반드시 호출해야 하며, 호출하지 않으면 매개변수가 등록되지 않는다.
4.2 nn.Sequential
nn.Sequential은 여러 신경망 계층을 순서대로 연결하고 입력을 각 계층에 차례로 전달하는 PyTorch 컨테이너다.
# 옵션 1: positional
model = nn.Sequential(
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10),
)
# 옵션 2: named (OrderedDict)
from collections import OrderedDict
model = nn.Sequential(OrderedDict([
('fc1', nn.Linear(784, 256)),
('relu', nn.ReLU()),
('fc2', nn.Linear(256, 10)),
]))
# 접근 레이어
print(model[0]) # Linear(in=784, out=256)
4.3 일반적인 계층 유형
| 계층 | 설명 |
|---|---|
nn.Linear(in, out) |
완전 연결 밀집 계층이다. 계산식은$y=xW^T+b$다. |
nn.Conv2d(in_ch, out_ch, k) |
2차원 합성곱 계층이다.k는 커널 크기이며 스트라이드와 패딩도 설정할 수 있다. |
nn.MaxPool2d(k) |
2차원 최대 풀링을 수행한다. |
nn.BatchNorm1d/2d(features) |
배치 정규화를 수행한다. 활성화 함수 전이나 후에 적용할 수 있다. |
nn.LayerNorm(shape) |
계층 정규화를 수행한다. 트랜스포머에 주로 사용한다. |
nn.Dropout(p) |
학습할 때만 뉴런의 비율p만큼을 무작위로 0으로 만든다. |
nn.Embedding(num, dim) |
정수 인덱스를 밀집 벡터에 대응시키는 조회표다. |
nn.LSTM(in, hidden) |
장단기 메모리 계층이다.(output, (h_n, c_n))을 반환한다. |
nn.MultiheadAttention(d, h) |
다중 헤드 자기·교차 어텐션을 수행하며 트랜스포머의 구성 요소로 사용한다. |
4.4 가중치 초기화
import torch.nn.init as init
# 모든 선형 계층에 사용자 정의 초기화 방식을 적용함
def init_weights(m):
if isinstance(m, nn.Linear):
init.xavier_uniform_(m.weight) # good for tanh/sigmoid
init.zeros_(m.bias)
elif isinstance(m, nn.Conv2d):
init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
model.apply(init_weights) # 모든 하위 모듈에 재귀적으로 적용함
| 초기화 함수 | 사용 시점 |
|---|---|
init.xavier_uniform_/normal_ |
tanh 또는 sigmoid 활성화 함수에 사용하며 분산을 안정적으로 유지한다. |
init.kaiming_uniform_/normal_ |
ReLU에 사용하는 He 초기화다. PyTorchConv2d의 기본 방식이다. |
init.zeros_/ones_/constant_ |
고정값으로 설정하며 주로 편향을 초기화할 때 사용한다. |
init.orthogonal_ |
직교 가중치 행렬을 만들며 순환 신경망에 적합하다. |
댓글남기기