3 minute read

1. Import, Declaration, and Datasets

import torch
import torchvision
import torchvision.transforms as transforms
transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))]
)

batch_size = 4

trainset = torchvision.datasets.CIFAR10(root='./data',train=True,download=True,transform=transform)
trainloader = torch.utils.data.DataLoader(trainset,batch_size=batch_size,shuffle=True,num_workers=2)

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

classes=('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')

출력

Files already downloaded and verified
Files already downloaded and verified

2. Image Check

import matplotlib.pyplot as plt
import numpy as np

#functions to show an image

def imgshow(img):
  img = img / 2 + 0.5 
  npimg = img.numpy()
  plt.imshow(np.transpose(npimg,(1,2,0)))
  plt.show()

# get some random training images
dataiter = iter(trainloader)
images,labels=dataiter.next()

# show images
imgshow(torchvision.utils.make_grid(images))

# print labels
print("".join('%10s'%classes[labels[j]] for j in range(batch_size)))

출력
output_3_0

     plane       cat      ship     horse

3. Define a Convolutional Neural Network

import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
  def __init__(self):
    super().__init__()
    self.conv1 = nn.Conv2d(3,6,5)
    self.pool = nn.MaxPool2d(2,2)
    self.conv2 = nn.Conv2d(6,16,5)
    self.fc1 = nn.Linear(16*5*5,120)
    self.fc2 = nn.Linear(120,84)
    self.fc3 = nn.Linear(84,10)

  def forward(self,x):
    x = self.pool(F.relu(self.conv1(x)))
    x = self.pool(F.relu(self.conv2(x)))
    x = torch.flatten(x,1)
    x = F.relu(self.fc1(x))
    x = F.relu(self.fc2(x))
    x = self.fc3(x)
    return x
  
net = Net()

Set device as GPU

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

net.to(device)

출력

cuda:0





