Image Classification with CNN using CIFAR-10 and MPS

원성혁·2023년 1월 2일
0

AI

목록 보기
1/2
post-thumbnail

스터디 모임에 앞서 CS231n Lecture 2개를 보고 숙제 하기 뿐만 아니라 각자 image classification을 시도해 보기로 했다.

나는 어렵게 구현하기 보다는 VGG기반 CNN 구조를 사용할 예정이고 이미 책을 통해 학습했던 코드를 기반으로 사용할 예정이다.

pytorch는 nn.Sequential 과 nn.Module 두가지 방법이 있는데 class방식이며 좀더 복잡하지만 권장받는 nn.Module을 활용해서 만들었다.

계획은 cnn basic block(conv-conv-relu-maxpooling) 의 블록이 3개로 이루어지고 말단은 flatten과정 이후 fully connected 연산을 진행한다.

import torch
import torch.nn as nn

class BasicBlock(nn.Module):
  def __init__(self, in_channels, out_channels, hidden_dim):
    super(BasicBlock, self).__init__()
    self.conv1 = nn.Conv2d(in_channels, hidden_dim, kernel_size=3, padding=1)
    self.conv2 = nn.Conv2d(hidden_dim, out_channels, kernel_size=3, padding=1)
    self.relu = nn.ReLU()
    self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
    
  def forward(self,x):
    x = self.conv1(x)
    x = self.relu(x)
    x = self.conv2(x)
    x = self.relu(x)
    x = self.pool(x)

    return x

다음이 CNN기반 Basic Block이다. nn.Conv2d를 사용하면 convolutional 연산을 사용할 수 있으며 4개의 argument를 기반으로 작동된다.

input -> hidden -> output

kernel size는 3으로 변함 없지만 위의 input layer, hidden layer output layer 의 수를 설계하는 것이 중요하다.
maxpooling은 stride=2이다.

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

    self.block1 = BasicBlock(in_channels=3, out_channels=32,hidden_dim=16)
    self.block2 = BasicBlock(in_channels=32, out_channels=128,hidden_dim=64)
    self.block3 = BasicBlock(in_channels=128, out_channels=256,hidden_dim=128)

    self.fc1 = nn.Linear(in_features = 4096, out_features = 2048)
    self.fc2 = nn.Linear(in_features = 2048, out_features = 256)
    self.fc3 = nn.Linear(in_features = 256, out_features = num_classes)

    self.relu = nn.ReLU()
  
  def forward(self,x):
    x = self.block1(x)
    x = self.block2(x)
    x = self.block3(x)
    x = torch.flatten(x,start_dim=1)

    x = self.fc1(x)
    x = self.relu(x)
    x = self.fc2(x)
    x = self.relu(x)
    x = self.fc3(x)

    return x

앞서 설계와 같이 CNN block 3개가 연결되어 있다. 각 블록별로 앞에 out_channels와 뒤의 in_channels의 개수가 같음을 중요하게 염두해야한다.

32x32 -> 16x16 -> 8x8 -> 4x4

세번의 풀링을 거치고 결과 이미지의 크기는 4x4이다. flatten의 결과는 256x4x4 총 4096으로 계산된다.

CNN의 channels수를 파악해 설계를 완벽하게 하는 것이 모델링의 핵심인 것 같다.

훈련은 최근에 산 M1pro 를 사용할 예정이고 GPU를 사용하는 방법이 MPS를 쓰면 된다고 한다. 나는 cuda만 사용 경험이 있었고 맥북은 cuda가 안된다고 해서 잘못된 선택을 했나 놀랐는데 최근 맥북을 활용한 pytorch gpu 가속이 가능하다고 해서 다행이다.

실제로 사용해보니 Colab을 쓴 유저로써 m1pro gpucore 14개의 성능은 그렇게 좋음을 잘 모르겠다...
50000개의 데이터 epoch 10으로 훈련을 했고 8분의 훈련시간이 걸렸다.
그 전에 100개의 epoch로 시도해보느라 많은 시간을 소비하기도 했고 20 epoch를 돌파하면서 loss가 높아지는현상이 일어나서 중단시켰다.
이유는 잘 모르겠다... cuda에서 사용한 경우랑 어떤 차이가 발생하는지 궁금증으로 남아있다.

결과는 0.7337의 정확도이고 이를 높이기 위해 어떻게 할지 고민을 해봐야 할 것 같다.

profile
AI개발자를 향해 전진중

1개의 댓글

comment-user-thumbnail
2023년 2월 2일

화이팅

답글 달기