Data_Analysis_Track_33/Python
Python_Deeplearning_pytorch_07(CNN_Model 정의)
lsc99
2023. 10. 30. 18:32
1. Convolutional Neural Network 모델 정의
import 및 device 설정
import torch
import torch.nn as nn
device = "cuda" if torch.cuda.is_available() else "cpu"
print(device)
layer = nn.Conv2d(in_channels=4, #입력 데이터의 channel 수
out_channels=2, #filter(kernel) 수
kernel_size=3, #filter 크기(3:h, 3:w)
# stride=1, # 이동크기 => 좌우, 상하 1칸씩 이동하면서 계산.
# padding=0 # 패딩 크기
# padding="same"
)
print(layer)
input_data = torch.ones(1, 4, 3, 3) # (데이터개수, channel, height, width)
feature_map = layer(input_data)
print(feature_map.shape)
# [1:데이터개수 , 2:out_channels, 1:height, 1:width]
feature_map
# 파라미터 weight
weight = layer.weight # conv2d의 weight 조회 => filter 조회
weight.shape
# [2:필터개수, 4:필터채널개수, 3:필터height, 3:필터width]
# 파라미터 bias
bias = layer.bias
bias.shape #[2:필터개수]
bias
첫번째 필터 계산
# 첫번째 필터 계산.
input_data[0].shape, weight[0].shape
ch1 = torch.sum(input_data[0, 0] * weight[0, 0]) #[0: 첫번째 필터, 0: 첫번째 채널]
ch2 = torch.sum(input_data[0, 1] * weight[0, 1]) #[0: 첫번째 필터, 1: 두번째 채널]
ch3 = torch.sum(input_data[0, 2] * weight[0, 2])
ch4 = torch.sum(input_data[0, 3] * weight[0, 3])
result = ch1 + ch2 + ch3 + ch4 + bias[0]
result
ch1 = torch.sum(input_data[0, 0] * weight[1, 0]) #[0: 첫번째 필터, 0: 첫번째 채널]
ch2 = torch.sum(input_data[0, 1] * weight[1, 1]) #[0: 첫번째 필터, 1: 두번째 채널]
ch3 = torch.sum(input_data[0, 2] * weight[1, 2])
ch4 = torch.sum(input_data[0, 3] * weight[1, 3])
result = ch1 + ch2 + ch3 + ch4 + bias[1]
result
p_layer = nn.MaxPool2d(kernel_size=2, # 최대값을 추출할 영역 크기
stride=2 # 이동 size => kernel_size와 stride는 같은 값은 값을 지정해서 영역이 겹치지 않도록 한다.
)
input_data2 = torch.rand(1, 4, 4)
input_data2
result2 = p_layer(input_data2)
print(result2.shape)
result2
p_layer = nn.MaxPool2d(kernel_size=2, stride=2
, padding=1)
# kernel_size보다 작은 영역에서는 최대값을 추출하지 않는다. =>
# padding을 지정해서 zero_padding을 추가해서 작은영역에서도 추출 될 수 있도록 한다.
input_data3 = torch.rand(1, 5, 5)
input_data3
result3 = p_layer(input_data3)
print(input_data3)
result3
2. MNIST
import
import os
import torch
from torch import nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import models, datasets, transforms
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
device = "cuda" if torch.cuda.is_available() else "cpu"
하이퍼파라미터
# 하이퍼파라미터
N_EPOCH = 1
BATCH_SIZE = 256
LR = 0.001
2.1 Data 준비
MNIST
# MNIST
train_loader = load_mnist_dataset("datasets", BATCH_SIZE, True) #저장경로, batch크기, Tainset여부
test_loader = load_mnist_dataset("datasets", BATCH_SIZE, False)
Fashion MNIST
# Fashion MNIST
train_loader = load_fashion_mnist_dataset("datasets", BATCH_SIZE, True) #저장경로, batch크기, Tainset여부
test_loader = load_fashion_mnist_dataset("datasets", BATCH_SIZE, False)
train_loader.dataset
test_loader.dataset
2.2 CNN 모델 정의
# CNN -> Convolution Layer: fitlter 개수(out_channels로 설정) 뒤로 갈수록 크게 잡는다.
# Max Pooling Layer를 이용해서 출력 결과(Feature map)의
# size(height, width) 는 줄여나간다. (보통 절반씩 줄인다.)
# conv block
## 1. Conv + ReLU + MaxPooling
## 2. Conv + BatchNorm + ReLU + MaxPooling
## 3. Conv + BatchNorm + ReLU + Dropout + MaxPooling
class MNISTCNNModel(nn.Module):
def __init__(self):
super().__init__()
self.b1 = nn.Sequential(
# Conv2d(): 3 X 3 필터, stide=1, padding=1 => same padding(입력 size와 출력 size가 동일)
nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(32), # channel을 기준을 정규화 -> 입력 channel수 지정.
nn.ReLU(),
nn.Dropout2d(p=0.3),
nn.MaxPool2d(kernel_size=2, stride=2)
# kernel_size와 stride가 같은 경우에는 stride를 생략가능
# MaxPool2d() 에서도 padding 지정.
)
self.b2 = nn.Sequential(
nn.Conv2d(32, 64, kernel_size=3, padding="same"),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.Dropout2d(p=0.3),
nn.MaxPool2d(kernel_size=2)
)
self.b3 = nn.Sequential(
nn.Conv2d(64, 128, kernel_size=3, padding="same"),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.Dropout2d(p=0.3),
nn.MaxPool2d(kernel_size=2, padding=1) # 입력: 7 x 7 => 1/2 줄이면 -> 3.5 -> 0.5를 살리기 위해 padding 지정
)
# 결과출력레이어 => Linear() 사용.
self.output_block = nn.Sequential(
# MaxPool2d() 출력결과 입력으로 받는다. => 4차원 (batch, ch, h, w)
# 3차원 -> 1차원
nn.Flatten(),
nn.Linear(in_features=128*4*4, out_features=512),
nn.ReLU(),
nn.Dropout(p=0.3),
nn.Linear(512, 10) # out=>클래스 개수
)
def forward(self, X):
out = self.b1(X)
out = self.b2(out)
out = self.b3(out)
out = self.output_block(out)
return out
모델 생성 및 summary
model = MNISTCNNModel()
summary(model, (1, 1, 28, 28))
2.3 Train
MNIST
# MNIST
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=LR)
result = fit(train_loader, test_loader, model, loss_fn, optimizer, N_EPOCH,
save_best_model=False, early_stopping=True, device=device,
mode="multi")
Fashion MNIST
# Fashion MNIST
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=LR)
result = fit(train_loader, test_loader, model, loss_fn, optimizer, N_EPOCH,
save_best_model=False, early_stopping=True, device=device,
mode="multi")