Net(
  (conv1): Conv2d(3, 16, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(16, 64, kernel_size=(5, 5), stride=(1, 1))
  (conv3): Conv2d(64, 32, kernel_size=(3, 3), stride=(1, 1))
  (fc1): Linear(in_features=288, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (dropout): Dropout(p=0.2, inplace=False)
)

4. Loss and Optimizer Setting

import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr = 0.001,momentum=0.9)

5. Run Training

for epoch in range(2):
  running_loss = 0.0
  for i,data in enumerate(trainloader,0):
    inputs,labels = data[0].to(device),data[1].to(device)

    optimizer.zero_grad()

    outputs = net(inputs)
    loss = criterion(outputs,labels)
    loss.backward()
    optimizer.step()

    running_loss += loss.item()
    if i % 2000 == 1999:
      print("[%d,%5d] loss: %.3f" %(epoch + 1, i + 1, running_loss/2000))
      running_loss = 0.0

출력

[1, 2000] loss: 2.301
[1, 4000] loss: 2.107
[1, 6000] loss: 1.894
[1, 8000] loss: 1.788
[1,10000] loss: 1.728
[1,12000] loss: 1.663
[2, 2000] loss: 1.590
[2, 4000] loss: 1.546
[2, 6000] loss: 1.494
[2, 8000] loss: 1.495
[2,10000] loss: 1.469
[2,12000] loss: 1.438
PATH = "./cifar_net.pth"
torch.save(net.state_dict(),PATH)

6. Test the network on the test data

dataiter = iter(testloader)
images,labels = dataiter.next()

imgshow(torchvision.utils.make_grid(images))
print("GroundTruth:", "".join("%8s"%classes[labels[j]] for j in range(4)))

출력

output_14_0

GroundTruth:      cat    ship    ship   plane

7. Test the network on the test data

net = Net()
net.load_state_dict(torch.load(PATH))

outputs = net(images)

_,predicted = torch.max(outputs,1)

print("Predicted:", "".join("%8s" % classes[predicted[i]] for i in range(4)))
Predicted:      cat    ship   plane    ship
correct = 0
total = 0

with torch.no_grad():
  for data in testloader:
    images,labels = data
    outputs = net(images)
    _,predicted = torch.max(outputs.data,1)
    total += labels.size(0)
    correct += (predicted==labels).sum().item()

print("accuracy of the network on the 10000 test images: %d %%"%(100*correct/total))

출력

accuracy of the network on the 10000 test images: 50 %
correct_pred = {classname:0 for classname in classes}
total_pred = {classname:0 for classname in classes}

with torch.no_grad():
  for data in testloader:
    images,labels = data
    outputs = net(images)
    _,predictions = torch.max(outputs.data,1)
    for label,prediction in zip(labels,predictions):
      if label==prediction:
        correct_pred[classes[label]] += 1
      total_pred[classes[label]] += 1
    total += labels.size(0)
    correct += (predicted==labels).sum().item()

for classname,correct_count in correct_pred.items():
  accuracy = 100 * float(correct_count) / total_pred[classname]
  print("Accuracy for class {:5s} is :{:.1f} %".format(classname,accuracy))

출력

Accuracy for class plane is :50.2 %
Accuracy for class car   is :63.6 %
Accuracy for class bird  is :30.0 %
Accuracy for class cat   is :30.0 %
Accuracy for class deer  is :37.7 %
Accuracy for class dog   is :41.8 %
Accuracy for class frog  is :74.8 %
Accuracy for class horse is :63.1 %
Accuracy for class ship  is :67.3 %
Accuracy for class truck is :67.9 %

8. Variations & Ablation Study

Define Deeper CNN

import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
  def __init__(self):
    super().__init__()
    self.conv1 = nn.Conv2d(3,6,5)
    self.conv2 = nn.Conv2d(6,16,5)
    self.conv3 = nn.Conv2d(16,32,3)
    self.pool = nn.MaxPool2d(2,2)
    
    self.fc1 = nn.Linear(32*3*3,120)
    self.fc2 = nn.Linear(120,84)
    self.fc3 = nn.Linear(84,10)

  def forward(self,x):
    x = self.pool(F.relu(self.conv1(x)))
    x = self.pool(F.relu(self.conv2(x)))
    x = F.relu(self.conv3(x))
    x = torch.flatten(x,1)
    x = F.relu(self.fc1(x))
    x = F.relu(self.fc2(x))
    x = self.fc3(x)
    return x
  
net = Net()

Number of Filters

import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
  def __init__(self):
    super().__init__()
    self.conv1 = nn.Conv2d(3,16,5)
    self.conv2 = nn.Conv2d(16,64,5)
    # self.conv3 = nn.Conv2d(16,32,3)
    self.pool = nn.MaxPool2d(2,2)
    
    self.fc1 = nn.Linear(64*5*5,120)
    self.fc2 = nn.Linear(120,84)
    self.fc3 = nn.Linear(84,10)

  def forward(self,x):
    x = self.pool(F.relu(self.conv1(x)))
    x = self.pool(F.relu(self.conv2(x)))
    # x = F.relu(self.conv3(x))
    x = torch.flatten(x,1)
    x = F.relu(self.fc1(x))
    x = F.relu(self.fc2(x))
    x = self.fc3(x)
    return x
  
net = Net()

Dropout

import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
  def __init__(self):
    super().__init__()
    self.conv1 = nn.Conv2d(3,16,5)
    self.conv2 = nn.Conv2d(16,64,5)
    self.conv3 = nn.Conv2d(64,32,3)
    
    self.fc1 = nn.Linear(32*3*3,120)
    self.fc2 = nn.Linear(120,84)
    self.fc3 = nn.Linear(84,10)

    self.pool = nn.MaxPool2d(2,2)
    self.dropout = nn.Dropout(p=0.2)

  def forward(self,x):
    x = self.pool(F.relu(self.conv1(x)))
    x = self.pool(F.relu(self.conv2(x)))
    x = F.relu(self.conv3(x))
    x = torch.flatten(x,1)
    x = F.relu(self.fc1(x))
    x = F.relu(self.fc2(x))
    x = self.fc3(x)
    x = self.dropout(x)
    return x
  
net = Net()

Leave a comment