Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

에코프로.AI

[Tensorflow] mnist 데이터셋 손글씨 예측 모델링(Feat. DNN 모델) 본문

AI Tutorial

[Tensorflow] mnist 데이터셋 손글씨 예측 모델링(Feat. DNN 모델)

AI_HitchHiker 2024. 8. 22. 20:14

mnist 데이터셋

TensorFlow 샘플에 보면 mnist 데이터셋이 많이 등장합니다. MNIST는 인공지능 연구의 권위자 LeCun교수가 만든 데이터 셋이고 현재 딥러닝을 공부할 때 반드시 거쳐야할 Hello, World같은 존재입니다. MNIST는 60,000개의 트레이닝 셋과 10,000개의 테스트 셋으로 이루어져 있고 이중 트레이닝 셋을 학습데이터로 사용하고 테스트 셋을 신경망을 검증하는 데에 사용합니다. MNIST는 간단한 컴퓨터 비전 데이터 세트로, 손으로 쓰여진 이미지들로 구성되어 있습니다. 숫자는 0에서 9까지의 값을 갖는 고정 크기 이미지 (28x28 픽셀)로 크기 표준화되고 중심에 배치되었습니다

MNIST 데이터베이스

 


Tensorflow 모델링 구현 (Feat. keras.Sequential)

구글 드라이브 연동 (colab 에서 실습)

# 구글 드라이브 마운트
from google.colab import drive
drive.mount('/content/drive')

# 나의 루트 경로 설정
rootdir = '/content/drive/MyDrive/Colab Notebooks'

 


데이터 불러오기

from tensorflow.keras.datasets  import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()

print(x_train.shape, y_train.shape, x_test.shape, y_test.shape)

 

  • 데이터확인 (train 이미지 10개를 표시)
import matplotlib.pyplot as plt

fig, axs = plt.subplots(nrows = 1, ncols = 10, layout = 'tight', figsize = (10, 100))
for i in range(10):
  axs.flat[i].set_title(y_train[i])
  axs.flat[i].imshow(x_train[i], cmap = 'Greys')
  #axs.flat[i].set_axis_off()
plt.show()

 

import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()

plt.figure(figsize=(10, 4))

for i in range(10):
    plt.subplot(1, 10, i + 1) 
    plt.imshow(x_train[i], cmap='gray')
    plt.title(f'Label: {y_train[i]}')
    plt.axis('off')

plt.tight_layout()
plt.show()

 

import matplotlib.pyplot as plt

# fig : 전체 그림(figure)을 나타내는 객체입니다. 서브플롯들을 포함하고 있는 큰 그림입니다.
# axs : 서브플롯을 나타내는 배열입니다. 이 배열의 각 요소는 개별 서브플롯을 나타내는 Axes 객체입니다.
# nrows = 2 : 서브플롯의 행(row) 개수를 2로 설정합니다.
# ncols = 10 : 서브플롯의 열(column) 개수를 10으로 설정합니다.
# layout = 'tight' : 서브플롯 간의 여백을 최소화하여 레이아웃을 조정합니다. 즉, 서브플롯들이 서로 붙어 보이도록 배치합니다.
# figsize = (10, 2) : 전체 그림의 크기를 가로 10 인치, 세로 2 인치로 설정합니다.
fig, axs = plt.subplots(nrows = 2, ncols = 10, layout = 'tight', figsize = (10, 2))

for i in range(20):
  axs.flat[i].set_title(y_train[i])
  axs.flat[i].imshow(x_train[i], cmap = 'Greys')
  #axs.flat[i].set_axis_off()
plt.show()

 

 

0~255까지의 값을 가짐. 손글씨이미지는 흑백으로 1개 차원의 값을 가짐.

# 0 ~ 255 까지의 밝기
np.min(x_train[0]), np.max(x_train[0])

 

글짜 이미지 0번 확인

x_train[0]

plt.gca().grid(False)
plt.imshow(x_train[0], cmap= plt.cm.binary)

 

train, test 데이터 개수 확인

print(x_train.shape)
print(x_test.shape)


전처리

  • 독립변수 - 차원축소 (60000 x 28 x 28 => 60000 x 784)
    • Input Layer는 1차원으로 입력해야 하므로, (28 x 28) => (784) 로 변환
#x_train_1d = x_train.reshape(60000, 28*28)
x_train_1d = x_train.reshape(60000, -1)
x_test_1d = x_test.reshape(10000, -1)

x_train_1d.shape, x_test_1d.shape

 

  • 독립변수 - 스케일 조정
    • min-max scaler 과 동일한 처리이나, min값이 0이라 그냥 max값으로 나눠주는 것과 동일함.
