신경망의 기본 구현 및 학습 프로세스

데이터 로드 및 전처리

이미지 데이터는 지정된 폴더 구조에 따라 구성되어야 하며, 각 클래스별로 폴더를 분리하여 저장합니다.

data_dir = "./data"
transform = {
    'train': transforms.Compose([
        transforms.Resize((64, 64)),
        transforms.ToTensor()
    ]),
    'valid': transforms.Compose([
        transforms.Resize((64, 64)),
        transforms.ToTensor()
    ])
}

dataset = {
    phase: datasets.ImageFolder(root=os.path.join(data_dir, phase), transform=transform[phase])
    for phase in ['train', 'valid']
}

dataloader = {
    phase: torch.utils.data.DataLoader(
        dataset=dataset[phase],
        batch_size=16,
        shuffle=True
    )
    for phase in ['train', 'valid']
}

모델 설계

기본적인 순환 신경망 아키텍처를 사용하여 이미지 분류 모델을 정의합니다. 컨볼루션 블록과 이후의 풀링, 선형 계층으로 구성됩니다.

class ImageClassifier(torch.nn.Module):
    def __init__(self):
        super(ImageClassifier, self).__init__()
        self.features = torch.nn.Sequential(
            torch.nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1),
            torch.nn.ReLU(),
            torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=2, stride=2),

            torch.nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
            torch.nn.ReLU(),
            torch.nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(kernel_size=2, stride=2)
        )

        self.classifier = torch.nn.Sequential(
            torch.nn.Linear(16 * 16 * 256, 512),
            torch.nn.ReLU(),
            torch.nn.Dropout(p=0.5),
            torch.nn.Linear(512, 7)
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(-1, 16 * 16 * 256)
        x = self.classifier(x)
        return x

model = ImageClassifier()

학습 설정

손실 함수와 최적화 알고리즘을 설정하고, 장치(가능한 경우 GPU)를 지정합니다.

loss_fn = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.0005)

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

num_epochs = 10

모델 학습

각 에포크마다 훈련 및 검증 단계를 반복하며 손실과 정확도를 기록합니다.

for epoch in range(num_epochs):
    print(f"Epoch {epoch+1}/{num_epochs}")
    print("-" * 10)

    for phase in ['train', 'valid']:
        model.train(phase == 'train')

        running_loss = 0.0
        running_corrects = 0

        for batch_idx, (inputs, labels) in enumerate(dataloader[phase], 1):
            inputs, labels = inputs.to(device), labels.to(device)

            optimizer.zero_grad()

            outputs = model(inputs)
            _, preds = torch.max(outputs, 1)
            loss = loss_fn(outputs, labels)

            if phase == 'train':
                loss.backward()
                optimizer.step()

            running_loss += loss.item()
            running_corrects += torch.sum(preds == labels.data)

            if batch_idx % 500 == 0 and phase == 'train':
                print(f"Batch {batch_idx}, Train Loss: {running_loss / batch_idx:.4f}, "
                       f"Train Acc: {100 * running_corrects / (4 * batch_idx):.4f}%")

        epoch_loss = running_loss * 4 / len(dataset[phase])
        epoch_acc = 100 * running_corrects / len(dataset[phase])

        print(f"{phase.capitalize()} Loss: {epoch_loss:.4f}, Accuracy: {epoch_acc:.4f}%")

모델 저장 및 불러오기

학습 완료 후 모델 상태를 파일로 저장하고, 필요 시 다시 불러옵니다.

torch.save(model, 'trained_model.pth')
# 불러오기
loaded_model = torch.load('trained_model.pth')

정규화 기법 및 트릭

  • Dropout: 훈련 중 무작위로 일부 노드를 비활성화하여 과적합 방지.
  • model.train(): 배치 정규화 및 드롭아웃 활성화.
  • model.eval(): 평가 모드에서 동작, 모든 드롭아웃/배치 정규화는 고정됨.
  • with torch.no_grad(): 그래디언트 계산을 일시적으로 비활성화하여 메모리 절약 및 성능 향상.

데이터 증강

훈련 데이터의 다양성을 높이기 위해 다양한 변환을 적용합니다.

augmentation = transforms.Compose([
    transforms.Resize((80, 80)),
    transforms.RandomHorizontalFlip(),
    transforms.RandomCrop(64),
    transforms.ColorJitter(brightness=0.5, contrast=0.5, hue=0.5),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])

파일 및 경로 처리

파일 읽기, 경로 조합, 디렉터리 목록 추출 등의 기초 작업 예시입니다.

with open('data.txt', 'r') as f:
    content = f.read()
    print(f"File content: {content}")

file_list = os.listdir('./data/train')
path = os.path.join('./data', 'train')

네트워크 구성 요소 이해

  • Backbone: 특징 추출을 담당하는 주요 네트워크 (예: ResNet).
  • Head: 최종 출력을 생성하는 분류기 부분.
  • Neck: 특징 맵을 보다 효과적으로 조합하는 중간 구조.
  • Bottleneck: 차원 축소를 통해 정보를 압축하는 구조.
  • GAP (Global Average Pooling): 채널별 평균값을 취해 입력 크기를 줄이는 방법.
  • Embedding: 입력 데이터를 벡터 공간으로 매핑하는 과정.
  • Pretext Task vs Downstream Task: 사전 훈련과 미세 조정의 역할 구분.
  • Warm-up: 초기 학습률을 낮게 시작하여 수렴 안정성 향상.

태그: PyTorch Neural Network image classification data augmentation dropout

6월 27일 19:56에 게시됨