본문 바로가기
취미 낙지/Python

[딥러닝 / Pytorch / 이미지 분석] Classification 예제 정리1 - 기본 사용법

by 대머리낙지 2023. 6. 25.
반응형

파이토치-로고

안녕하세요 대머리 낙지입니다.

 

Pytorch를 활용한 이미지 분류(Classification) 문제를 다루는 전반적인 flow를 기록해보려 합니다.

Google colab환경에서 CIFAR10 이미지 데이터를 활용해 간단한 CNN을 돌려보겠습니다.

 

CIFAR10?

- CIFAR10은 10가지 사물에 대한 32X32X3 크기의 이미지 데이터셋입니다. 크기도 작고 가벼워 테스트에 많이들 활용하십니다.

해당 dataset은 torchvision을 통해 쉽게 다운로드 받을 수 있습니다.

이미지넷-이미지
CIFAR10의 이미지 구성

 

 

 

먼저 필요한 모듈들을 import 합니다.

# import modules
import torch
import torch. nn as nn
import torchvision.transforms as transforms
import torch.optim as optim
import torchvision
import matplotlib.pyplot as plt
import numpy as np

# torch 연산을 수행할 환경 설정
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print('using device:', device)

여기서 중요한 포인트는 "device"라는 변수에 torch 연산을 수행할 환경을 넣는 것 입니다.

gpu가 사용 가능한 경우 "cuda"가, 불가능한 경우 "cpu"가 입력됩니다.

 

 

CIFAR10 이미지 데이터를 불러오기 전에 Augmentation을 설정해줍니다.

# Image augmentation - train
transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4), # 테두리에 4만큼 여분을 준뒤 그 안에서 32X32의 Random 영역 자르기
    transforms.RandomHorizontalFlip(0.5), # 50% 확률로 좌우 반전
    # transforms.RandomVerticalFlip(0.5), # 50% 확률로 상하 반전
    transforms.ToTensor(), # pixel 값들을 0~1 사이로 scaling하고 tensor 객체로 변환
])

# Image augmentation - test
transform_test = transforms.Compose([
    transforms.ToTensor(), # pixel 값들을 0~1 사이로 scaling하고 tensor 객체로 변환
])

 

train 시에는 이미지를 조금 흔들어주기 위해서 random crop, 상하좌우 반전 등을 넣었고,

test 시에는 이미지를 그대로 사용하기 위해 rescaling만 진행하였습니다.

 

설정이 필요한 일부 Hyper parameter들과 CIFAR10 데이터셋을 활용하여 Dataloader를 만들어줍니다.

Dataloader는 for문을 돌며 설정된 옵션들을 따라 이미지와 라벨을 뱉어줍니다.

#==== Hyper parameters ====
LEARNING_RATE = 1e-3
BATCH_SIZE = 128


# LOAD CIFAR10 & Make dataset
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=BATCH_SIZE, shuffle=True, num_workers=1)

testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
testloader = torch.utils.data.DataLoader(testset, batch_size=100, shuffle=False, num_workers=1)

 

반응형

 

Train/Test Dataloader를 확인해보겠습니다.

전부다 확인이 필요하시면 batch 내에서 for문을 돌리시고, break을 해제 해주시면 됩니다.

for batch, label in trainloader:
    img = batch[0].numpy()# batch 내 index=0 데이터 확인
    img = img.transpose(1,2,0) # c, h w --> h, w, c 변환

    plt.figure()
    plt.imshow(img)
    plt.show()
    break
    

for batch, label in testloader:
    img = batch[3].numpy() # batch 내 index=3 데이터 확인
    img = img.transpose(1,2,0) # c, h w --> h, w, c 변환

    plt.figure()
    plt.imshow(img)
    plt.show()
    break

이미지넷-트럭이미지넷-비행기
Train(트럭)과 Test loader(비행기)의 이미지 확인

Trainloader의 경우 Augmentation이 적용된 것을 확인할 수 있습니다.

 

 

그럼 Classification을 수행할 모델을 생성해보겠습니다.

모델은 아래와 같이 구성하였습니다.

