การจำแนกวัตถุ (Cifar10) โดยใช้ CNN อย่างง่ายบน Pytorch

 Ref : Building an Image Classification Model From Scratch Using PyTorch


import matplotlib.pyplot as plt
import numpy as np

import torch
import torchvision 
import torchvision.transforms as transforms 
import torch.nn as nn 
import torch.nn.functional as F 
import torch.optim as optim 


#### 1. Load and normalize data
transform   = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) 
batch_size  = 4
num_workers = 2

trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
testset  = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)

trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True, num_workers=num_workers)
testloader  = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=num_workers)

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

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

dataiter = iter(trainloader) 
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print(labels,' '.join('%s' % classes[labels[j]] for j in range(batch_size)))



#### 2. Define the CNN
class Net(nn.Module):    
    def __init__(self):
        super(Net, self).__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 = x.view(-1, 16 * 5 * 5) 
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()
print(net)



#### 3. Define a Loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)



#### 4. Train the network
start = torch.cuda.Event(enable_timing=True)
end   = torch.cuda.Event(enable_timing=True)
start.record()
for epoch in range(2):  
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels        = data             
        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

            end.record()
torch.cuda.synchronize()
print('Finished Training')
print(start.elapsed_time(end))  # milliseconds

# save and reload
PATH = './data/cifar_net.pth'
torch.save(net.state_dict(), PATH)
net = Net()
net.load_state_dict(torch.load(PATH))



#### 5. Test the network on test data

# Test on 4 images of a batch
dataiter       = iter(testloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%s' % classes[labels[j]] for j in range(4)))
outputs        = net(images)
_, predicted   = torch.max(outputs, 1)
print('Predicted: ', ' '.join('%s' % classes[predicted[j]] for j in range(4)))

# Test on 10,000 images
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))






Previous
Next Post »