영상처리를 위한 Convolution Layer. 입력으로 (N, Channel, Height, Width) shape의 tensor를 받는다.
Hyper parameter
Feature Map



import os import torch from torch import nn from torchinfo import summary import matplotlib.pyplot as plt import numpy as np from module.data import load_mnist_dataset, load_fashion_mnist_dataset from module.train import fit from module.utils import plot_fit_result device = "cuda" if torch.cuda.is_available() else "cpu"### 하이퍼파라미터 선언 epochs = 1 batch_size = 256 lr = 0.001Data 준비
## Dataset->DataLoader data_path = r"C:\Classes\deeplearning\datasets" train_loader = load_mnist_dataset(data_path, batch_size) test_loader = load_mnist_dataset(data_path, batch_size, False)CNN 모델 정의
# Conv (layer) block # 1. Conv + ReLU + MaxPooling, (Conv + ReLU + Conv + ReLU +MaxPooling) # 2. Conv + BatchNorm + ReLU + MaxPooling (BatchNorm 은 Conv, Activation 사이에 정의) # 3. Conv + ReLU + Dropout + MaxPooling (Dropout activiation 다음에 정의) # 4. Conv + BatchNorm + ReLU + Dropout + MaxPooling # # CNN: filter(channel-depth) 개수는 늘리고 size(height, width)는 줄여나가도록 모델 네트워크를 구성. #### depth 늘리는 것: Convolution Layer, size 를 줄이것: Max Pooling import torch.nn as nnclass MnistCNNModel(nn.Module):def __init__(self, dropout_rate): super().__init__() # conv block 단위 생성. # Conv: kernel size- 3 x 3, stride=1(default), padding=same, MaxPooling: kernel size-2, stride=1 self.b1 = nn.Sequential( nn.Conv2d(1, 32, kernel_size=3, stride=1, padding="same"), nn.BatchNorm2d(32), # 입력 channel 수 nn.ReLU(), nn.Dropout(p=dropout_rate), nn.MaxPool2d(kernel_size=2, stride=2) ) self.b2 = nn.Sequential( nn.Conv2d(32, 64, kernel_size=3, padding="same"), # stride기본값: 1 nn.BatchNorm2d(64), nn.ReLU(), nn.Dropout(p=dropout_rate), nn.MaxPool2d(kernel_size=2, stride=2) ) self.b3 = nn.Sequential( nn.Conv2d(64, 128, kernel_size=3, padding="same"), nn.BatchNorm2d(128), nn.ReLU(), nn.Dropout(p=dropout_rate), nn.MaxPool2d(kernel_size=2, stride=2, padding=1) # input: 7 X 7 -> padding 1 ( 8 X 8) ) # # 추론기 -> Linear() self.classifier = nn.Sequential( ## conv output: 3차원, linear input: 1차원 nn.Flatten(), nn.Linear(in_features=128*4*4, out_features=256), nn.ReLU(), nn.Dropout(p=dropout_rate), nn.Linear(256, 10) # out_features=10: 정답 class 수. (0 ~ 9) )def forward(self, X): out = self.b1(X) out = self.b2(out) out = self.b3(out) out = self.classifier(out) return outcnn_mnist_model = MnistCNNModel(0.5) summary(cnn_mnist_model, (batch_size, 1, 28, 28))
Train
# 모델 생성 model = MnistCNNModel(0.3).to(device) # loss 함수 loss_fn = nn.CrossEntropyLoss() # 다중 분류 # optimizer optimizer = torch.optim.Adam(model.parameters(), lr=lr)# fit() os.makedirs('saved_models', exist_ok=True) save_path = "saved_models/mnist_cnn_model.pth" result = fit(train_loader, test_loader, model, loss_fn, optimizer, epochs, save_model_path=save_path, device=device, mode="multi")Epoch[1/10] - Train loss: 0.12209 Train Accucracy: 0.98235 || Validation Loss: 0.11540 Validation Accuracy: 0.98410
<<<<<<<저장: 1 - 이전 : inf, 현재: 0.11539805261418223
Epoch[2/10] - Train loss: 0.09952 Train Accucracy: 0.98130 || Validation Loss: 0.09316 Validation Accuracy: 0.98340
<<<<<<<저장: 2 - 이전 : 0.11539805261418223, 현재: 0.093156498670578
Epoch[3/10] - Train loss: 0.11717 Train Accucracy: 0.97543 || Validation Loss: 0.11376 Validation Accuracy: 0.97600
Epoch[4/10] - Train loss: 0.06415 Train Accucracy: 0.98817 || Validation Loss: 0.06278 Validation Accuracy: 0.98810
<<<<<<<저장: 4 - 이전 : 0.093156498670578, 현재: 0.0627757616341114
Epoch[5/10] - Train loss: 0.10670 Train Accucracy: 0.97413 || Validation Loss: 0.10420 Validation Accuracy: 0.97380
Epoch[6/10] - Train loss: 0.07991 Train Accucracy: 0.98752 || Validation Loss: 0.08260 Validation Accuracy: 0.98470
Epoch[7/10] - Train loss: 0.05045 Train Accucracy: 0.99042 || Validation Loss: 0.05138 Validation Accuracy: 0.99090
<<<<<<<저장: 7 - 이전 : 0.0627757616341114, 현재: 0.05137930030468851
Epoch[8/10] - Train loss: 0.04340 Train Accucracy: 0.99130 || Validation Loss: 0.04542 Validation Accuracy: 0.98980
<<<<<<<저장: 8 - 이전 : 0.05137930030468851, 현재: 0.04541729437187314
Epoch[9/10] - Train loss: 0.06679 Train Accucracy: 0.98468 || Validation Loss: 0.06880 Validation Accuracy: 0.98190
Epoch[10/10] - Train loss: 0.06055 Train Accucracy: 0.98662 || Validation Loss: 0.06228 Validation Accuracy: 0.98540
164.44112515449524 초plot_fit_result(*result)
colab에서 학습한 모델을 이용해서 검증 및 추론
import torch import torch.nn as nn from torchvision import transforms from module.data import load_mnist_dataset from module.train import test_multi_classification device = 'cuda' if torch.cuda.is_available() else 'cpu'# 모델 loading cnn_model = torch.load('saved_models/mnist_cnn_model.pth', map_location=torch.device('cpu')) # cuda 에서 학습 모델을 cpu에서 사용하도록 설정 cnn_model = cnn_model.to(device) cnn_modelMnistCNNModel(
(b1): Sequential(
(0): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1), padding=same)
(1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU()
(3): Dropout(p=0.3, inplace=False)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(b2): Sequential(
(0): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=same)
(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU()
(3): Dropout(p=0.3, inplace=False)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(b3): Sequential(
(0): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=same)
(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(2): ReLU()
(3): Dropout(p=0.3, inplace=False)
(4): MaxPool2d(kernel_size=2, stride=2, padding=1, dilation=1, ceil_mode=False)
)
(classifier): Sequential(
(0): Flatten(start_dim=1, end_dim=-1)
(1): Linear(in_features=2048, out_features=256, bias=True)
(2): ReLU()
(3): Dropout(p=0.3, inplace=False)
(4): Linear(in_features=256, out_features=10, bias=True)
)
)### test set loading 후 모델 평가 test_loader = load_mnist_dataset(r"C:\Classes\deeplearning\datasets", batch_size=256, is_train=False) loss, acc = test_multi_classification(test_loader, cnn_model, nn.CrossEntropyLoss(), "cpu") print(f"Loss: {loss}, Accuracy: {acc}")Loss: 0.13318236041814088, Accuracy: 0.9857