# 모델 생성
class MyCNN(nn.Module):
    # model 초기화 및 사용할 layer들 정의
    def __init__(self):
        super(MyCNN, self).__init__()

        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, padding=1)
        # 3ch input을 64ch로 확장, size는 동일하게 유지하는 conv layer
        self.maxpool = nn.MaxPool2d(2) # size / 2
        self.conv2 = nn.Conv2d(64, 128, kernel_size=3, padding=1) 
        # 64ch input을 128ch로 확장, size는 동일하게 유지하는 conv layer
        self.avgpool = nn.AdaptiveAvgPool2d(1) # avg pooling layer
        self.flatten = nn.Flatten() # feature들을 1차원화
        self.dropout = nn.Dropout(0.5) # 50% 확률로 dropout 적용
        self.fc1 = nn.Linear(128, 32)
        self.fc_out = nn.Linear(32, 10) # CIFAR10의 lable 수만큼 출력

    # model의 연산이 진행되는 부분
    def forward(self, x):
        x = self.conv1(x)
        x = self.maxpool(x)
        x = self.conv2(x)
        x = self.avgpool(x)
        x = self.flatten(x)
        x = self.fc1(x)
        x = self.dropout(x)
        x = self.fc_out(x)
        return x

 

 

다음으로 생성된 모델을 학습하고 평가하기 위한 코드를 작성하였습니다.

매 epoch마다 학습되는 과정을 모니터링할 수 있도록 설정하였습니다.

# test model
def test_model(model, testloader):
    model.eval() # test mode 전환
    correct = 0
    for x, y in testloader:
        x = x.to(device)
        y = y.to(device)

        y_hat = model(x)
        pred = y_hat.max(1)[1] # model output을 max index로 예측
        
        correct += sum(y == pred).item()
    print("test acc: {:.4f}".format(correct/len(testloader.dataset)) ) 
    
 # train define 
model = MyCNN() # model에 생성한 model class를 할당해줍니다.
criterion = nn.CrossEntropyLoss() # Loss function 정의 : multiclass의 단일 예측 문제 cross entropy
opt = optim.Adam(model.parameters(), lr=LEARNING_RATE)

#==== Hyper parameters ====
epochs = 30

model.to(device) # 초기에 설정한 device로 모델을 보내줍니다 (cuda or cpu)

for ep in range(epochs):
    epoch_loss = 0
    epoch_acc = 0
    for x, y in trainloader:

        # to device
        x = x.to(device)
        y = y.to(device)

        # set train mode
        model.train()

        # init.
        opt.zero_grad() # batch 별 grad 계산을 위한 초기화

        # run model
        y_hat = model(x)
        pred = y_hat.max(1)[1]
        loss = criterion(y_hat, y)

        # update weights
        loss.backward() # backpropagation을 이용한 weight update
        opt.step() # lr 만큼 학습 진행
        epoch_loss += loss.item()

        # monitoring
        epoch_acc += (pred==y).sum().item()

    epoch_acc = epoch_acc/len(trainloader.dataset)
        
    
    # 매 epoch 마다 학습결과 모니터링
    if ep%1 == 0:
        print('epoch: {}, loss: {:.4f}, acc: {:.4f}'.format(ep, epoch_loss, epoch_acc))
        test_model(model, testloader)

 

생성한 모델의 학습이 진행되며 loss는 줄고, accuracy는 상승하는 것을 볼 수 있습니다.

좀 더 빠르고 정확하게 모델을 학습하기 위해서는 모델의 변경과 Hyper parameter의 적절한 튜닝을 진행하면 됩니다.

파이썬플롯

 

감사합니다.

 

[취미생활/Python] - [딥러닝 / Pytorch / 이미지 분석] Classification 예제 정리2 - VGGNet

 

[딥러닝 / Pytorch / 이미지 분석] Classification 예제 정리2 - VGGNet

안녕하세요 대머리 낙지입니다. VGGNet을 Pytorch로 직접 모델링하는 과정을 정리해 보겠습니다. 우선 VGGNet이란? 딥러닝을 활용한 이미지 분류 분야에서 초창기에 개발된 모델입니다. VGG16을 직접 py

nakzi-lab.tistory.com

[취미생활/Python] - [딥러닝 / Pytorch / 이미지 분석] Classification 예제 정리3 - ResNet

 

[딥러닝 / Pytorch / 이미지 분석] Classification 예제 정리3 - ResNet

안녕하세요 대머리 낙지입니다. VGG에 이어서 ResNet을 Pytorch로 직접 구현해 보는 시간을 갖겠습니다. ResNet이란 Residual Block의 개념이 처음 도입된 network로써 등장 당시에 아주 큰 성능 향상과 함께

nakzi-lab.tistory.com

 

반응형