now is better than never

[딥러닝] 4. 이미지 분류 (MNIST) 본문

머신러닝 & 딥러닝

[딥러닝] 4. 이미지 분류 (MNIST)

김초송 2023. 5. 1. 14:28

MNIST

  • 숫자 0 ~ 9 까지의 이미지로 구성
  • 훈련 데이터가 6만 장, 테스트 데이터가 1만 장
  • 28x28 크기의 회색조 이미지(1채널)
  • 각 픽셀은 0~255 까지의 값
from tensorflow.keras.datasets.mnist import load_data

(x_train, y_train), (x_test, y_test) = load_data('mnist.npz')
print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)

# 차원 축소 (3 -> 2)
x_train = x_train.reshape(x_train.shape[0], -1)
x_test = x_test.reshape(x_test.shape[0], -1)
print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)

# 최대 최소 정규화
x_train = x_train / 255 
x_test = x_test / 255

from tensorflow.keras.utils import to_categorical

# one-hot encoding (정답(y))
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

원핫인코딩 (one-hot encoding)

  • 정답만 1 나머지는 0 으로
  • tensorflow 에서 to_categorical 사용

 

import tensorflow as tf
import numpy as np
from tensorflow.keras.models import Sequential # 신경망 모델 구성
from tensorflow.keras.layers import Dense # 완전 연결계층
from tensorflow.keras.optimizers import SGD, Adam # 경사하강법
from tensorflow.keras.losses import mse # 오차함수
tf.random.set_seed(777)

model = Sequential()

# 다층 퍼셉트론 (뉴런이 많으면 오래걸리고 적으면 정확도 낮음)
model.add(Dense(100, input_shape=(784, ), activation='relu')) # 은닉 1층
model.add(Dense(50, activation='relu')) # 은닉 2층
model.add(Dense(10, activation='softmax')) # 출력층 (출력층 뉴런수 = 분류 종류수)

model.compile(optimizer=Adam(), loss=mse, metrics=['acc'])

model.fit(x_train, y_train, batch_size=100, epochs=500)

# 모델 저장
model.save("C:/Users/user/python/model/MNIST.h5")

from tensorflow.keras.models import load_model
model = load_model("C:/Users/user/python/model/MNIST.h5")
result = model.predict(x_test[6].reshape(1, 784))

# one-hot 을 index 로
np.argmax(result) # 가장 큰 원소의 인덱스값 출력
  • metrics : epoch 마다 정확도 출력
  • batch_size : 한 번에 100장 씩 학습
# 시각화
import matplotlib.pyplot as plt
img = x_test[6].reshape(28, 28)
plt.figure()
plt.imshow(img, cmap='gray')

 

내 손글씨로 테스트

# 이미지 전처리
import torchvision.transforms as transforms

img_size = (28, 28)
img_path = 'C:/Data/1.png'

img = cv2.imread(img_path)
img = cv2.bitwise_not(img) # 색 반전

T = transforms.Compose([transforms.ToPILImage(), # pillow 형태로 변환
                        transforms.Grayscale(1), # 흑백 처리
                        transforms.Resize(img_size),
                        transforms.ToTensor()]) # 다차원 배열

img_input = T(img)
x_my = np.array(img_input)
x_my = x_my.reshape(-1, 784)

result = model.predict(x_my)
np.argmax(result)