Skip to content

pypypypy5/mini-class

Repository files navigation

CIFAR-10 이미지 분류 프로젝트

PyTorch로 처음부터 만드는 CNN 이미지 분류기 학습 프로젝트입니다.


📁 프로젝트 구조

mini-class/
├── data/                    # 데이터 저장 공간
│   ├── raw/                 # 원본 데이터 (CIFAR-10 자동 다운로드됨)
│   ├── processed/           # 전처리된 데이터
│   └── train/val/test/      # 데이터 분할
│
├── src/                     # 소스 코드
│   ├── data/
│   │   └── dataset.py       # 🔨 [구현 필요] 데이터 로딩 및 전처리
│   ├── models/
│   │   └── cnn.py           # 🔨 [구현 필요] CNN 모델 정의
│   ├── train.py             # 🔨 [구현 필요] 학습/평가 함수
│   └── main.py              # 전체 파이프라인 실행
│
└── outputs/                 # 실험 결과 저장
    ├── checkpoints/         # 모델 체크포인트
    ├── logs/                # 학습 로그
    └── best_models/         # 최고 성능 모델

🎯 학습 목표

  1. PyTorch 기본 사용법 익히기

    • 데이터 로딩 (Dataset, DataLoader)
    • 모델 정의 (nn.Module)
    • 학습 루프 작성
  2. 딥러닝 파이프라인 이해하기

    • 데이터 전처리 → 모델 정의 → 학습 → 평가 흐름 체험
  3. 실험과 튜닝 경험하기

    • 하이퍼파라미터 변경이 성능에 미치는 영향 관찰

🚀 시작하기

⚠️ 중요: Python 요구사항

PyTorch는 공식 Python만 지원합니다!

  • ✅ Python 3.8-3.12 (python.org, conda, Windows Store)
  • ❌ MSYS2/MinGW Python (지원 안 됨!)

Python 확인:

python -c "import platform; print(platform.python_compiler())"
# 'MSC' = ✅ OK  |  'GCC' = ❌ 안 됨

자세한 내용: INSTALL.md


1. 환경 설정

방법 1: 자동 설치 (권장 ⭐)

자동 설치 스크립트가 Python 호환성을 체크하고 GPU를 감지하여 최적의 PyTorch 버전을 설치합니다.

Windows (PowerShell):

# 가상환경 활성화
.venv\Scripts\activate

# 자동 설치
.\setup.ps1

Linux/Mac:

# 가상환경 활성화
source .venv/bin/activate

# 자동 설치
python setup.py

방법 2: 수동 설치

1) PyTorch 설치 (환경에 맞게 선택)

# CPU only
pip install torch torchvision torchaudio

# NVIDIA GPU (CUDA 11.8)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

# NVIDIA GPU (CUDA 12.1)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

# AMD GPU (ROCm)
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm5.6

2) 기타 의존성 설치

pip install -r requirements.txt

GPU 지원 확인

python -c "import torch; print(f'CUDA: {torch.cuda.is_available()}'); print(f'MPS: {torch.backends.mps.is_available() if hasattr(torch.backends, \"mps\") else False}')"

2. 구현 순서 (단계별로 진행!)


🔄 완성된 프로그램 파이프라인 상세 설명

프로그램이 완성되면 다음과 같은 순서로 동작합니다:

파이프라인 실행 흐름

[main.py 실행]
      ↓
① 하이퍼파라미터 설정 & GPU/CPU 선택
      ↓
② 데이터 로딩 (dataset.py)
   - CIFAR-10 다운로드 (최초 1회)
   - Transform 적용 (정규화, 증강)
   - DataLoader 생성 (배치 단위로 묶기)
      ↓
③ 모델 생성 (cnn.py)
   - SimpleCNN 인스턴스 생성
   - GPU/CPU로 모델 이동
      ↓
④ 손실함수 & 옵티마이저 초기화
   - CrossEntropyLoss
   - SGD or Adam
      ↓
