# pytorch pre-loaded 데이터 로딩 코드
import torch
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda
ds = datasets.FashionMNIST(
root="data",
train=True,
download=True,
transform=ToTensor(),
target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
)
transform=ToTensor()
- PIL Image/Numpy를 PyTorch의 기본 단위인 FloatTensor로 바꾸면서 특성스케일링인 정규화(값의 범위를 0.0 ~ 1.0으로) 진행
- 차원 변경 : (높이, 너비, 채널) -> (채널, 높이, 너비)
target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
- 해당 코드에서는 원-핫 인코딩 수행
- y : 정답 라벨
- torch.zeros(10, dtype=torch.float) : (1차원)길이가 10인 float 0으로 채워진 벡터 생성
- .scatter_(0, torch.tensor(y), value=1) : 0번째 차원(1차원) 기준으로, 앞서 torch.zeros에서 만든 벡터의 y번째 인덱스에 value 1를 할당
신경망을 구성하는데 필요한 모든 구성 요소 제공 (레이어, 활성화 함수, 손실함수 등)
예시 코드
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")
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
model = NeuralNetwork().to(device)
print(model)
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}")
__init____init__에서 선언한 레이어 사용# 1. 신경망 모델 정의 (nn.Module을 상속받아야 함)
class NeuralNetwork(nn.Module):
def __init__(self):
super().__init__() # 부모 클래스(nn.Module) 초기화 (필수!)
# 평탄화 계층: 28x28(2차원) 이미지를 784(1차원) 벡터로 쫙 펴주는 역할
self.flatten = nn.Flatten()
# 순차 컨테이너: 내부에 정의된 층들을 순서대로 통과시킴
self.linear_relu_stack = nn.Sequential(
nn.Linear(28*28, 512), # 입력층 -> 은닉층1 (입력 784개, 출력 512개)
nn.ReLU(), # 활성화 함수 (비선형성 추가)
nn.Linear(512, 512), # 은닉층1 -> 은닉층2 (입력 512개, 출력 512개)
nn.ReLU(), # 활성화 함수
nn.Linear(512, 10), # 은닉층2 -> 출력층 (출력 10개 = 클래스 개수)
)
# 순전파(Forward): 데이터가 모델을 통과하는 경로 정의
def forward(self, x):
x = self.flatten(x) # 1. 이미지를 1차원으로 폄
logits = self.linear_relu_stack(x) # 2. 신경망 층을 통과 (결과값은 Logits)
return logits # 3. Logits 반환 (아직 확률 아님)
# 2. 모델 인스턴스 생성 및 장치(CPU/GPU)로 이동
# device 변수는 앞서 정의되어 있어야 함 (예: "cuda" or "cpu")
model = NeuralNetwork().to(device)
print(model) # 모델 구조 출력 확인
# 3. 모델 테스트 (추론)
# 더미(가짜) 입력 데이터 생성 (배치크기 1, 28x28 이미지)
X = torch.rand(1, 28, 28, device=device)
# 모델에 입력 데이터 넣고 예측 실행
# 주의: model.forward(X)가 아니라 model(X)로 호출해야 함!
logits = model(X)
# 예측 결과(Logits)를 확률(Probability)로 변환
# dim=1은 클래스 차원을 기준으로 합이 1이 되게 하라는 뜻
pred_probab = nn.Softmax(dim=1)(logits)
# 가장 높은 확률을 가진 클래스의 인덱스(번호) 추출
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")
준비된 데이터와 모델을 활용하여 매개변수 최적화하여 모델 학습, 검증, 테스트 진행
더 자세한 설명 : https://tutorials.pytorch.kr/beginner/basics/optimization_tutorial.html
예시 코드
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor
# 학습 데이터 로드
training_data = datasets.FashionMNIST(
root="data",
train=True,
download=True,
transform=ToTensor()
)
# 테스트 데이터 로드
test_data = datasets.FashionMNIST(
root="data",
train=False,
download=True,
transform=ToTensor()
)
train_dataloader = DataLoader(training_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)
device = "cuda" if torch.cuda.is_available() else "cpu"
# 모델 구성
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
model = NeuralNetwork().to(device)
# 실제 학습 실행 (데이터, 모델, 손실함수, 옵티마이저를 매개변수로)
def train_loop(dataloader, model, loss_fn, optimizer):
size = len(dataloader.dataset)
model.train()
for batch, (X, y) in enumerate(dataloader):
X, y = X.to(device), y.to(device)
pred = model(X)
loss = loss_fn(pred, y)
loss.backward()
optimizer.step()
optimizer.zero_grad()
if batch % 100 == 0:
loss, current = loss.item(), batch * len(X)
print(f"loss: {loss:>7f} [{current:>5d}/{size:>5d}]")
# 테스트 실행 (데이터, 모델, 손실함수)
def test_loop(dataloader, model, loss_fn):
model.eval()
size = len(dataloader.dataset)
num_batches = len(dataloader)
test_loss, correct = 0, 0
with torch.no_grad():
for X, y in dataloader:
X, y = X.to(device), y.to(device)
pred = model(X)
test_loss += loss_fn(pred, y).item()
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= num_batches
correct /= size
print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
learning_rate = 1e-3
batch_size = 64
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
epochs = 10
for t in range(epochs):
print(f"Epoch {t+1}\n-------------------------------")
train_loop(train_dataloader, model, loss_fn, optimizer)
test_loop(test_dataloader, model, loss_fn)
print("Done!")
참고