MNIST Datebase (Modified National Institute of Standards and Technology)
- 손으로 쓴 숫자들로 이루어진 대형 데이터베이스
- Train dataset 60,000개, Test dataset 10,000개로 구성됨
1. Single Layer Perceptron (SLP) 실습
목표 : MNIST 손글씨 데이터를 분류하는 single layer(단층) perceptron 모델 학습
입력 : 손글씨 이미지 (28x28x1)
출력 : 0~9까지 숫자들의 정답 확률
▼ 패키지 선언
import torch
import torch.nn as nn
import torchvision.datasets as dataset
import torchvision.transforms as transform
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
print(len(mnist_train)) # training dataset 개수 확인
first_data = mnist_train[0]
print(first_data[0].shape) # 첫번째 data의 형상 확인print(first_data[1]) # 첫번째 data의 정답 확인
plt.imshow(first_data[0][0,:,:], cmap='gray') # 이미지를 시각화
plt.show()
60000 torch.Size([1, 28, 28]) 5
※ 참고 _ MNIST 데이터셋 형상
Image : 28x28 (pixels)
MNIST "train" dataset 과 MNIST "test" dataset
MNIST 데이터셋의 perceptron 입력 방법
- Perceptron의 각 노드는 한 번에 한 개의 값을 입력받을 수 있다
- 따라서 2D 형태의 이미지 전처리가 필요하다 → 평탄화
▼ 평탄화 확인
first_img = first_data[0]
print(first_img.shape)
first_img = first_img.view(-1, 28*28) # 이미지 평탄화 수행 2D -> 1Dprint(first_img.shape)
torch.Size([1, 28, 28]) torch.Size([1, 784])
● MNIST 이미지는 28x28 픽셀의 2D 배열로 표현된다. (이미지 데이터는 보통 2D 형태로 표현된다.) ● 일부 신경망 모델은 1D 벡터 형태의 입력을 기대할 수 있다. ● 따라서 원래 2D 이미지를 1D로 평탄화하는 역할을 수행한다 → view(-1, 28*28) ● 이렇게 평탄화된 1D 벡터는 주로 이미지의 모든 픽셀 값을 포함하고 신경망의 입력으로 사용되어 이미지의 구조적 특징을 보존하면서도 효과적으로 처리될 수 있다
▼ Single Layer Perceptron 모델 정의
classSLP(nn.Module):def__init__(self):
super(SLP, self).__init__()
# SLP의 입력은 784개, 출력은 10개self.fc = nn.Linear(in_features=784, out_features=10)
defforward(self, x):
x = x.view(-1, 28*28) #이미지 평탄화
y = self.fc(x)
return y
Pytorch에서 구현하는 모델은 반드시 2가지 함수를 선언해야 한다.
__init__() 함수 에 포함해야 하는 정보
- Parameter를 가지는 layer 정보 (Fully connected layer, Convolutional layer 등)
✓ Batch size : 100 (한번에 학습할 데이터의 개수) ✓ Learning rate : 0.1 (가중치를 얼마나 변경시킬지 정하는 상수) ✓ Epoch : 15 (1 Epoch: 전체 데이터셋에 대해 1회 학습) ✓ Loss function : Cross entropy error (학습 모델이 얼마나 잘못 예측하고 있는지는 표현하는 지표)
※ 참고 : torch.nn.CrossEntropyLoss()함수
1. 예측 값들에 대해서 자동으로 softmax 적용
2. 정답 값과 예측 값을 이용해서 cross entropy loss 측정
✓ Optimizer: SGD (Loss function을 최소로 만들기 위한 가중치, 편향을 찾는 알고리즘)
✓ Batch 단위의 학습을 위해서 data_loader 함수 사용
▼ Perceptron 학습을 위한 반복문 선언
network.train()
for epoch in range(training_epochs): # 전체 데이터에 대한 반복 : epoch
avg_cost = 0
total_batch = len(data_loader)
for img, label in data_loader: # 1 epoch 내의 1 batch에 대한 반복 : iteration
pred = network(img) → 1. 입력 이미지에 대해서 forward pass
loss = loss_function(pred, label) → 2. 예측 값, 정답 값을 이용해 loss 계산
optimizer.zero_grad() # gradient 초기화
loss.backward() → 3. 모든 weight에 대해 편미분 값 계산
optimizer.step() → 4. 파라미터 업데이트
avg_cost += loss / total_batch # 모든 batch에 대한 평균 loss값 계산print('Epoch: %d Loss = %f'%(epoch+1, avg_cost))
print('Learning finished')
Epoch: 1 Loss = 0.535026 Epoch: 2 Loss = 0.358744 Epoch: 3 Loss = 0.330988 Epoch: 4 Loss = 0.316194 Epoch: 5 Loss = 0.306888 Epoch: 6 Loss = 0.300198 Epoch: 7 Loss = 0.294928 Epoch: 8 Loss = 0.290794 Epoch: 9 Loss = 0.287432 Epoch: 10 Loss = 0.284395 Epoch: 11 Loss = 0.281804 Epoch: 12 Loss = 0.279809 Epoch: 13 Loss = 0.277766 Epoch: 14 Loss = 0.275743 Epoch: 15 Loss = 0.274424 Learning finished
▼ 학습이 완료된 모델을 이용해 정답률 확인
network.eval()
img_test = mnist_test.data.float()
label_test = mnist_test.targets
with torch.no_grad(): # test에서는 기울기 계산 제외
prediction = network(img_test) # 전체 test data를 한번에 계산
correct_prediction = torch.argmax(prediction, 1) == label_test # 예측 값이 가장 높은 숫자(0~9)와 정답 데이터가 일치한지 확인
accuracy = correct_prediction.float().mean()
print('Accuracy:', accuracy.item())
Accuracy: 0.8894000053405762
▼ 예측 결과 확인
first_data = mnist_test.data[0] # Test dataset 중 첫 번째 Image에 대해 예측 값 확인
with torch.no_grad():
prediction = network(first_data.float())
prediction_num = torch.argmax(prediction, 1)
print(prediction)
print(prediction_num)
plt.imshow(first_data, cmap="gray")
plt.show
목표 : MNIST 손글씨 데이터를 분류하는 multi layer(단층) perceptron 모델 학습
입력 : 손글씨 이미지 (28x28x1)
출력 : 0~9까지 숫자들의 정답 확률
▼ 패키지 선언 (SLP 와 동일)
import torch
import torch.nn as nn
import torchvision.datasets as dataset
import torchvision.transforms as transform
from torch.utils.data import DataLoader
✓ Batch size : 100(한번에 학습할 데이터의 개수) ✓ Learning rate : 0.1(가중치를 얼마나 변경시킬지 정하는 상수) ✓ Epoch : 15(1 Epoch: 전체 데이터셋에 대해 1회 학습) ✓ Loss function : Cross entropy error(학습 모델이 얼마나 잘못 예측하고 있는지는 표현하는 지표)
※ 참고 : torch.nn.CrossEntropyLoss()함수
1. 예측 값들에 대해서 자동으로 softmax 적용
2. 정답 값과 예측 값을 이용해서 cross entropy loss 측정
✓ Optimizer: SGD(Loss function을 최소로 만들기 위한 가중치, 편향을 찾는 알고리즘)
✓ Batch 단위의 학습을 위해서 data_loader 함수 사용
▼ Perceptron 학습을 위한 반복문 선언 (SLP 와 동일)
network.train()
for epoch in range(training_epochs): # 전체 데이터에 대한 반복 : epoch
avg_cost = 0
total_batch = len(data_loader)
for img, label in data_loader: # 1 epoch 내의 1 batch에 대한 반복 : iteration
pred = network(img) → 1. 입력 이미지에 대해서 forward pass
loss = loss_function(pred, label) → 2. 예측 값, 정답 값을 이용해 loss 계산
optimizer.zero_grad() # gradient 초기화
loss.backward() → 3. 모든 weight에 대해 편미분 값 계산
optimizer.step() → 4. 파라미터 업데이트
avg_cost += loss / total_batch # 모든 batch에 대한 평균 loss값 계산print('Epoch: %d Loss = %f'%(epoch+1, avg_cost))
print('Learning finished')
Epoch: 1 Loss = 1.154235 Epoch: 2 Loss = 0.450059 Epoch: 3 Loss = 0.360999 Epoch: 4 Loss = 0.324635 Epoch: 5 Loss = 0.302197 Epoch: 6 Loss = 0.285472 Epoch: 7 Loss = 0.271260 Epoch: 8 Loss = 0.258964 Epoch: 9 Loss = 0.247979 Epoch: 10 Loss = 0.237658 Epoch: 11 Loss = 0.228358 Epoch: 12 Loss = 0.219735 Epoch: 13 Loss = 0.211678 Epoch: 14 Loss = 0.204083 Epoch: 15 Loss = 0.196845 Learning finished
▼ 학습이 완료된 모델을 이용해 정답률 확인 (SLP 와 동일)
network.eval()
img_test = mnist_test.data.float()
label_test = mnist_test.targets
with torch.no_grad(): # test에서는 기울기 계산 제외
prediction = network(img_test) # 전체 test data를 한번에 계산
correct_prediction = torch.argmax(prediction, 1) == label_test # 예측 값이 가장 높은 숫자(0~9)와 정답 데이터가 일치한지 확인
accuracy = correct_prediction.float().mean()
print('Accuracy:', accuracy.item())
Accuracy: 0.9406999945640564
▼ 예측 결과 확인 (SLP 와 동일)
first_data = mnist_test.data[0] # Test dataset 중 첫 번째 Image에 대해 예측 값 확인with torch.no_grad():
prediction = network(first_data.float())
prediction_num = torch.argmax(prediction, 1)
print(prediction)
print(prediction_num)
plt.imshow(first_data, cmap="gray")
plt.show