MNIST 손글씨 숫자 예측¶
In [58]:
다음과 같은 ANN 을 만든다¶
이미지파일(28X28픽셀)이 입력으로 들어오면, 아웃풋으로는 0~9 까지의 10개 숫자로 분류하는 인공지능!
사진은 2차원 데이터이므로, 우리는 ANN의 입력에, 사진의 픽셀값을 flattening 하여 입력을 줄 것이다.
따라서 입력레이어는 784개, 히든1은 512, 히든2는 512, 아웃풋은 10개의 신경망 구축.
In [58]:
In [58]:
In [59]:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from PIL import Image
%matplotlib inline
In [60]:
import tensorflow as tf
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import Adam
from keras.utils import to_categorical
In [61]:
# MNist 데이터를 가져온다. 이미 7만장의 손글씨 이미지 데이터가 있다.
In [62]:
(X_train, y_train), (X_test, y_test) = mnist.load_data()
In [63]:
# 데이터 모양 확인
In [64]:
X_train.shape
Out[64]:
(60000, 28, 28)
In [65]:
X_test.shape
Out[65]:
(10000, 28, 28)
In [66]:
y_train.shape
Out[66]:
(60000,)
In [67]:
y_test.shape
Out[67]:
(10000,)
In [68]:
# 이미지 데이터 1개를 가져와서, 화면에 찍어보자.
In [69]:
X_train[0]
Out[69]:
array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 18, 18, 18, 126, 136, 175, 26, 166, 255, 247, 127, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 30, 36, 94, 154, 170, 253, 253, 253, 253, 253, 225, 172, 253, 242, 195, 64, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 49, 238, 253, 253, 253, 253, 253, 253, 253, 253, 251, 93, 82, 82, 56, 39, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 18, 219, 253, 253, 253, 253, 253, 198, 182, 247, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 80, 156, 107, 253, 253, 205, 11, 0, 43, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 1, 154, 253, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 253, 190, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 190, 253, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 241, 225, 160, 108, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 240, 253, 253, 119, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 186, 253, 253, 150, 27, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 93, 252, 253, 187, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 253, 249, 64, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 130, 183, 253, 253, 207, 2, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 148, 229, 253, 253, 253, 250, 182, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 114, 221, 253, 253, 253, 253, 201, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 23, 66, 213, 253, 253, 253, 253, 198, 81, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 18, 171, 219, 253, 253, 253, 253, 195, 80, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 55, 172, 226, 253, 253, 253, 253, 244, 133, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 136, 253, 253, 253, 212, 135, 132, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
In [70]:
plt.imshow(X_train[0], cmap= 'gray')
plt.show()
In [71]:
y_train[0]
Out[71]:
5
In [72]:
# 이미지는 가로, 세로가 있고, 이 안에 숫자 0~255까지 숫자로 채워진 데이터다.
In [72]:
In [73]:
# 실제 이미지 파일을 표시.
In [73]:
In [74]:
# 1. 데이터를 딥러닝으로 처리하기 위해서, 행렬로 만들면서, 가로세로 값을 일렬로 만든다.
In [75]:
X_train = X_train.reshape(60000, 28*28)
In [76]:
X_test = X_test.reshape(10000, 28*28)
In [76]:
In [77]:
# 2. 데이터를 딥러닝에서 처리할 수 있도록 float로 바꿔준다.
In [78]:
X_train = X_train.astype(float)
In [79]:
X_test = X_test.astype(float)
In [79]:
In [80]:
# 3. 이미지라서, 숫자가 0~255 이므로, 0~1 사이로 정규화 시켜주자.
In [89]:
X_train = X_train / 255.0
In [90]:
X_test = X_test / 255.0
In [83]:
# 4. 분류의 문제이므로, y값을 확인하여, 카테고리컬 데이터를 원핫인코딩값으로 바꾼다.
In [91]:
y_train
Out[91]:
array([5, 0, 4, ..., 5, 6, 8], dtype=uint8)
In [92]:
# 넘파이의 레이블 인코딩된 값을, 원핫 인코딩으로 바꾸는 방법!
# 텐서플로우가 제공한다!!!
In [94]:
y_train = tf.keras.utils.to_categorical(y_train, num_classes = 10)
In [95]:
y_train
Out[95]:
array([[0., 0., 0., ..., 0., 0., 0.], [1., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 1., 0.]], dtype=float32)
In [96]:
y_test = tf.keras.utils.to_categorical(y_test, num_classes = 10)
In [97]:
y_test
Out[97]:
array([[0., 0., 0., ..., 1., 0., 0.], [0., 0., 1., ..., 0., 0., 0.], [0., 1., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32)
In [98]:
y_train.shape
Out[98]:
(60000, 10)
In [99]:
y_test.shape
Out[99]:
(10000, 10)
In [101]:
plt.imshow(X_train[0].reshape(28,28))
plt.show()
In [102]:
y_train[0]
Out[102]:
array([0., 0., 0., 0., 0., 1., 0., 0., 0., 0.], dtype=float32)
In [85]:
# 5. 모델 만들기
In [104]:
def build_model() :
model = Sequential()
model.add( Dense(512, 'relu', input_shape=(784, )))
model.add( Dropout(0.4))
model.add( Dense(10, 'softmax'))
model.compile('adam', loss='categorical_crossentropy', metrics=['accuracy']) # 원핫인코딩을 직접 해주었기 때문에 sparse를 제외한다.
return model
In [105]:
model = build_model()
In [106]:
epoch_history = model.fit(X_train, y_train, epochs=5, validation_data= (X_test,y_test) )
Epoch 1/5 1875/1875 [==============================] - 9s 4ms/step - loss: 0.2466 - accuracy: 0.9267 - val_loss: 0.1067 - val_accuracy: 0.9675 Epoch 2/5 1875/1875 [==============================] - 8s 4ms/step - loss: 0.1194 - accuracy: 0.9637 - val_loss: 0.0886 - val_accuracy: 0.9721 Epoch 3/5 1875/1875 [==============================] - 8s 4ms/step - loss: 0.0915 - accuracy: 0.9712 - val_loss: 0.0691 - val_accuracy: 0.9787 Epoch 4/5 1875/1875 [==============================] - 8s 4ms/step - loss: 0.0769 - accuracy: 0.9759 - val_loss: 0.0618 - val_accuracy: 0.9809 Epoch 5/5 1875/1875 [==============================] - 8s 4ms/step - loss: 0.0636 - accuracy: 0.9789 - val_loss: 0.0692 - val_accuracy: 0.9789
In [85]:
In [86]:
# 5. 컴파일
In [86]:
In [86]:
In [87]:
# 6. 학습
In [87]:
In [87]:
In [88]:
# 7. 모델 평가.
In [107]:
model.evaluate(X_test, y_test)
313/313 [==============================] - 1s 4ms/step - loss: 0.0692 - accuracy: 0.9789
Out[107]:
[0.06922364234924316, 0.9789000153541565]
In [108]:
from sklearn.metrics import confusion_matrix
In [109]:
y_test
Out[109]:
array([[0., 0., 0., ..., 1., 0., 0.], [0., 0., 1., ..., 0., 0., 0.], [0., 1., 0., ..., 0., 0., 0.], ..., [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.], [0., 0., 0., ..., 0., 0., 0.]], dtype=float32)
In [110]:
y_pred = model.predict(X_test)
313/313 [==============================] - 1s 3ms/step
In [111]:
y_pred
Out[111]:
array([[1.4162736e-08, 2.8566420e-09, 3.3658864e-07, ..., 9.9999171e-01, 3.6670287e-09, 1.6145473e-06], [3.2866534e-10, 7.0322676e-06, 9.9999267e-01, ..., 8.5267507e-14, 1.8275100e-09, 8.1794092e-15], [1.9671109e-09, 9.9995953e-01, 4.6451614e-06, ..., 2.3026543e-05, 1.1550460e-05, 4.2384027e-08], ..., [1.2443285e-13, 4.4002441e-12, 2.7011916e-13, ..., 5.7719120e-08, 1.0429911e-08, 2.3091688e-06], [2.5430101e-08, 1.6531608e-10, 5.9343253e-11, ..., 4.1160360e-09, 4.4811331e-06, 6.7273162e-12], [3.1477523e-09, 5.8081496e-13, 8.8750625e-08, ..., 6.4088869e-12, 4.0916509e-10, 1.0882610e-10]], dtype=float32)
In [113]:
y_test = y_test.argmax(axis=1)
In [114]:
y_pred = y_pred.argmax(axis=1)
In [116]:
y_test
Out[116]:
array([7, 2, 1, ..., 4, 5, 6])
In [117]:
y_pred
Out[117]:
array([7, 2, 1, ..., 4, 5, 6])
In [118]:
cm= confusion_matrix(y_test, y_pred)
In [119]:
cm
Out[119]:
array([[ 971, 1, 1, 1, 1, 0, 2, 1, 2, 0], [ 0, 1125, 3, 1, 0, 1, 1, 0, 4, 0], [ 4, 0, 1014, 3, 2, 0, 1, 4, 4, 0], [ 0, 0, 1, 1002, 0, 1, 0, 3, 3, 0], [ 1, 1, 4, 0, 964, 0, 3, 0, 1, 8], [ 2, 1, 0, 26, 2, 846, 5, 2, 6, 2], [ 6, 3, 0, 1, 7, 3, 938, 0, 0, 0], [ 2, 6, 9, 3, 0, 0, 0, 1002, 1, 5], [ 1, 0, 6, 8, 3, 2, 2, 3, 947, 2], [ 1, 4, 1, 7, 6, 0, 1, 7, 2, 980]])
In [120]:
import seaborn as sb
In [122]:
sb.heatmap(cm, annot=True, fmt='.0f', cmap='RdPu')
plt.show()
In [ ]: