Artificial intelligence, AI/Pytorch

[Pytorch] Image Preprocessing 이미지 전처리

engine 2021. 5. 11. 16:30

개발 환경 : 리눅스 (Ubuntu)

언어 : 파이썬 (Python)

라이브러리 :  파이 토치 (Pytorch)

 

이미지 분류 (Image Classification) 

이미지는 컴퓨터 비전 (Computer Vision) 분야에 속한다.

4차 산업혁명의 핵심인 딥러닝 기술은 현재까지 해당 분야에서 가장 큰 발전을 이뤘다고 볼 수 있으며,

크게 아래의 3가지 분야로 연구가 진행되고 있다.

 - Classification 고양이라는 사물의 존재 여부를 분류한다.

 - Detection은 고양이라는 사물의 위치를 찾아냄과 동시에 여러가지 사물을 인식한다.

 - Segmentation 고양이라는 사물의 형태를 찾아낸다.

이번 프로젝트는 4차 산업혁명과 딥러닝의 가능성을 처음으로 대두시킨 CNN (Convolution Neural Network)

모델을 통한 이미지 분류 (Image Classification)를 파이썬 (Python)과 파이 토치 (Pytorch)로 진행했다.


이미지 데이터 전처리 (Image Preprocessing)

딥러닝 모델이 잘 학습하기 위해선 준비된 데이터들을 모델에 맞게 정제하는 과정이 필요하다.

이를 데이터 전처리 과정 (Preprocessing)이라 부르며,

이미지 데이터는 Augmentation,Normalizing,OpenCV,Scaling 등의 과정을 거친다.

 

데이터에 적합한 딥러닝 모델 생성

데이터 처리에 대표적인 딥러닝 모델은 CNN (Convolution Neural Network)이다.

2012년 ImageNet Large Scale Visual Recognition Challenge (ILSVRC)에서Alexnet 등장으로 딥러닝에 대한 가능성이 화제 되면서 많은 사람들이 CNN을 활용하기 시작했다.

 

기존 딥러닝 Neural Network는 Image Pixel 단위로 학습하기 때문에 Image의 공간적 패턴을 가진 특징을 찾지 못하는 한계가 있다. 이를 해결하기 위해 CNN 은 Convolution, Pooling, ReLU 과정을 통해 이미지 공간적 특징을 추출 후  이를 Fully Connected Layer를 통해 분류하는 구조로 구성되어 있다. 한마디로 이미지 공간적 정보를 갖고 있는 채 특징을 추출해 학습시키는 원리이다.

torchsummary는 코드를 쉽게 나타낸다. 없으면 pip로 설치하면 된다.

pip install torchsummary

 

Code

import torch.nn as nn

class CNN(nn.Module):

    def __init__(self):
        super(CNN, self).__init__()
        self.layer = nn.Sequential(
            #        3*200*200
            nn.Conv2d(3, 32, 3, stride = 1),
            nn.BatchNorm2d(32),
            nn.ReLU(),

            #         32*198*198
            nn.Conv2d(32, 64, 3, stride = 1),
            nn.BatchNorm2d(64),
            nn.ReLU(),

            #            64*196*196
            nn.MaxPool2d(2, 2),

            #         64*98*98
            nn.Conv2d(64, 128, 3, stride = 1),
            nn.BatchNorm2d(128),
            nn.ReLU(),

            #         128*96*96
            nn.Conv2d(128, 256, 3, stride = 1),
            nn.BatchNorm2d(256),
            nn.ReLU(),

            #           256*94*94
            nn.MaxPool2d(2, 2),

            #            256*47*47
            nn.Conv2d(256,512,3, stride=1),
            nn.BatchNorm2d(512),
            nn.ReLU()
        )
        #                          512*45*45
        self.avg_pool = nn.AvgPool2d(45)
        self.classifier = nn.Linear(512,5)

    def forward(self, x):
        feat = self.layer(x)
        flat = self.avg_pool(feat).view(feat.size(0),-1)
        out = self.classifier(flat)
        return out, feat

