본 포스팅은 파이토치(PYTORCH) 한국어 튜토리얼을 참고하여 공부하고 정리한 글임을 밝힙니다.
torch.nn
: 신경망을 구성하는데 필요한 모든 구성 요소 제공nn.Module
의 하위 클래스(subclass)import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
torch.cuda
를 사용하여 GPU에서 모델 학습device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")
Out:
Using cuda device
nn.Module
의 하위클래스로 정의__init__
에서 신경망 계층 초기화nn.Module
을 상속받은 모든 클래스는 forward
메소드에 입력 데이터에 대한 연산 구현class NeuralNetwork(nn.Module):
def __init__(self):
super(NeuralNetwork, self).__init__()
self.flatten = nn.Flatten()
self.linear_relu_stack = nn.Sequential(
nn.Linear(28*28, 512),
nn.ReLU(),
nn.Linear(512, 512),
nn.ReLU(),
nn.Linear(512, 10),
)
def forward(self, x):
x = self.flatten(x)
logits = self.linear_relu_stack(x)
return logits
NeuralNetwork
의 인스턴스를 생성하고 이를 device
로 이동한 뒤, 구조(structure) 출력model = NeuralNetwork().to(device)
print(model)
Out:
NeuralNetwork(
(flatten): Flatten(start_dim=1, end_dim=-1)
(linear_relu_stack): Sequential(
(0): Linear(in_features=784, out_features=512, bias=True)
(1): ReLU()
(2): Linear(in_features=512, out_features=512, bias=True)
(3): ReLU()
(4): Linear(in_features=512, out_features=10, bias=True)
)
)
모델 사용을 위해 입력 데이터를 전달 ➡️ 백그라운드 연산들과 함께 모델의 forward
실행
model.forward()
직접 호출 ❌모델 입력 호출 시 각 분류(class)에 대한 raw 예측값이 있는 10-차원 텐서가 반환되고, 이를 nn.Softmax
모듈의 인스턴스를 통과시켜 예측 확률을 얻음
X = torch.rand(1, 28, 28, device=device) # 3차원 랜덤 텐서
logits = model(X)
pred_probab = nn.Softmax(dim=1)(logits)
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")
Out:
tensor([2], device='cuda:0')
input_image = torch.rand(3, 28, 28)
print(input_image.size())
Out:
torch.Size([3, 28, 28])
nn.Flatten
계층 초기화하여 각 28x28의 2D 이미지를 784 픽셀 값을 갖는 연속된 배열로 변환 (dim=0의 미니배치 차원 유지)flatten = nn.Flatten()
flat_image = flatten(input_image)
print(flat_image.size())
Out:
torch.Size([3, 784])
nn.Linear
는 가중치(weight)와 편향(bias)을 사용하여 입력에 선형변환(linear transformation)을 적용하는 모듈layer1 = nn.Linear(in_features=28*28, out_features=20)
hidden1 = layer1(flat_image)
print(hidden1.size())
Out:
torch.Size([3, 20])
= 비선형 활성화: 모델 입력과 출력 사이에 복잡한 관계(mapping) 만들어 선형 변환 후 적용되어 비선형성(nonlinearity) 도입
print(f"Before ReLU: {hidden1}\n\n")
hidden1 = nn.ReLU()(hidden1)
print(f"After ReLU: {hidden1}")
Out:
Before ReLU: tensor([[ 0.0049, 0.2853, 0.1693, -0.2735, -0.0701, 0.0343, -0.6752, -0.2479,
-0.0830, 0.0630, -0.4482, 0.1797, 0.2182, -0.0486, 0.4651, 0.1920,
-0.0647, 1.2193, -0.2621, -0.4581],
[-0.2920, 0.0676, 0.0520, 0.1891, -0.0580, -0.3115, -0.2957, -0.3636,
-0.1154, -0.1232, -0.4627, 0.2641, -0.0069, 0.0628, 0.3546, 0.5656,
-0.2520, 0.8359, -0.1429, -0.4318],
[-0.0435, -0.2776, 0.2480, 0.2754, -0.0964, 0.0246, -0.3559, 0.1068,
-0.3989, 0.0987, -0.4338, -0.0148, 0.1941, -0.1593, 0.2892, 0.5237,
-0.1785, 1.1747, -0.1691, -0.2251]], grad_fn=<AddmmBackward0>)
After ReLU: tensor([[0.0049, 0.2853, 0.1693, 0.0000, 0.0000, 0.0343, 0.0000, 0.0000, 0.0000,
0.0630, 0.0000, 0.1797, 0.2182, 0.0000, 0.4651, 0.1920, 0.0000, 1.2193,
0.0000, 0.0000],
[0.0000, 0.0676, 0.0520, 0.1891, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000,
0.0000, 0.0000, 0.2641, 0.0000, 0.0628, 0.3546, 0.5656, 0.0000, 0.8359,
0.0000, 0.0000],
[0.0000, 0.0000, 0.2480, 0.2754, 0.0000, 0.0246, 0.0000, 0.1068, 0.0000,
0.0987, 0.0000, 0.0000, 0.1941, 0.0000, 0.2892, 0.5237, 0.0000, 1.1747,
0.0000, 0.0000]], grad_fn=<ReluBackward0>)
seq_modules
와 같은 신경망 생성 가능seq_modules = nn.Sequential(
flatten,
layer1,
nn.ReLU(),
nn.Linear(20, 10)
)
input_image = torch.rand(3,28,28)
logits = seq_modules(input_image)
nn.Softmax
모듈에 전달될 ([-infty, infty] 범위의 원시 값(raw value)인) logtis를 반환dim
매개변수: 갑의 합이 1이 되는 차원 나타냄softmax = nn.Softmax(dim=1)
pred_probab = softmax(logits)
신경망 내부의 많은 게층들은 매개변수화(parameterize) 됨
nn.Module
을 상속하면 모델 객체 내부의 모든 필드들이 자동으로 추적되며, 모델의 parameters()
및 named_parameters()
메소드로 모든 매개변수 접근 가능
예제) 매개변수의 크기와 값 출력
print(f"Model structure: {model}\n\n")
for name, param in model.named_parameters():
print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")