# 0 ~ 255 까지 스케일
x_train_1d = x_train_1d / 255.0
x_test_1d = x_test_1d / 255.0

 

  • 종속변수 - 원핫인코딩
    • 종속변수의 유니크한 값 개수 확인
print(np.unique(y_train))
print(np.unique(y_test))

 

from tensorflow.keras.utils import to_categorical

y_train_enc = to_categorical(y_train)
y_test_enc = to_categorical(y_test)

y_train_enc.shape, y_test_enc.shape

 

10개의 더미변수로 변환 됨.

print(y_train[:5])					# 원핫인코딩 전
print(y_train_enc[:5])				# 원핫인코딩 후

 


모델링

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Input
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint

model = Sequential()

EPOCHS = 100		# epoch 회수 지정

Input_cnt = 784		# Input Layer 의 입력개수 지정
Output_cnt = 10		# Output Layer 의 출력개수 지정

model.add(Input(shape=(Input_cnt,)))                        # Input Layer

model.add(Dense(256, activation='relu'))                    # Hidden Layer
model.add(Dense(128, activation='relu'))                    # Hidden Layer
model.add(Dense(Output_cnt, activation='softmax'))          # Out Layer

model.summary()
model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])

# 모델링 얼리스탑핑 설정
# patience = 20 : 20 epoch 동안 더 개선이 안되면,, 20epoch 전의 loss를 가져온다.
esc = EarlyStopping(monitor='val_loss', patience=20)

# 모델을 저장
chkpt = ModelCheckpoint(filepath=rootdir + '/mnist_model.keras', monitor = 'val_loss', verbose = 1, save_best_only = True)

# 모델을 학습
hist = model.fit(x_train_1d, y_train_enc, validation_data = (x_test_1d, y_test_enc), callbacks = [esc, chkpt], epochs = EPOCHS)

 

epoch 23에서 더 이상 val_loss 가 감속하지 않아서 종료됨

 

  • 그래프 그리기
# 종료된 epoch 길이 설정
e_stop_cnt = 23

 

  • 정확도 그래프 그리기
# 정확도 그래프 그리기
import matplotlib.pyplot as plt
plt.plot(range(e_stop_cnt), hist.history['accuracy'][:e_stop_cnt], label = 'Train data')
plt.plot(range(e_stop_cnt), hist.history['val_accuracy'][:e_stop_cnt], label = 'Test data')
plt.legend()
plt.grid()
plt.xlabel('Epoch')
plt.ylabel('Accuracy')

 

  • 오차(loss) 그래프 그리기
# loss 그래프 그리기
import matplotlib.pyplot as plt
plt.plot(range(e_stop_cnt), hist.history['loss'][:e_stop_cnt], label = 'Train data')
plt.plot(range(e_stop_cnt), hist.history['val_loss'][:e_stop_cnt], label = 'Test data')
plt.legend()
plt.grid()
plt.xlabel('Epoch')
plt.ylabel('loss')

 

 

  • 결과값 그래프 함수 구현
def train_report(hist):
  fig, axs = plt.subplots(nrows = 1, ncols = 2, layout = 'tight', figsize = (7, 3))

  for i, mt in enumerate(['accuracy', 'val_accuracy', 'loss', 'val_loss']):
    if i % 2 == 0:
        axs.flat[i//2].set_title(mt)
    axs.flat[i//2].plot(range(len(hist.history[mt])), hist.history[mt], label = mt)
    #axs.flat[i/2].imshow(x_train[i], cmap = 'Greys')
    #axs.flat[i].set_axis_off()
  plt.show()
train_report(hist)


저장한 모델 가져오기

from tensorflow.keras.models import load_model

ha_model = load_model(rootdir + '/mnist_model.keras')
ha_model.summary()

  • 불러온 모델로 예측(predict) 하기-1
print(x_test_1d.shape)
print(x_test_1d[0].shape)
print(x_test_1d[:1].shape)
print(x_test_1d[np.newaxis, 0].shape)

 

# predict 매개변수는 2차원의 데이터를 넣어야 됨.
pred = ha_model.predict(x_test_1d[:1])

 

print(pred)
print(np.sum(pred))

 

 

  • 불러온 모델로 예측(predict) 하기-2
img_idx = 5

plt.gca().grid(False)
plt.imshow(x_test[img_idx], cmap= plt.cm.binary)

pred = ha_model.predict(x_test_1d[img_idx:img_idx + 1])
print('예측값 : ', np.argmax(pred, axis = 1))

 

끝~