⑤ 학습 루프 (에폭 반복)
   │
   ├─→ [학습 단계] train_one_epoch()
   │    - 전체 학습 데이터를 배치 단위로 순회
   │    - 각 배치마다:
   │      1. 데이터 → GPU/CPU 이동
   │      2. 그래디언트 초기화
   │      3. Forward: 모델 예측
   │      4. Loss 계산
   │      5. Backward: 그래디언트 계산
   │      6. 파라미터 업데이트
   │    - 평균 loss와 정확도 반환
   │
   ├─→ [평가 단계] evaluate()
   │    - 전체 테스트 데이터를 배치 단위로 순회
   │    - 그래디언트 계산 없이 Forward만 수행
   │    - Loss와 정확도 계산
   │    - 평균 loss와 정확도 반환
   │
   ├─→ [결과 출력]
   │    - 학습 loss/정확도
   │    - 테스트 loss/정확도
   │
   └─→ [모델 저장]
        - 최고 성능 모델 → outputs/best_models/
        - 정기 체크포인트 → outputs/checkpoints/
      ↓
⑥ 학습 완료 & 최종 결과 출력

각 구성 요소의 역할

1. main.py - 지휘자(Conductor)

전체 파이프라인을 조율하는 엔트리 포인트입니다.

  • 하이퍼파라미터 설정
  • 모든 모듈 임포트 및 초기화
  • 학습 루프 실행
  • 결과 저장 관리

2. data/dataset.py - 데이터 공급자(Data Provider)

모델에게 데이터를 공급하는 역할입니다.

  • CIFAR-10 다운로드 및 로딩
  • 이미지 전처리 (정규화, 증강)
  • 배치 단위로 데이터 제공

왜 분리? 데이터 처리 로직을 독립적으로 관리하면, 다른 데이터셋으로 교체하거나 전처리 방법을 변경할 때 이 파일만 수정하면 됩니다.

3. models/cnn.py - 모델 정의자(Model Architect)

신경망 구조를 정의합니다.

  • CNN 레이어 구성
  • Forward pass 정의
  • 모델 아키텍처

왜 분리? 모델 구조를 독립적으로 관리하면, 여러 모델을 실험하거나 아키텍처를 변경할 때 다른 코드에 영향을 주지 않습니다.

4. train.py - 학습 관리자(Training Manager)

학습과 평가의 실제 로직을 담당합니다.

  • 학습 루프 (forward → backward → update)
  • 평가 루프 (forward → metrics)
  • 체크포인트 저장/로드

왜 분리? 학습 로직을 재사용 가능하게 만들어, 다른 프로젝트에서도 동일한 학습 함수를 사용할 수 있습니다.

데이터 흐름 예시 (1 배치)

[DataLoader]
    ↓
images: (64, 3, 32, 32)  ← 64개 이미지, 3채널, 32x32 크기
labels: (64,)             ← 64개의 정답 레이블
    ↓
[GPU 이동]
    ↓
[Model Forward]
    ↓
outputs: (64, 10)         ← 64개 샘플의 10개 클래스 점수
    ↓
[Loss 계산]
loss = CrossEntropyLoss(outputs, labels)
    ↓
[Backward]
각 파라미터의 그래디언트 계산
    ↓
[Optimizer Step]
파라미터 업데이트: weight = weight - lr * gradient

전체 학습 과정 시각화

에폭 1:
  배치1 → Forward → Loss → Backward → Update
  배치2 → Forward → Loss → Backward → Update
  ...
  배치782 (50000/64) → Forward → Loss → Backward → Update
  [평균 loss, 정확도 계산]
  [테스트 데이터로 평가]

에폭 2:
  (반복...)

...

에폭 10:
  (반복...)

[최고 성능 모델 저장]

📝 단계별 구현 가이드

1단계: 데이터 로딩 (src/data/dataset.py)

🎯 목표

  • CIFAR-10 데이터셋을 다운로드하고 전처리
  • DataLoader로 배치 단위로 묶기

🔍 구현할 내용

get_cifar10_transforms() 함수

# 찾아볼 키워드:
# - transforms.Compose
# - transforms.ToTensor()
# - transforms.Normalize()
# - CIFAR-10 정규화 값: mean=[0.4914, 0.4822, 0.4465], std=[0.2470, 0.2435, 0.2616]

