FashionMNIST 데이터셋의 이미지들을 분류하는 신경망을 구성해보고자 한다.
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
학습을 위한 장치 얻기
device = (
"cuda"
if torch.cuda.is_available()
else "mps"
if torch.backends.mps.is_available()
else "cpu"
)
print(f"Using {device} device")
클래스 정의하기
- 신경망 모델을 nn.Module의 하위클래스로 정의하고, __init__ 에서 신경망 계층들을 초기화한다.
- nn.Module 을 상속받은 모든 클래스는 forward 메소드에 입력 데이터에 대한 연산들을 구현한다.
class NeuralNetwork(nn.Module):
def __init__(self):
super().__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 의 인스턴스(instance)를 생성하고 이를 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()를 직접 호출하면 안된다.
- 모델에 입력을 전달하여 호출하면 2차원 텐서를 반환한다.
- 2차원 텐서의 dim=0은 각 분류(class)에 대한 raw 예측값 10개가, dim=1에는 각 출력의 개별 값들이 해당한다.
- raw 예측값을 nn.Softmax 모듈의 인스턴스에 통과시켜 예측 확률을 얻는다.
X = torch.rand(1, 28, 28, device=device)
logits = model(X)
pred_probab = nn.Softmax(dim=1)(logits)
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")
모델 계층(Layer)
- 28 x 28 크기의 이미지 3개로 구성된 미니배치를 가져와, 신경망을 통과할 때 어떤 일이 발생하는지 알아보고자 한다.
input_image = torch.rand(3,28,28)
print(input_image.size())
Out:
torch.Size([3, 28, 28])
nn.Flatten
- nn.Flatten 계층을 초기화하여 각 28 x 28의 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])
nn.ReLU
- 비선형 활성화(activation)는 모델의 입-출력 사이에 복잡한 관계(mapping)를 만든다.
- 비선형 활성화는 선형 변환 후에 적용되어, 비선형성(nonlinearity)를 도입하고, 신경망이 다양한 현상을 학습할 수 있도록 돕는다.
- nn.ReLU 이외의 다른 비선형성 활성화 함수를 도입할 수도 있다.
print(f"Before ReLU: {hidden1}\n\n")
hidden1 = nn.ReLU()(hidden1)
print(f"After ReLU: {hidden1}")
Out:
Before ReLU: tensor([[-0.0251, -0.0921, 0.2688, 0.0091, 0.0885, 0.1725, -0.0981, -0.3290,
0.1264, -0.2142, 0.0291, 0.0834, 0.3299, 0.1260, 0.3924, -0.1626,
-0.3833, -0.3058, -0.0281, -0.1061],
[ 0.0722, -0.0170, 0.2973, -0.1068, -0.0644, 0.0034, -0.4394, -0.5947,
-0.2328, -0.3774, 0.3962, 0.0735, 0.5387, -0.0721, 0.0665, -0.0798,
0.0287, -0.0591, 0.1872, 0.0013],
[ 0.1833, -0.1361, 0.4334, -0.1708, 0.0088, 0.1179, 0.1551, -0.3565,
-0.1464, -0.4036, 0.2725, -0.0768, 0.3906, 0.2656, 0.3837, -0.0969,
-0.3594, -0.2714, 0.0758, -0.0043]], grad_fn=<AddmmBackward0>)
After ReLU: tensor([[0.0000, 0.0000, 0.2688, 0.0091, 0.0885, 0.1725, 0.0000, 0.0000, 0.1264,
0.0000, 0.0291, 0.0834, 0.3299, 0.1260, 0.3924, 0.0000, 0.0000, 0.0000,
0.0000, 0.0000],
[0.0722, 0.0000, 0.2973, 0.0000, 0.0000, 0.0034, 0.0000, 0.0000, 0.0000,
0.0000, 0.3962, 0.0735, 0.5387, 0.0000, 0.0665, 0.0000, 0.0287, 0.0000,
0.1872, 0.0013],
[0.1833, 0.0000, 0.4334, 0.0000, 0.0088, 0.1179, 0.1551, 0.0000, 0.0000,
0.0000, 0.2725, 0.0000, 0.3906, 0.2656, 0.3837, 0.0000, 0.0000, 0.0000,
0.0758, 0.0000]], grad_fn=<ReluBackward0>)
nn.Sequential
- 순서를 갖는 모듈의 컨테이너로, 데이터는 정의된 것과 같은 순서로 모든 모듈들을 통해 전달된다.
- 순차 컨테이너(sequential container)를 사용하여 아래의 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
- 신경망의 마지막 선형 계층은 nn.Softmax 모듈에 전달될 ([-infty, \infty] 범위의 원시 값(raw value)인) logits 를 반환한다.
- logits 는 모델의 각 분류(class)에 대한 예측 확률을 나타내도록 [0, 1] 범위로 비례하여 조정(scale) 된다.
- dim 매개변수는 값의 합이 1이 되는 차원을 나타낸다.
softmax = nn.Softmax(dim=1)
pred_probab = softmax(logits)
모델 매개변수
- nn.Module 을 상속하면 모델 객체 내부의 모든 필드들이 자동으로 추적(track)되며, 모델의 parameters() 및 named_parameters() 메소드로 모든 매개변수에 접근할 수 있게 된다.
- 아래의 코드에서는 각 매개변수들을 순회하며(iterate), 매개변수의 크기와 값을 출력한다.
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")
Out:
Model structure: 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)
)
)
Layer: linear_relu_stack.0.weight | Size: torch.Size([512, 784]) | Values : tensor([[ 0.0053, 0.0255, 0.0002, ..., 0.0179, 0.0238, 0.0260],
[ 0.0300, 0.0331, 0.0168, ..., -0.0267, -0.0049, 0.0160]],
grad_fn=<SliceBackward0>)
Layer: linear_relu_stack.0.bias | Size: torch.Size([512]) | Values : tensor([-0.0345, -0.0263], grad_fn=<SliceBackward0>)
Layer: linear_relu_stack.2.weight | Size: torch.Size([512, 512]) | Values : tensor([[ 0.0078, -0.0284, -0.0307, ..., 0.0328, 0.0039, 0.0119],
[ 0.0252, -0.0136, -0.0009, ..., 0.0348, -0.0379, 0.0106]],
grad_fn=<SliceBackward0>)
Layer: linear_relu_stack.2.bias | Size: torch.Size([512]) | Values : tensor([-0.0032, 0.0172], grad_fn=<SliceBackward0>)
Layer: linear_relu_stack.4.weight | Size: torch.Size([10, 512]) | Values : tensor([[-0.0141, 0.0060, -0.0353, ..., -0.0312, 0.0311, -0.0356],
[ 0.0357, -0.0232, -0.0379, ..., 0.0124, -0.0329, -0.0377]],
grad_fn=<SliceBackward0>)
Layer: linear_relu_stack.4.bias | Size: torch.Size([10]) | Values : tensor([0.0032, 0.0246], grad_fn=<SliceBackward0>)
https://tutorials.pytorch.kr/beginner/basics/buildmodel_tutorial.html
신경망 모델 구성하기
파이토치(PyTorch) 기본 익히기|| 빠른 시작|| 텐서(Tensor)|| Dataset과 Dataloader|| 변형(Transform)|| 신경망 모델 구성하기|| Autograd|| 최적화(Optimization)|| 모델 저장하고 불러오기 신경망은 데이터에 대한 연
tutorials.pytorch.kr
'Deep Learning & Machine Learning > PyTorch' 카테고리의 다른 글
[PyTorch] tutorial, 6.최적화(Optimization) (0) | 2024.05.19 |
---|---|
[PyTorch] tutorial, 5.Autograd (0) | 2024.05.19 |
[PyTorch] tutorial, 3.변형(Transform) (0) | 2024.05.19 |
[PyTorch] tutorial, 2.Dataset과 DataLoader (0) | 2024.05.19 |
[PyTorch] tutorial, 1.텐서(TENSOR) (0) | 2024.05.19 |