LeNet-5 구현 및 손글씨 숫자 분류 실습

LeNet-5은 Yann LeCun이 1998년에 제안한 초기 합성곱 신경망으로, 특히 MNIST와 같은 저해상도 이미지 분류 작업에서 뛰어난 성능을 보였습니다. 이 모델은 현재 딥러닝 아키텍처의 기초를 형성하며, 층별 특징 추출과 공간 차원 축소 전략을 명확히 보여줍니다.

구조적 구성 요소

LeNet-5는 다음과 같은 순차적 레이어로 구성됩니다:

  • 입력: 1채널 흑백 이미지 (28×28)
  • 첫 번째 합성곱층: 6개 필터 (5×5), 패딩 2 → 출력 크기: 28×28
  • 비선형 활성화: Sigmoid 함수
  • 평균 풀링층: 2×2 윈도우, 스트라이드 2 → 크기 반감
  • 두 번째 합성곱층: 16개 필터 (5×5), 패딩 없음 → 출력 크기: 10×10
  • 다시 Sigmoid + 평균 풀링 (2×2, 스트라이드 2) → 5×5 피처 맵
  • 전방향 연결층: 16×5×5 = 400 입력 → 120 유닛 → Sigmoid
  • 중간 은닉층: 120 → 84 → Sigmoid
  • 출력층: 84 → 10 (10개 클래스에 대한 로짓)

PyTorch 기반 구현

다음 코드는 위 구조를 nn.Sequential을 사용해 간결하게 정의합니다:

import torch
import torch.nn as nn

def build_lenet5():
    return nn.Sequential(
        nn.Conv2d(in_channels=1, out_channels=6, kernel_size=5, padding=2),
        nn.Sigmoid(),
        nn.AvgPool2d(kernel_size=2, stride=2),
        nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5),
        nn.Sigmoid(),
        nn.AvgPool2d(kernel_size=2, stride=2),
        nn.Flatten(),
        nn.Linear(in_features=16 * 5 * 5, out_features=120),
        nn.Sigmoid(),
        nn.Linear(in_features=120, out_features=84),
        nn.Sigmoid(),
        nn.Linear(in_features=84, out_features=10)
    )

# 입력 테스트
sample_input = torch.randn(1, 1, 28, 28)
model = build_lenet5()
for idx, layer in enumerate(model):
    sample_input = layer(sample_input)
    print(f"Layer {idx+1} ({layer.__class__.__name__}): {sample_input.shape}")

학습 파이프라인

모델을 실제 데이터셋(MNIST 또는 Fashion-MNIST)에 적용하기 위해 다음 구성 요소가 필요합니다:

  • 데이터 로더: 배치 크기 256으로 로드
  • 장치 설정: GPU 자동 감지 및 이동
  • 가중치 초기화: Xavier 균등 분포로 선형/합성곱 계층 초기화
  • 옵티마이저: SGD, 학습률 0.9
  • 손실 함수: CrossEntropyLoss
  • 평가 메트릭: 정확도 누적 계산 (Accumulator 기반)

훈련 루프 개요

각 에폭에서는 다음 단계를 수행합니다:

  1. 배치 단위로 데이터를 GPU로 이동
  2. 순전파 → 손실 계산 → 역전파 → 가중치 업데이트
  3. 누적된 손실 및 정확도를 기준으로 훈련 지표 갱신
  4. 에폭 종료 시 테스트 세트에서 정확도 평가
  5. 학습 진행 상황 시각화 (animator)

실행 예시:

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = build_lenet5().to(device)
train_loader, test_loader = load_mnist_data(batch_size=256)

trainer = ModelTrainer(model, train_loader, test_loader, device)
trainer.train(num_epochs=10, learning_rate=0.9)

여기서 ModelTrainer는 학습 로직을 캡슐화한 사용자 정의 클래스로, d2l 라이브러리 없이도 동일한 기능을 제공할 수 있습니다.

태그: PyTorch convolutional-neural-network handwritten-digit-recognition

8월 8일 18:12에 게시됨