ToTensor() & Noramlize()

SeongGyun Hong·2024년 12월 26일

1. 데이터 형식의 이해

원본 이미지 데이터

  • CIFAR10과 같은 데이터셋은 기본적으로 PIL(Python Imaging Library) Image 형식으로 저장
  • PIL Image는 [0, 255] 범위의 정수값으로 픽셀 표현
original_dataset = CIFAR10(root='./data', train=True, download=True, transform=None)
image, label = original_dataset[0]

print(f"Type: {type(image)}")  # <class 'PIL.Image.Image'>
print(f"Mode: {image.mode}")   # RGB
print(f"Size: {image.size}")   # (32, 32)

2. ToTensor() 변환

2.1 기능

  1. PIL Image/NumPy array를 PyTorch Tensor로 변환
  2. 이미지 채널 순서 변경: (H, W, C) → (C, H, W)
  3. 픽셀값 스케일 조정: [0, 255] → [0.0, 1.0]

2.2 코드 예시

tensor_transform = transforms.ToTensor()
tensor_dataset = CIFAR10(root='./data', train=True, transform=tensor_transform)
image_tensor, _ = tensor_dataset[0]

print(f"Tensor shape: {image_tensor.shape}")         # [3, 32, 32]
print(f"Value range: {image_tensor.min():.3f} ~ {image_tensor.max():.3f}")  # 0.000 ~ 1.000

3. Normalize() 변환

3.1 목적

  1. Internal Covariate Shift 감소
  2. 최적화 과정 개선
  3. 이상치 영향 감소
  4. 전이학습 용이성 증가

3.2 수학적 표현

normalized = (x - mean) / std

3.3 ImageNet 통계값을 사용하는 이유

  • mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
  • 전이학습 시 원본 학습 조건과의 일관성 유지
  • 검증된 통계값으로 안정적인 학습 보장

3.4 코드 예시와 효과

transforms_full = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], 
                       std=[0.229, 0.224, 0.225])
])

normalized_dataset = CIFAR10(root='./data', train=True, transform=transforms_full)
norm_image, _ = normalized_dataset[0]

print(f"Normalized range: {norm_image.min():.3f} ~ {norm_image.max():.3f}")

4. 정규화의 이점과 이론적 근거

4.1 학습 안정성 향상

  • 논문: "Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift" (Ioffe & Szegedy, 2015)
  • 각 레이어의 입력 분포 안정화
  • 학습률(learning rate)을 더 크게 설정 가능

4.2 최적화 효율성

  • 논문: "Understanding the difficulty of training deep feedforward neural networks" (Glorot & Bengio, 2010)
  • 그래디언트 스케일 균일화
  • 수렴 속도 향상
# 정규화 효과 시각화
unnormalized = torch.tensor([0, 127, 255], dtype=torch.float32)
normalized = (unnormalized - unnormalized.mean()) / unnormalized.std()

print("Unnormalized gradients:", torch.abs(unnormalized).mean())
print("Normalized gradients:", torch.abs(normalized).mean())

4.3 이상치 처리

  • 논문: "Deep Residual Learning for Image Recognition" (He et al., 2016)
  • 극단값의 영향 감소
  • 모델의 일반화 성능 향상

5. 실제 적용 시 고려사항

5.1 데이터셋별 정규화 통계

  • 데이터셋의 특성에 따라 평균/표준편차 값 조정 가능
  • ImageNet 통계값이 일반적으로 좋은 성능을 보임

5.2 검증/테스트 시 주의사항

  • 학습 데이터와 동일한 정규화 적용 필요
  • 정규화 파라미터는 학습 데이터에서만 계산

5.3 역변환 고려

# 정규화 역변환
denormalize = transforms.Normalize(
    mean=[-0.485/0.229, -0.456/0.224, -0.406/0.225],
    std=[1/0.229, 1/0.224, 1/0.225]
)
profile
헤매는 만큼 자기 땅이다.

0개의 댓글