MNIST 간단한 CNN 구현 및 정리
모두의 딥러닝 시즌2 - Pytorch를 참고 했습니다.
모두의 딥러닝 시즌2 깃헙
import torch
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import torch.nn.init
- pytorch import
device = 'cuda' if torch.cuda.is_available() else 'cpu'
torch.manual_seed(777)
if device == 'cuda':
torch.cuda.manual_seed_all(123)
- device 설정(GPU or CPU)
learning_rate = 0.001
training_epochs = 15
batch_size = 100
- parameter 설정(learning rate, training epochs, batch size)
mnist_train = dsets.MNIST(root = 'MNIST_data/',
train=True,
transform=transforms.ToTensor(),
download=True)
mnist_test = dsets.MNIST(root='MNIST_data/',
train=False,
transform=transforms.ToTensor(),
download=True)
- mnist import
transforms.ToTensor() -> pytorch에서 다룰 수 있는 tensor의 형태로 불러온다
data_loader = torch.utils.data.DataLoader(dataset=mnist_train,
batch_size=batch_size,
shuffle=True,
drop_last=True)
- DataLoader로 mnist_train 데이터를 미니배치 단위로 처리할 수 있고,
- shuffle함으로서 학습의 효율성을 향상
- drop_last=True -> 데이터를 배치 사이즈로 나누었을 때, 나머지를 버림
class CNN(torch.nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.layer1 = torch.nn.Sequential(
torch.nn.Conv2d(1, 32, kernel_size=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, kernel_size=3, stride=1, 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):
# print(x.size())
out = self.layer1(x)
# print(out.size())
out = self.layer2(out)
# print(out.size())
out = out.view(out.size(0), -1)
# print(out.size())
out = self.fc(out)
# print(out.size())
return out
- CNN 모델에서의 처리 과정은 다음과 같다. [batch_size, number_of_kernels, w, h]
- shape를 print 함으로서 확인할 수 있다.
[100, 28, 28, 1] -> layer1 -> [100, 14,14,32] -> layer2 -> [100, 7, 7, 64] -> view(펼치기) -> [100, 3136] -> fc -> [100, 10]
model
CNN(
(layer1): Sequential(
(0): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(layer2): Sequential(
(0): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(fc): Linear(in_features=3136, out_features=10, bias=True)
)
풀어서 표현하면 위와 같다
model = CNN().to(device)
CNN 모델을 device에 넣어줌
criterion = torch.nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
- cost/loss 설정(크로스엔트로피)
cross-entropy loss : 신경망의 출력이 0~1 사이로 나오는 경우 loss 함수로 사용할 수 있다.- optimizer 설정(adam optimizer)
total_batch = len(data_loader)
# total_batch
for epoch in range(training_epochs):
avg_cost = 0
for X, Y in data_loader:
X = X.to(device)
Y = Y.to(device)
optimizer.zero_grad()
hypothesis = model(X)
cost = criterion(hypothesis, Y)
cost.backward()
optimizer.step()
avg_cost += cost / total_batch
print('[Epoch: {:>4}] cost = {:>.9}'.format(epoch + 1, avg_cost))
[Epoch: 1] cost = 0.231875896
[Epoch: 2] cost = 0.0620613769
[Epoch: 3] cost = 0.0451710336
[Epoch: 4] cost = 0.0371446609
[Epoch: 5] cost = 0.0305327885
[Epoch: 6] cost = 0.0256100874
[Epoch: 7] cost = 0.021398209
[Epoch: 8] cost = 0.0179504156
[Epoch: 9] cost = 0.0161231514
[Epoch: 10] cost = 0.013235067
[Epoch: 11] cost = 0.0123889502
[Epoch: 12] cost = 0.0102491155
[Epoch: 13] cost = 0.00809138734
[Epoch: 14] cost = 0.0077691027
[Epoch: 15] cost = 0.00681020087
{ } 안의 :>4는 4자리 오른쪽 정렬, :>.9는 소숫점 9자리 오른쪽정렬 이라는 뜻이다.
print(len(mnist_train))
print(batch_size)
print(total_batch)
print(len(mnist_test))
60000
100
600
10000
- 6만개의 training data와 1만개의 test data
- batch size 100으로 600개의 batch를 만들어 training
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)
print(prediction.size())
correct_prediction = torch.argmax(prediction, 1) == Y_test
accuracy = correct_prediction.float().mean()
print('Accuracy: ', accuracy.item())
torch.Size([10000, 10])
Accuracy: 0.9882999658584595
- test 시에는 gradient가 필요 없으믈 torch.no_grad()로 감싸줌
- batch 없이 1만개의 데이터 한번에 test
- 마찬가지로 to(device)
- prediction size [10000, 10]에 대해 argmax (axis = 1)
- 모든 test 결과에 대해 평균 .mean(), 값만 빼옴 .item()
torch.Size([10000, 10])
Accuracy: 0.9882999658584595
'프로그래머 > Pytorch' 카테고리의 다른 글
[Pytorch] 기초 강의 day1 (0) | 2020.06.15 |
---|---|
[Pytorch] VGG CIFAR-10에 적용 및 정리 (2) | 2020.06.07 |
[Pytorch] VGG 구현 및 정리 (2) | 2020.06.07 |
[Pytorch tutorial] Autograd: 자동미분 (0) | 2020.06.04 |
[Pytorch tutorial] PyTorch가 무엇인가요? (0) | 2020.06.04 |