딥러닝 파이토치 강좌, 합성곱 신경망

이번 강좌에서는 합성곱 신경망(Convolutional Neural Networks, CNN)에 대해 자세히 알아보고, 파이토치(PyTorch) 라이브러리를 이용하여 CNN을 구현하는 방법을 배워보겠습니다.
CNN은 주로 이미지 처리에 사용되며, 이미지 내에서 특징을 잘 추출하는 능력을 가지고 있습니다.

합성곱 신경망 개요

CNN은 이미지를 입력으로 받아들여, 여러 계층을 통해 이미지의 특징을 추출하고 분류하는 신경망입니다. CNN은 다음과 같은 주요 요소로 구성됩니다:

  • 합성곱 층(Convolutional Layer): 입력 이미지와 필터(커널)를 사용하여 특징 맵(feature map)을 생성합니다.
  • 활성화 함수(Activation Function): 비선형성을 추가하기 위해 ReLU(Rectified Linear Unit)와 같은 함수를 적용합니다.
  • 풀링 층(Pooling Layer): 특징 맵의 크기를 줄여 계산량을 감소시키고, 특징을 요약합니다.
  • 완전 연결 층(Fully Connected Layer): CNN의 마지막 부분에서 최종 분류를 수행합니다.

합성곱 신경망의 작동 원리

CNN의 작동 원리는 다음과 같은 단계로 이루어집니다:

  1. 이미지 데이터를 입력으로 받아들입니다.
  2. 합성곱 연산을 통해 이미지에서 특징을 추출합니다.
  3. 추출된 특징을 활성화 함수로 비선형 변환을 적용합니다.
  4. 필요시 풀링 연산을 통해 데이터를 축소합니다.
  5. 완전 연결 층을 통해 최종 출력(예: 클래스 확률)을 생성합니다.

파이토치로 합성곱 신경망 구현하기

이제 파이썬의 파이토치 라이브러리를 사용하여 간단한 CNN을 구현해보겠습니다. 먼저, 필요한 라이브러리를 설치하고 임포트해야 합니다.

pip install torch torchvision matplotlib

1. 라이브러리 임포트

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt

2. 데이터셋 로드

MNIST 데이터셋은 손글씨 숫자 데이터셋으로, CNN을 학습하는 데 널리 사용됩니다. 다음 코드를 통해 데이터를 다운로드하고 로드합니다.

# 데이터 변환 정의
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])

# 훈련 데이터 세트와 테스트 데이터 세트 다운로드
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)

testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)

3. CNN 모델 정의

이제 CNN 모델을 정의합니다. 간단한 CNN 구조를 사용하며, 두 개의 합성곱 층과 풀링 층, 그리고 두 개의 완전 연결 층으로 구성됩니다.

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=5)  # 첫 번째 합성곱 층
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  # 풀링 층
        self.conv2 = nn.Conv2d(32, 64, kernel_size=5)  # 두 번째 합성곱 층
        self.fc1 = nn.Linear(64 * 4 * 4, 128)  # 첫 번째 완전 연결 층
        self.fc2 = nn.Linear(128, 10)  # 두 번째 완전 연결 층 (10개 클래스)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))  # 첫 번째 합성곱 및 풀링
        x = self.pool(F.relu(self.conv2(x)))  # 두 번째 합성곱 및 풀링
        x = x.view(-1, 64 * 4 * 4)  # Flatten
        x = F.relu(self.fc1(x))  # 첫 번째 완전 연결
        x = self.fc2(x)  # 두 번째 완전 연결
        return x

4. 모델 학습

모델을 정의한 후, 손실 함수와 최적화 알고리즘을 설정하고 모델을 학습시킵니다. CrossEntropyLoss를 손실 함수로 사용하고, SGD(Stochastic Gradient Descent)를 최적화 알고리즘으로 사용합니다.

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model = CNN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 모델 학습
for epoch in range(10):  # 10 에폭 동안 학습
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()  # 기울기 초기화
        outputs = model(inputs)  # 모델의 출력 계산
        loss = criterion(outputs, labels)  # 손실 계산
        loss.backward()  # 기울기 계산
        optimizer.step()  # 매개변수 업데이트

        running_loss += loss.item()
    print(f'Epoch {epoch + 1}, Loss: {running_loss / len(trainloader)}')

print('Finished Training')

5. 모델 평가

학습이 완료된 후, 테스트 데이터를 사용하여 모델의 성능을 평가합니다.

correct = 0
total = 0

with torch.no_grad():
    for data in testloader:
        images, labels = data
        images, labels = images.to(device), labels.to(device)
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy of the network on the 10000 test images: {100 * correct / total}%')

6. 모델 저장 및 불러오기

학습된 모델을 저장하고 나중에 다시 불러올 수 있습니다. 아래 코드를 통해 모델을 저장하고 불러오는 방법을 보여줍니다.

# 모델 저장
torch.save(model.state_dict(), 'model.pth')

# 모델 불러오기
model = CNN()
model.load_state_dict(torch.load('model.pth'))

결론

이번 강좌에서는 합성곱 신경망(CNN)의 기본 개념과 파이토치 라이브러리를 이용하여 손글씨 숫자 인식 모델을 구현하는 방법을 살펴보았습니다.
CNN은 이미지 분류 및 다양한 컴퓨터 비전 분야에서 매우 중요한 역할을 하며, 기본적인 이해와 구현 방법을 아는 것이 중요합니다.
더 나아가 여러 가지 고급 방법론을 학습하여 딥러닝 모델을 더욱 발전시키는 데 도움이 되기를 바랍니다.