-아래 부터는 FashionMNIST 데이터셋의 이미지를 분류하는 신경망을 구성해보자
-시작 코드
import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
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
flatten
은 numpy에서 제공하는 다차원 배열 공간으로 1차원으로 평탄화해주는 함수이다.
nn.Sequential
클래스는 nn.Linear
, nn.ReLU
(활성화 함수) 같은 모듈들을 인수로 받아서 순서대로 정렬해놓고 입력값이 들어오면 순서대로 모듈을 실행해서 결과값을 리턴한다.
nn.Linear
는 선형 변환을 수행하는 클래스로 28*28 크기 데이터를 인풋하면 512크기 데이터로 아웃풋 해줍니다.
nn.ReLU()
Rectified Linear Unit의 약자, 입력이 0 이하일 경우에는 0을 출력하지만 입력이 0을 넘어가면 입력값 그대로 출력함
-nn.Linear(512, 512)
바로 위 입력이 512여도 내부 연산으로 값이 바뀔수 있으므로 512,512를 해줌
NeuralNetwork
의 인스턴스를 생성하고 이를 device
로 이동한 뒤, 구조를 출력합니다.
코드
model = NeuralNetwork().to(device)
print(model)
결과
결과 값의 bias는 편향으로 모델이 실제 데이터와 얼마나 차이가 있는지를 나타내는 척도
-코드
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}")
모델을 사용하기 위해 입력 데이터를 전달합니다.
-이는 일부 백그라운드 연산들과 함께 모델의 forward
를 실행합니다.
*model.forward()
는 직접 호출하지 말것
모델에 입력을 전달하여 호출하면 2차원 텐서를 반환합니다.
2차원 텐서의 dim = 0은 각 분류(class)에 대한 원시(raw) 예측값 10개가, dim=1에는 각 출력의 개별 값들이 해당함
-원시 예측값을 nn.Softmax
모듈의 인스턴스에 통과시켜 예측 확률을 얻습니다.
Softmax Class
의 개수가 여러개 일 때 사용하는 것이 바로 Softmax function으로 어떤 Score값에 대해서 각 Class일 확률을 뽑아낼 수 있다.
ex) Score 한개에 대해서 Class1일 확률, Class2일 확률, ... ClassN일 확률이 나온다면 모두 다 깂이 0~1이어야 하고 모두 다 더했을 때, 당연히 1이 나와야함
argmax
: input tensor에 있는 모든 요소들 중에서 가장 큰 값을 가지는 공간의 인덱스 번호를 반환하는 함수
-FashionMINST 모델의 계층들
-28X28 크기의 이미지 3개로 구성된 미니배치를 가져와, 신경망을 통과할 때 어떤 일이 발생하는지
-코드
input_image = torch.rand(3,28,28)
print(input_image.size())
-결과
nn.Flatten
를 사용하여 28X28의 2D이미지를 784 픽셀 값을 갖는 연속된 배열로 변환합니다.(dim=0의 미니배치 차원은 유지됩니다.)flatten = nn.Flatten()
flat_image = flatten(input_image)
print(flat_image.size())
nn.Linear
선형 계층은 저장된 가중치와 편향을 사용하여 입력에 선형 변환을 적용하는 모듈입니다.
코드
layer1 = nn.Linear(in_features=28*28, out_features=20)
hidden1 = layer1(flat_image)
print(hidden1.size())
-코드
print(f"Before ReLU: {hidden1}\n\n")
hidden1 = nn.ReLU()(hidden1)
print(f"After ReLU: {hidden1}")
-결과
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)
logits
를 반환합니다. logits
는 모델의 각 분류(class)에 대한 예측 확률을 나타내도록 [0,1] 범위로 비례하여 조정(scale)됩니다.dim
매개변수는 값의 합이 1이 되는 차원을 나타탭니다.softmax = nn.Softmax(dim=1)
pred_probab = softmax(logits)
nn.Module
을 상속하면 모델 객체 내부의 모든 필드들이 자동으로 추적되며, 모델의 parameters()
및 named_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")
-결과