Adventure_cnn

Adventure_CNN
https://adventuresinmachinelearning.com/convolutional-neural-networks-tutorial-in-pytorch/
path = 'e:/DL/torch/cnn/adventure_cnn_0504.ipynb'


# 필요 모듈
%matplotlib inline
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
import torchvision.transforms as transforms
import torchvision.datasets
 
# Hyperparameters
num_epochs = 1
#num_classes = 10
batch_size = 100
learning_rate = 0.001
 
DATA_PATH = './data'
MODEL_STORE_PATH = './model'
 
# transforms to apply to the data
trans = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
 
# MNIST dataset
train_dataset = torchvision.datasets.MNIST(root=DATA_PATH, train=True,
transform=trans, download=False)
test_dataset = torchvision.datasets.MNIST(root=DATA_PATH, train=False,
transform=trans)
 
# Data loader
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size,
shuffle=False)
test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
 
len(train_dataset)
60000
 
# Convolutional neural network (two convolutional layers)
class ConvNet(nn.Module):
   def __init__(self):
      super(ConvNet, self).__init__()
      self.layer1 = nn.Sequential(
      nn.Conv2d(1, 32, kernel_size=5, stride=1, padding=2),
      nn.ReLU(),
      nn.MaxPool2d(kernel_size=2, stride=2))
      self.layer2 = nn.Sequential(
      nn.Conv2d(32, 64, kernel_size=5, stride=1, padding=2),
      nn.ReLU(),
      nn.MaxPool2d(kernel_size=2, stride=2))
      self.drop_out = nn.Dropout()
      self.fc1 = nn.Linear(7 * 7 * 64, 1000)
      self.fc2 = nn.Linear(1000, 10)
 
   def forward(self, x):
      out = self.layer1(x)
      out = self.layer2(out)
      out = out.reshape(out.size(0), -1)

      # out.size가 (12, 64, 7, 7)이면 12는 batch 길이, 64는 채널갯수, 7 x 7,
         여기서 out.size(0) = 12, 즉, batch 길이 
         out.reshape(out.size(0), -1)는 batch 길이 12를 제외하고 나머지는 모두 
         flatten하라는 것

      out = self.drop_out(out)
      out = self.fc1(out)
      out = self.fc2(out)
      return out
 
# 모델
model = ConvNet()
 
# Loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
 
 
# Train the model
total_step = len(train_loader) # 600
loss_list = []
acc_list = []
for epoch in range(num_epochs): # num_epoch = 1

# 데이터 개수가 너무 많아 자른 것
   nsamples = 500
   for i, (images, labels) in enumerate(train_loader):
      if i >= nsamples:
      break

images.shape = torch.Size([5, 1, 28, 28])  # batch가 5개
labels.shape = torch.Size([5])                 # label은 5개 숫자
 
      # Run the forward pass
      outputs = model(images)
      loss = criterion(outputs, labels)
      loss_list.append(loss.item())
 
      # Backprop and perform Adam optimisation
      optimizer.zero_grad()
      loss.backward()
      optimizer.step()

      # Track the accuracy
      total = labels.size(0)
label,size() = torch.Size([5])
total = label,size(0) = 5
outputs.data.size() = torch.Size([5, 10])
이미지가 10개로 분류되고 배치가 5개이므로 outputs의 shape은 5*10
각 데이터에서 확률이 가장 높은 것의 위치가 분류번호임.
즉, 5개 데이터의 target은 [5, 0, 4, 1, 9] 이다.

outputs.data =
tensor([[-1.2115, -0.5433, 0.9069, 2.2487, -0.0394, 4.1010, 1.3367, -2.3835,
-2.6181, 0.9274],
 
[ 5.9270, -5.7935, 3.2588, 1.2869, 2.1887, 1.3981, 4.3176, -2.7138,
-3.7101, 0.1457],
 
[-0.8513, -3.4468, 0.8990, 1.7049, 9.7010, 1.6340, 0.2176, -2.0064,
-3.0131, 1.4095],
 
[-2.5266, 3.1374, 0.8038, -0.0947, 1.4950, 2.5771, 2.2418, -2.6114,
-1.9924, 1.4202],
 
[-1.4229, 0.8560, 1.3030, 0.5409, 0.5772, 1.5919, 2.0649, -2.6247,
-2.9612, 4.6833]])

      _, predicted = torch.max(outputs.data, 1)
여기서 1은 axis=1, 즉 횡으로 높은 것을 고른다는 뜻
torch.max()는 2개 값을 return, 전자는 values, 후자는 indices
필요한 것은 후자인 indices 임

torch.max(outputs.data, 1) =
torch.return_types.max(values=tensor([4.1010, 5.9270, 9.7010, 3.1374, 4.6833]),
indices=tensor([5, 0, 4, 1, 9]))
 
predicted.size() = torch.Size([5])
      
      correct = (predicted == labels).sum().item()
 
(predicted == labels) = tensor([1, 1, 1, 1, 1], dtype=torch.uint8)
(predicted == labels).sum() = tensor(5)
correct = (predicted == labels).sum().item() : 5
 
      acc_list.append(correct / total)
      acc_accuracy = (sum(acc_list) / len(acc_list)) * 100

      if (i + 1) % 10 == 0:
         print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}, Accuracy: {:.2f}%, Accuracy_accu: {:.2f}%'.
format(epoch + 1, num_epochs, i + 1, total_step, loss.item(), (correct / total) * 100, acc_accuracy))
 
Epoch [1/1], Step [10/600], Loss: 0.0711, Accuracy: 97.00%, Accuracy_accu: 96.90%
Epoch [1/1], Step [20/600], Loss: 0.3579, Accuracy: 94.00%, Accuracy_accu: 96.80%
 

 

댓글