질문해보세요:

  • Q1. 왜 이미지를 정규화(Normalize)해야 하나요?
  • Q2. 학습용과 테스트용 transform을 다르게 설정하는 이유는?
  • Q3. Data Augmentation(데이터 증강)이란? 언제 적용할까?

load_cifar10() 함수

# 찾아볼 키워드:
# - datasets.CIFAR10
# - DataLoader
# - shuffle의 역할
# - batch_size가 성능에 미치는 영향

✅ 테스트 방법

cd src
python data/dataset.py
# 출력 예시:
# 배치 이미지 shape: torch.Size([64, 3, 32, 32])
# 전체 학습 데이터 개수: 50000

2단계: CNN 모델 설계 (src/models/cnn.py)

🎯 목표

  • 간단한 CNN 모델을 직접 설계하고 구현

🔍 구현할 내용

SimpleCNN 클래스

입력/출력 정보:

  • 입력: (batch_size, 3, 32, 32) - CIFAR-10 이미지
  • 출력: (batch_size, 10) - 10개 클래스 점수

추천 구조 (자유롭게 변경 가능!):

입력 (3x32x32)
    ↓
Conv2d → ReLU → MaxPool2d    # 첫 번째 합성곱 블록
    ↓
Conv2d → ReLU → MaxPool2d    # 두 번째 합성곱 블록
    ↓
Flatten                      # (batch, C, H, W) → (batch, C*H*W)
    ↓
Linear → ReLU                # Fully Connected 1
    ↓
Linear                       # Fully Connected 2 (출력)
    ↓
출력 (10)

찾아볼 키워드:

  • nn.Conv2d - 파라미터: in_channels, out_channels, kernel_size, padding
  • nn.MaxPool2d - 파라미터: kernel_size, stride
  • nn.Linear - 파라미터: in_features, out_features
  • F.relu - 활성화 함수
  • x.view() - Flatten 처리

설계 시 고민해볼 점:

  1. Conv 레이어의 필터 개수를 얼마로? (16, 32, 64, 128...)
  2. Pooling을 몇 번 적용할까? (적용 시마다 크기가 절반으로)
  3. FC 레이어의 노드 수는?

💡 크기 계산 팁

32x32 이미지 → MaxPool(2,2) → 16x16
16x16 이미지 → MaxPool(2,2) → 8x8
8x8 이미지 → MaxPool(2,2) → 4x4

예: Conv로 32채널까지 증가 + 8x8 크기
    → Flatten 후 크기 = 32 * 8 * 8 = 2048

✅ 테스트 방법

cd src
python models/cnn.py
# 모델 구조와 파라미터 개수 확인

3단계: 학습/평가 함수 (src/train.py)

🎯 목표

  • 학습 루프와 평가 루프 구현

🔍 구현할 내용

train_one_epoch() 함수 - 1 에폭 학습

# 의사코드:
model.train()  # 학습 모드 설정

for 배치 in train_loader:
    1. 데이터를 device(GPU/CPU) 이동
    2. optimizer.zero_grad()           # 이전 그래디언트 초기화
    3. outputs = model(images)         # Forward pass
    4. loss = criterion(outputs, labels)  # 손실 계산
    5. loss.backward()                 # Backward pass (그래디언트 계산)
    6. optimizer.step()                # 파라미터 업데이트
    7. 정확도 계산 (예측값과 실제 레이블 비교)

return 평균_loss, 정확도

찾아볼 키워드:

  • .to(device) - GPU/CPU로 데이터 이동
  • optimizer.zero_grad() - 왜 필요할까?
  • .backward() - 역전파
  • torch.max(outputs, 1) - 예측 클래스 구하기

evaluate() 함수 - 평가

# 의사코드:
model.eval()  # 평가 모드 (Dropout, BatchNorm 동작 변경)

with torch.no_grad():  # 그래디언트 계산 비활성화 (메모리 절약, 속도 향상)
    for 배치 in test_loader:
        1. 데이터를 device로 이동
        2. outputs = model(images)  # Forward만 수행
        3. loss = criterion(outputs, labels)
        4. 정확도 계산

return 평균_loss, 정확도

질문해보세요:

  • Q1. model.train()model.eval()의 차이는?
  • Q2. torch.no_grad()는 왜 사용하나요?
  • Q3. 정확도는 어떻게 계산하나요?

