tf.keras
의 Sequential API
를 이용한 숫자 손글씨 인식기 생성import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
import os
print(tf.__version__)
mnist = keras.datasets.mnist
# MNIST 데이터 로드
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(len(x_train))
- 내용 참고 : THE MNIST DATABASE of handwritten digits
- 숫자 손글씨 이미지 크기 : 28x28
- MNIST dataset에는 총 70,000장의 손글씨 이미지가 있음
- train_set : 60,000
- test_set : 10,000
- training set에는 약 250명의 손글씨가 들어있음
x_train
, x_test
: 이미지 데이터 matrixx_train[1]
은 x_train
행렬의 2번째 이미지임!plt.imshow(x_train[1],cmap=plt.cm.binary)
plt.show()
y_train
행렬 2번째 값 확인print(y_train[1])
index = 10000 # 0 ~ 59999 사이 숫자
plt.imshow(x_train[index],cmap=plt.cm.binary)
plt.show()
print( (index+1), '번째 이미지의 숫자는 바로 ', y_train[index], '입니다.')
index = 40000 # 0 ~ 59999 사이 숫자
plt.imshow(x_train[index],cmap=plt.cm.binary)
plt.show()
print( (index+1), '번째 이미지의 숫자는 바로 ', y_train[index], '입니다.')
print(x_train.shape)
print(x_test.shape)
Q&A
- validation set(검증 데이터) 사용
- ML 과정의 정상적 진행 여부
- overfitting 여부 확인
- 학습 중단 가능 여부 판단...
- 교차 검증(cross validation) 기법
- 모델 평가 및 성능 측정의 한 기법으로, 주어진 데이터를 분할해서 모델 훈련 및 검증하는 과정을 반복하는 기법을 말함.
- 일반적으로 데이터 양이 부족한 경우 자주 사용하며, 모델 일반화 성능을 더 정확히 평가할 수 있게끔 해줌.
- K-Fold Cross-Validation을 주로 사용!
print('최소값:',np.min(x_train), ' 최대값:',np.max(x_train))
x_train_norm, x_test_norm = x_train / 255.0, x_test / 255.0
print('최소값:',np.min(x_train_norm), ' 최대값:',np.max(x_train_norm))
tf.keras
의 Sequential API 사용Conv2D(16, (3,3)
: 16 -> 이미지 특징 개수input_shape=(28,28,1)
: 입력 이미지 형태keras.layers.Dense(32,...
: 분류기 알고리즘의 복잡도 설정(숫자가 커질수록 복잡도 올라감)keras.layers.Dense(10,...
: 최종 분류기 class 개수(0~9까지 총 10개의 클래스이기 때문에 10으로 설정)model=keras.models.Sequential()
model.add(keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D(2,2))
model.add(keras.layers.Conv2D(32, (3,3), activation='relu'))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
print('Model에 추가된 Layer 개수: ', len(model.layers))
model.summary()
로 만든 딥러닝 네트워크 모델 확인model.summary()
(데이터 개수, 이미지 크기 x, 이미지 크기 y, 채널 수)
print(f"Before Reshape - x_train_norm shape: {x_train_norm.shape}")
print(f"Before Reshape - x_test_norm shape: {x_test_norm.shape}")
x_train_reshaped=x_train_norm.reshape( -1, 28, 28, 1)
x_test_reshaped=x_test_norm.reshape( -1, 28, 28, 1)
print(f"After Reshape - x_train_reshaped shape: {x_train_reshaped.shape}")
print(f"After Reshape - x_test_reshaped shape: {x_test_reshaped.shape}")
epochs=10
: 전체 데이터(60,000)를 10번 반복 사용해 학습한다는 의미model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train_reshaped, y_train, epochs=10)
test_loss, test_accuracy = model.evaluate(x_test_reshaped,y_test, verbose=2)
print(f"test_loss: {test_loss}")
print(f"test_accuracy: {test_accuracy}")
model.predict()
predicted_result = model.predict(x_test_reshaped)
predicted_labels = np.argmax(predicted_result, axis=1)
idx=0
print('model.predict() 결과 : ', predicted_result[idx])
print('model이 추론한 가장 가능성이 높은 결과 : ', predicted_labels[idx])
print('실제 데이터의 라벨 : ', y_test[idx])
plt.imshow(x_test[idx],cmap=plt.cm.binary)
plt.show()
import random
wrong_predict_list=[]
for i, _ in enumerate(predicted_labels):
if predicted_labels[i] != y_test[i]:
wrong_predict_list.append(i)
samples = random.choices(population=wrong_predict_list, k=5)
for n in samples:
print("예측확률분포: " + str(predicted_result[n]))
print("라벨: " + str(y_test[n]) + ", 예측결과: " + str(predicted_labels[n]))
plt.imshow(x_test[n], cmap=plt.cm.binary)
plt.show()
라벨과 예측 결과가 상당히 다르게 나옴을 확인할 수 있음
Conv2D
: 입력 이미지 특징 수 변경Dense
: 뉴런 개수 변경epoch
: 학습 횟수 변경# 변경 시도가 가능한 파라미터
n_channel_1=16
n_channel_2=32
n_dense=32
n_train_epoch=10
model=keras.models.Sequential()
model.add(keras.layers.Conv2D(n_channel_1, (3,3), activation='relu', input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D(2,2))
model.add(keras.layers.Conv2D(n_channel_2, (3,3), activation='relu'))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(n_dense, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
model.summary()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 모델 훈련
model.fit(x_train_reshaped, y_train, epochs=n_train_epoch)
# 모델 시험
test_loss, test_accuracy = model.evaluate(x_test_reshaped, y_test, verbose=2)
print(f"test_loss: {test_loss} ")
print(f"test_accuracy: {test_accuracy}")
n_channel_1 = 32
n_channel_2 = 64
n_dense = 128
n_train_epoch = 15
model = keras.models.Sequential()
model.add(keras.layers.Conv2D(n_channel_1, (3,3), activation='relu', input_shape=(28,28,1)))
model.add(keras.layers.MaxPool2D(2,2))
model.add(keras.layers.Conv2D(n_channel_2, (3,3), activation='relu'))
model.add(keras.layers.MaxPooling2D((2,2)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(n_dense, activation='relu'))
model.add(keras.layers.Dense(10, activation='softmax'))
model.summary()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# 모델 훈련
model.fit(x_train_reshaped, y_train, epochs=n_train_epoch)
# 모델 시험
test_loss, test_accuracy = model.evaluate(x_test_reshaped, y_test, verbose=2)
print(f"test_loss: {test_loss}")
print(f"test_accuracy: {test_accuracy}")