철학과 학생의 개발자 도전기

[Pytorch] Pytorch Tutorial - CNN 본문

Pytorch

[Pytorch] Pytorch Tutorial - CNN

Younghun 2022. 10. 4. 13:32

 

Convolutional Neural Network (CNN)

  • 2층짜리 Convolutional layer를 쌓고, Filter Size는 5*5로 정한다.
  • 2층짜리 Pooling layer를 쌓고, 2*2 size의 Max Pooling을 사용한다.
  • 마지막에 Fully Connected Layer를 사용한다.
  • 자세한 내용은 아래 링크에서 CNN파트를 확인하면 된다.

Pytorch Tutorial for Deep Learning Lovers | Kaggle

 

Pytorch Tutorial for Deep Learning Lovers

Explore and run machine learning code with Kaggle Notebooks | Using data from Digit Recognizer

www.kaggle.com

import torch
import torch.nn as nn
from torch.autograd import Variable

class CNNModel(nn.Module):
    def __init__(self):
        super(CNNModel, self).__init__()

        # Convolution 1
        self.cnn1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5, stride=1, padding=0)
        self.relu1 = nn.ReLU()

        # Max Pool 1
        self.maxpool1 = nn.MaxPool2d(kernel_size=2)

        # Convolution 2
        self.cnn2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, stride=1, padding=0)
        self.relu2 = nn.ReLU()

        # Max Pool 2
        self.maxpool2 = nn.MaxPool2d(kernel_size=2)

        # Fully conected 1
        self.fc1 = nn.Linear(32 * 4 * 4, 10) # 28 -> 24 -> 12 -> 8 -> 4 size

    def forward(self, x):
        # Convolution 1
        out = self.cnn1(x)
        out = self.relu1(out)

        # Max pool 1
        out = self.maxpool1(out)

        # Convolution 2 
        out = self.cnn2(out)
        out = self.relu2(out)

        # Max pool 2 
        out = self.maxpool2(out)

        # flatten
        out = out.view(out.size(0), -1)

        # Linear function (readout)
        out = self.fc1(out)

        return out

# batch_size, epoch and iteration
batch_size = 100
n_iters = 2500
num_epochs = n_iters / (len(features_train) / batch_size)
num_epochs = int(num_epochs)

# Pytorch train and test sets
train = torch.utils.data.TensorDataset(featuresTrain,targetsTrain)
test = torch.utils.data.TensorDataset(featuresTest,targetsTest)

# data loader
train_loader = torch.utils.data.DataLoader(train, batch_size = batch_size, shuffle = False)
test_loader = torch.utils.data.DataLoader(test, batch_size = batch_size, shuffle = False)
    
# Create CNN
model = CNNModel()

# Cross Entropy Loss 
error = nn.CrossEntropyLoss()

# SGD Optimizer
learning_rate = 0.1
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

대부분의 내용은 이전 ANN과 동일하다. hidden layer만 2차원 Convolution layer를 사용하면 된다. CNN은 activation function으로 주로 ReLU를 사용한다. 마지막 FC layer에서 input은 32 * 4 * 4이다. 32개의 채널에 feature map size가 4*4인 것이다. input size는 28*28인데 5*5 필터를 가진 Conv layer를 통과하면서 24*24가 되고 2*2 size의 Max pooling을 통해 12*12가 된다. 같은 과정을 반복하면 12 -> 8 -> 4 로 줄어든다.

 

 

이제 CNN 학습을 시켜보자.

# CNN model training
count = 0
loss_list = []
iteration_list = []
accuracy_list = []
for epoch in range(num_epochs):
    for i, (images, labels) in enumerate(train_loader):
        
        train = Variable(images.view(100,1,28,28))
        labels = Variable(labels)
        
        # Clear gradients
        optimizer.zero_grad()
        
        # Forward propagation
        outputs = model(train)
        
        # Calculate softmax and ross entropy loss
        loss = error(outputs, labels)
        
        # Calculating gradients
        loss.backward()

        # Update parameters
        optimizer.step()
        
        count += 1
        
        if count % 50 == 0:
            # Calculate Accuracy         
            correct = 0
            total = 0
            # Iterate through test dataset
            for images, labels in test_loader:
                
                test = Variable(images.view(100,1,28,28))
                
                # Forward propagation
                outputs = model(test)
                
                # Get predictions from the maximum value
                predicted = torch.max(outputs.data, 1)[1]
                
                # Total number of labels
                total += len(labels)
                
                correct += (predicted == labels).sum()
            
            accuracy = 100 * correct / float(total)

            # store loss and iteration
            loss_list.append(loss.data)
            iteration_list.append(count)
            accuracy_list.append(accuracy)
            
        if count % 500 == 0:
            # Print Loss
            print('Iteration: {}  Loss: {}  Accuracy: {} %'.format(count, loss.data, accuracy))

2000번의 반복만에 98%라는 높은 정확도를 보인다! ANN보다 더 좋은 성능을 보인다. 하지만 학습시간은 훨씬 더 오래 걸렸다.

 

 

학습과정을 간단히 시각화하면 다음과 같다.


후기

CNN에 대한 개념적 이해만 있으면 코드로 작성하는 것은 크게 어렵지 않은 것 같다. 기존에 배운 ANN에서 조금씩 수정해주면 되기 때문이다.  사람들이 왜 모델 튜닝보다 데이터 전처리가 더 중요하다고 말하는지 알 것 같다. 데이터 전처리가 훨씬 복잡하고 데이터에 대한 이해도를 필요로 하기 때문인 것 같다. 그렇게 데이터를 잘 가공하면 좋은 알고리즘을 사용해서 괜찮은 성능을 얻을 수 있을 것 같다.

'Pytorch' 카테고리의 다른 글

[Pytorch] Pytorch Tutorial - ANN  (2) 2022.10.03
[Pytorch] Pytorch Tutorial - Basics of Pytorch  (0) 2022.10.02