4단계: 전체 파이프라인 실행 (src/main.py)

🎯 목표

  • 모든 모듈을 연결하여 학습 진행

🔍 구현할 내용

  1. 주석 해제 및 코드 완성

    • 각 TODO 부분의 주석을 해제하며 진행
    • 옵티마이저 선택 (SGD vs Adam)
  2. 하이퍼파라미터 설정

    BATCH_SIZE = 64          # 배치 크기
    LEARNING_RATE = 0.001    # 학습률
    NUM_EPOCHS = 10          # 에폭 수
  3. 학습 실행

    cd src
    python main.py

✅ 예상 출력

Device: cuda  (또는 cpu)

Epoch [1/10]
Train - Loss: 1.8234, Acc: 32.45%
Test  - Loss: 1.6521, Acc: 38.12%

Epoch [2/10]
Train - Loss: 1.5234, Acc: 43.21%
...

🧪 실험 & 개선 아이디어

필수 실험

  1. 데이터 증강 효과 확인

    # dataset.py의 train_transform에 추가
    transforms.RandomHorizontalFlip(),
    transforms.RandomCrop(32, padding=4),
    • 정확도가 얼마나 향상되나요?
  2. 옵티마이저 비교

    • SGD vs Adam 성능 차이는?
    • Learning rate를 변경하면?
  3. 모델 구조 변경

    • Conv 레이어를 더 깊게 쌓으면?
    • 필터 개수를 늘리면?

심화 실험

  • Dropout 추가 (nn.Dropout)
  • Batch Normalization 추가 (nn.BatchNorm2d)
  • Learning Rate Scheduler 사용
  • 학습 곡선 그래프 그리기 (matplotlib)

📚 학습 체크리스트

  • 1단계: 데이터 로딩 구현 완료
  • 2단계: CNN 모델 설계 완료
  • 3단계: 학습/평가 함수 구현 완료
  • 4단계: 전체 학습 성공 (정확도 50% 이상 목표!)
  • 실험: 데이터 증강 적용 및 성능 비교
  • 실험: 하이퍼파라미터 튜닝

🔗 참고 자료

PyTorch 공식 문서

개념 학습

  • 정규화(Normalization): 학습 안정화 및 수렴 속도 향상
  • Data Augmentation: 과적합 방지, 일반화 성능 향상
  • Optimizer: SGD(안정적), Adam(빠른 수렴)
  • Learning Rate: 너무 크면 발산, 너무 작으면 느림

❓ 막힐 때 질문 가이드

데이터 관련

  • "CIFAR-10 정규화 값은 어떻게 구하나요?"
  • "DataLoader의 shuffle은 왜 필요한가요?"
  • "배치 크기를 어떻게 정해야 하나요?"

모델 관련

  • "Conv2d의 padding은 왜 사용하나요?"
  • "Flatten 후 크기가 안 맞아요! (크기 계산 방법)"
  • "활성화 함수를 왜 써야 하나요?"

학습 관련

  • "loss.backward()가 하는 일은?"
  • "optimizer.zero_grad()를 빼먹으면?"
  • "학습이 너무 느려요! (GPU 사용, batch_size 조정)"

💡 팁

  1. 한 번에 다 하지 마세요

    • 1단계씩 완성하고 테스트
    • 에러가 나면 그 단계에서 해결
  2. print 디버깅 활용

    print(f"입력 shape: {images.shape}")
    print(f"출력 shape: {outputs.shape}")
  3. 작은 실험부터

    • NUM_EPOCHS=2로 먼저 돌려보기
    • 학습이 되는지 확인 후 에폭 늘리기
  4. 모르는 건 검색하고 질문하세요!

    • PyTorch 공식 문서가 가장 정확
    • 에러 메시지를 구글에 검색

🎓 완성 후 다음 단계

  1. ResNet 같은 유명 모델 구현해보기
  2. 전이 학습(Transfer Learning) 시도
  3. 다른 데이터셋 적용 (MNIST, Fashion-MNIST 등)
  4. PyTorch Lightning으로 코드 리팩토링

Good Luck! 🚀

About

cnn classification toy project

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors