PyTorch
PyTorch 이미지 분류(Image Classification) 예제 (MNIST, CIFAR-10)
PyExplorer
2025. 4. 21. 14:05
728x90
PyTorch 이미지 분류(Image Classification) 예제 (MNIST, CIFAR-10)
1. 서론
이미지 분류(Image Classification)는 딥러닝에서 가장 기본적인 문제 중 하나로, 입력된 이미지를 특정 클래스에 할당하는 작업입니다. 이번 글에서는 PyTorch를 사용하여 MNIST와 CIFAR-10 데이터셋을 활용한 이미지 분류 모델을 구현하는 방법을 소개합니다.
2. 데이터셋 소개
2.1 MNIST 데이터셋
MNIST는 손으로 쓴 숫자(0~9)로 구성된 28x28 픽셀의 흑백 이미지 데이터셋입니다. 총 60,000개의 학습 데이터와 10,000개의 테스트 데이터로 구성되어 있으며, 딥러닝 모델의 성능 평가에 자주 사용됩니다.
2.2 CIFAR-10 데이터셋
CIFAR-10은 10개의 일반적인 객체 클래스(비행기, 자동차, 새, 고양이, 사슴, 개, 개구리, 말, 배, 트럭)로 구성된 컬러 이미지 데이터셋입니다. 각 이미지는 32x32 픽셀 크기이며, 50,000개의 학습 데이터와 10,000개의 테스트 데이터로 구성되어 있습니다.
3. PyTorch를 활용한 이미지 분류 모델 구현
3.1 라이브러리 및 데이터 로딩
먼저 필요한 라이브러리를 불러오고, 데이터셋을 로드합니다.
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
# 하이퍼파라미터 설정
batch_size = 64
learning_rate = 0.001
epochs = 10
# 데이터 전처리 변환 정의
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)) # MNIST의 경우 흑백 정규화 적용
])
# MNIST 데이터 로드
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
3.2 CNN 모델 정의
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(64 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.5)
def forward(self, x):
x = self.relu(self.conv1(x))
x = self.pool(self.relu(self.conv2(x)))
x = x.view(x.size(0), -1)
x = self.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x)
return x
3.3 모델 학습
# 모델, 손실 함수, 옵티마이저 정의
model = CNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
def train(model, train_loader, criterion, optimizer, epochs):
model.train()
for epoch in range(epochs):
running_loss = 0.0
for images, labels in train_loader:
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch [{epoch+1}/{epochs}], Loss: {running_loss/len(train_loader):.4f}')
train(model, train_loader, criterion, optimizer, epochs)
3.4 모델 평가
def evaluate(model, test_loader):
model.eval()
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
outputs = model(images)
_, predicted = torch.max(outputs, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy: {100 * correct / total:.2f}%')
evaluate(model, test_loader)
4. CIFAR-10을 위한 모델 수정
CIFAR-10은 컬러 이미지이므로 in_channels=3
으로 변경하고, Fully Connected Layer 크기를 조정해야 합니다.
transform_cifar10 = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
train_dataset_cifar10 = torchvision.datasets.CIFAR10(root='./data', train=True, transform=transform_cifar10, download=True)
test_dataset_cifar10 = torchvision.datasets.CIFAR10(root='./data', train=False, transform=transform_cifar10, download=True)
train_loader_cifar10 = torch.utils.data.DataLoader(train_dataset_cifar10, batch_size=batch_size, shuffle=True)
test_loader_cifar10 = torch.utils.data.DataLoader(test_dataset_cifar10, batch_size=batch_size, shuffle=False)
class CIFAR10_CNN(nn.Module):
def __init__(self):
super(CIFAR10_CNN, self).__init__()
self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=1)
self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(64 * 8 * 8, 128)
self.fc2 = nn.Linear(128, 10)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.5)
def forward(self, x):
x = self.relu(self.conv1(x))
x = self.pool(self.relu(self.conv2(x)))
x = x.view(x.size(0), -1)
x = self.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x)
return x
5. 결론
이번 글에서는 MNIST와 CIFAR-10을 활용하여 이미지 분류 모델을 구현하는 방법을 살펴보았습니다. 기본적인 CNN 모델을 적용하는 방법을 익히고, 데이터셋의 특성에 맞게 모델을 수정하는 방법을 실습하였습니다.
728x90