torchsummary import summary를 이용해 출력

from torchsummary import summary
    model = CNN().cuda()
    summary(model)

딥러닝 Hyperparameter, Optimizer, Loss Function을 지정해주면 모델 제작이 끝나게 된다.

Hyperparameter는 기본적으로 Batch Size, Epoch, Learning Rate 가 있고, Parser 를 활용해서 쉽게 수치를 바꿔 실험할 수 있다. Optimizer와 Loss Function 은 가장 많이 사용되는 Adam, Cross Entropy를 사용해도 좋다. 자유롭게 사용하자.

Log Interval 은 학습 과정을 출력하는 데 사용되는 수치이다.

import torch.optim

    parser = argparse.ArgumentParser(description='Image')
    parser.add_argument('--Resize',type=int)

    parser.add_argument('--batch-size', type=int)
    parser.add_argument('--epochs', type=int)
    parser.add_argument('--lr', type=float)

    parser.add_argument('--log-interval', type=float)
    args = parser.parse_args()

    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)
    loss_func = nn.CrossEntropyLoss()

마지막으로 train & test code 작성

dataset Loader에서 batch에 따른 image, label 호출 후 학습 진행

code

def train(args, model, train_loader, optimizer, epoch, loss_func, min_loss):
    model.train()
    train_loss = 0
    correct = 0
    for batch_index,[image,label] in enumerate(train_loader):
        image = image.cuda()
        label = label.cuda()

        out, feat = model(image)
        loss = loss_func(out,label)
        train_loss += loss.item()
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        pred = out.argmax(dim=1, keepdim=True)  # get the index of the max log-probability
        correct += pred.eq(label.view_as(pred)).sum().item()

        if batch_index % args.log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, batch_index * len(image), len(train_loader.dataset),
                       100. * batch_index / len(train_loader), loss.item()))

    train_loss /= len(train_loader)
    acc = 100. * correct / len(train_loader.dataset)

    if train_loss < min_loss:
        min_loss = train_loss
        torch.save(model.state_dict(), '/path(모델 저장 경로)/')

    return train_loss, acc, min_loss

테스트 코드는 말 그대로 테스트만!

학습에 관여하면 안 되므로 loss.backward과 같은 코드를 제거 후 트레이닝과 유사하게 작성한다.

def test(args, model, test_loader, loss_func):
    model.eval()
    test_loss = 0
    correct = 0
    pred_save = []

    for image, label in test_loader:
        image = image.cuda()
        label = label.cuda()
        out, feat = model(image)
        loss = loss_func(out,label)
        test_loss += loss.item()
        pred = out.argmax(dim=1, keepdim=True)  # 최대 확률 인덱스 가져오기
        correct += pred.eq(label.view_as(pred)).sum().item()
        pred_save.append(pred)

    test_loss /= len(test_loader)
    print('\n Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset)))
    val_acc = 100.*correct/len(test_loader.dataset)

    return test_loss, val_acc, pred_save

 

모델 평가 (Evaluation)

딥러닝 모델에 대한 성능 평가 지표로 파이썬 (Python)의 Loss 값과 Accuracy를 사용했다.

Loss 란 실제 주어진 값이랑 딥러닝이 예측한 결과 값 간의 오차를 나타낸다. deeplearning 학습을 통해 해당 오차를 줄이기 위한 최적의 가중치(weight)를 찾아나가는 과정을 반복한다.

Accuracy는 딥러닝이 Classifier를 통해 최종 Class를 Predict 하면 예측 값과 실제 주어진 Class 가 일치했는지 확인할 수 있다.

참조 블로그 : 

 

무이메이커스_딥러닝을 활용한 인공지능 (AI) 이미지 분류 (Image Classification) 프로젝트

프로젝트 진행 순서 1. 이미지 분류 (Image Classification) 개요 2. 이미지 데이터 전처리 (Image Preprocessing) 3. 데이터에 적합한 딥러닝 모델 생성 4. 모델 평가 및 시각화 (Evaluation and Visualization)..

honeycomb-makers.tistory.com