합성곱 신경망은 합성곱 층을 부르는 단위가 통합이 되어있지는 않습니다.
합성곱(nn.Conv2d) + 활성화 함수(nn.ReLU)를 하나의 합성곱 층으로 보고 최대 풀링(nn.MaxPool2d)은 풀링 층으로 별도로 명명합니다.
합성곱(nn.Conv2d) + 활성화 함수(nn.ReLU) + 최대 풀링(nn.MaxPool2d)을 하나의 합성곱 층으로 봅니다.
풀링도 하나의 층으로 보느냐 아니냐에 따라서 표기 방법에 달라지는데 편의를 위해서 최대 풀링까지 포함해 하나의 합성곱 층으로 판단하고 정리하겠습니다.
MNIST 분류를 하기 전에 기본적인 모델 구조를 구현하겠습니다.
import torch
import torch.nn as nn
#배치크기 x 채널 x 높이 x 너비
inputs = torch.Tensor(1, 1, 28, 28)
#입력채널 1, 출력채널 32, 필터크기 3, 패딩 1
conv1 = nn.Conv2d(1, 32, 3, padding=1)
conv2 = nn.Conv2d(32, 64, 3, padding=1)
#인자에 정수 하나를 넣으면
#커널 사이즈와 스트라이드가 정수의 값으로 지정됩니다.
pool = nn.MaxPool2d(2)
import torch
import torchvision.datasets as datasets
import torchvision.transforms as transforms
import torch.nn.init
import torch.utils.data.DataLoader as DataLoader
device = 'cuda' if torch.cuda.is_available() else 'cpu'
#parameters
lr = 0.001
epochs = 10
batch_size = 100
mnist_train = datasets.MNIST(root='MNIST_data/', train=True, transform=transforms.ToTensor(), download=True)
mnist_test = datasets.MNINST(root='MNIST_data/', train=False, transform=transforms.ToTensor(), download=True)
data_loader = DataLoader(dataset=mnist_train, batch_size=batch_size, shuffle=True, drop_last=True)
#class로 모델 설계
class CNN(torch.nn.Module):
def __init__(self):
super(CNN, self).__init__()
#첫번째 층
self.layer1 = torch.nn.Sequential(
torch.nn.Conv2d(1, 32, 3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2))
self.layer2 = torch.nn.Sequential(
torch.nn.Conv2d(32, 64, 3, stride=21, padding=1),
torch.nn.ReLU(),
torch.nn.Maxpool2d(kernel_size=2, stride=2))
self.fc =torch.nn.Linear(7*7*64, 10, bias=True)
torch.nn.init.xavier_uniform_(self.fc.weight)
def forward(self, x):
out = self.layer(x)
out = self.layer2(out)
out = out.view(out.size(0), -1)
out = self.fc(out)
return out
model = CNN()
loss_fn = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
total_batch = len(data_loader)
for epoch in range(epochs):
avg_loss = 0
for X, Y in data_loader:
optimizer.zero_grad()
predicted = model(X)
loss = loss_fn(predicted, Y)
loss.backward()
optimizer.step()
avg_loss += loss / total_batch
print('[Epoch: {:>4}] cost = {:>.9}'.format(epoch + 1, avg_cost))
[Epoch: 1] cost = 0.224006683
[Epoch: 2] cost = 0.062186949
[Epoch: 3] cost = 0.0449030139
[Epoch: 4] cost = 0.0355709828
[Epoch: 5] cost = 0.0290450025
[Epoch: 6] cost = 0.0248527844
[Epoch: 7] cost = 0.0207189098
[Epoch: 8] cost = 0.0181982815
[Epoch: 9] cost = 0.0153046707
[Epoch: 10] cost = 0.0124179339
# 학습을 진행하지 않을 것이므로 torch.no_grad()
with torch.no_grad():
X_test = mnist_test.test_data.view(len(mnist_test), 1, 28, 28).float().to(device)
Y_test = mnist_test.test_labels.to(device)
prediction = model(X_test)
correct_prediction = torch.argmax(prediction, 1) == Y_test
accuracy = correct_prediction.float().mean()
print('Accuracy:', accuracy.item())
Accuracy: 0.9883000254631042