정규화

흑백 이미지와 컬러 이미지를 **따로 정규화**하려면, 두 데이터셋의 평균(mean)과 표준편차(std)를 **각각 계산**하고, 학습 시 별도로 처리해야 합니다. 이를 통해 각 이미지 유형에 적합한 정규화를 적용할 수 있습니다.


1. 흑백과 컬러 이미지를 따로 정규화하는 이유

  1. 채널 수의 차이:
  2. 흑백 이미지는 단일 채널, 컬러 이미지는 3채널(R, G, B)이므로 정규화 기준이 다릅니다.

  3. 분포 차이:

  4. 흑백과 컬러 데이터는 픽셀 값 분포가 다를 수 있으므로, 각 데이터셋에 맞는 정규화를 적용해야 학습 안정성이 높아집니다.

  5. 정규화 공식:

  6. 정규화는 다음 공식에 따라 이루어집니다:

    $$ x' = \frac{x - \text{mean}}{\text{std}} $$

  7. 이때, meanstd는 각 데이터셋에 따라 별도로 계산됩니다.


2. 구현 방법

2.1. 흑백 데이터와 컬러 데이터 로드

데이터셋을 흑백과 컬러로 분리하여 로드합니다.

from torchvision import datasets, transforms
from torch.utils.data import DataLoader
from PIL import Image

# 흑백 이미지 전처리
transform_grayscale = transforms.Compose([
    transforms.Resize((224, 224)),   # 크기 조정
    transforms.ToTensor()            # 텐서 변환
])

# 컬러 이미지 전처리
transform_rgb = transforms.Compose([
    transforms.Resize((224, 224)),   # 크기 조정
    transforms.ToTensor()            # 텐서 변환
])

# 흑백과 컬러 이미지 데이터셋 로드
dataset_grayscale = datasets.ImageFolder(root='./data_grayscale', transform=transform_grayscale)
dataset_rgb = datasets.ImageFolder(root='./data_rgb', transform=transform_rgb)

loader_grayscale = DataLoader(dataset_grayscale, batch_size=32, shuffle=False)
loader_rgb = DataLoader(dataset_rgb, batch_size=32, shuffle=False)

2.2. 평균(mean)과 표준편차(std) 계산

흑백 데이터셋

def calculate_mean_std(loader):
    mean = 0.0
    std = 0.0
    total_samples = 0

    for images, _ in loader:
        batch_samples = images.size(0)  # 배치 크기
        images = images.view(batch_samples, -1)  # (N, H*W)

        # 배치별 평균 및 표준편차 계산
        mean += images.mean() * batch_samples
        std += images.std() * batch_samples
        total_samples += batch_samples

    mean /= total_samples
    std /= total_samples

    return mean.item(), std.item()

# 흑백 데이터 평균 및 표준편차 계산
mean_grayscale, std_grayscale = calculate_mean_std(loader_grayscale)
print("Grayscale Mean:", mean_grayscale)
print("Grayscale Std:", std_grayscale)

컬러 데이터셋

def calculate_mean_std_rgb(loader):
    mean = torch.zeros(3)  # RGB 채널별 평균 초기화
    std = torch.zeros(3)   # RGB 채널별 표준편차 초기화
    total_samples = 0

    for images, _ in loader:
        batch_samples = images.size(0)  # 배치 크기
        images = images.view(batch_samples, images.size(1), -1)  # (N, C, H*W)

        # 채널별 평균 및 표준편차 계산
        mean += images.mean(dim=[0, 2]) * batch_samples
        std += images.std(dim=[0, 2]) * batch_samples
        total_samples += batch_samples

    mean /= total_samples
    std /= total_samples

    return mean.tolist(), std.tolist()

# 컬러 데이터 평균 및 표준편차 계산
mean_rgb, std_rgb = calculate_mean_std_rgb(loader_rgb)
print("RGB Mean:", mean_rgb)
print("RGB Std:", std_rgb)

2.3. 정규화 전처리

계산된 meanstd를 기반으로 흑백과 컬러 데이터를 별도로 정규화합니다.

흑백 이미지 전처리

transform_grayscale_with_normalize = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[mean_grayscale], std=[std_grayscale])  # 정규화
])

dataset_grayscale_normalized = datasets.ImageFolder(
    root='./data_grayscale', transform=transform_grayscale_with_normalize
)

컬러 이미지 전처리

transform_rgb_with_normalize = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=mean_rgb, std=std_rgb)  # 정규화
])

dataset_rgb_normalized = datasets.ImageFolder(
    root='./data_rgb', transform=transform_rgb_with_normalize
)

3. 흑백과 컬러를 병합하여 학습

흑백과 컬러 이미지를 **동일한 모델**에 입력하려면 두 데이터셋을 병합하거나 같은 데이터 로더로 사용할 수 있습니다.

데이터 병합:

from torch.utils.data import ConcatDataset

# 병합된 데이터셋 생성
merged_dataset = ConcatDataset([dataset_grayscale_normalized, dataset_rgb_normalized])

# 병합된 데이터 로더
merged_loader = DataLoader(merged_dataset, batch_size=32, shuffle=True)

4. 요약

  1. 흑백과 컬러 데이터를 분리하여 로드:
  2. 흑백: 단일 채널(Grayscale) 정규화.
  3. 컬러: 3채널(RGB) 정규화.

  4. 각 데이터셋에서 평균(mean)과 표준편차(std)를 별도로 계산:

  5. 흑백: 단일 값.
  6. 컬러: 3채널 값.

  7. 정규화를 각 데이터셋에 적용:

  8. Normalize(mean=[...], std=[...])로 데이터셋 별 정규화.

  9. 병합하여 학습:

  10. 흑백과 컬러 데이터를 병합하거나, 모델에서 데이터를 다르게 처리하도록 설계 가능.

이 방법을 통해 흑백 이미지와 컬러 이미지를 적절히 정규화하고 모델에 입력할 수 있습니다.