반응형

Keras mnist 데이터세트의 이미지는 보통 matplotlib.pyplot으로 표시한다.

데이터 타입을 확인하고 OpenCV로 표시해 보자.

 

import numpy as np
import matplotlib.pyplot as plt
import cv2
import keras

(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()

print(train_input.shape) # (60000, 28, 28)
print(train_input[0].shape) # (28, 28)
print(type(train_input[0])) # <class 'numpy.ndarray'>

# 첫 번째 이미지 데이터 출력
np.set_printoptions(linewidth=115, threshold=np.inf) # threshold: 출력 생략 임계값. 내용이 많아도 출력이 생략되지 않는다.
print(train_input[0])

# 첫 번째 ~ 열 번째 이미지 출력(pyplot)
fig, axs = plt.subplots(1, 10, figsize=(10, 10))
for i in range(10):
	axs[i].imshow(train_input[i], cmap='gray')
	axs[i].axis('off')
plt.show()

# 첫 번째 이미지 출력(OpenCV)
image = cv2.resize(src=train_input[0], dsize=(0, 0), fx=10, fy=10) # 10배로 확대
cv2.imshow("image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

Gray 스케일 이미지의 데이터가 출력되었다. 데이터 모양만으로도 대략적인 모양을 알 수 있다.

 

matplotlib.pyplot으로 첫 10개의 이미지를 출력했다.

 

28X28 사이즈의 이미지라 너무 작아 10배 확대하고 OpenCV로 출력했다.

Keras에서 사용하는 이미지 데이터 타입도 numpy.ndarray이고, OpenCV에서 사용하는 이미지 데이터 타입도 numpy.ndarray이기 때문에 서로 호환된다.

 

 

LeNet-5 모델을 만들고 OpenCV로 로드한 이미지를 이용해 결과를 예측해 보자.

 

import numpy as np
import cv2
import keras
from keras import layers
from sklearn.model_selection import train_test_split

# LeNet-5 정의
lenet5 = keras.Sequential()
lenet5.add(layers.Input(shape=(28, 28, 1)))
lenet5.add(layers.Conv2D(filters=6, kernel_size=5, activation='sigmoid', padding='same'))
lenet5.add(layers.AveragePooling2D(pool_size=2))
lenet5.add(layers.Conv2D(filters=16, kernel_size=5, activation='sigmoid'))
lenet5.add(layers.AveragePooling2D(pool_size=2))
lenet5.add(layers.Flatten())
lenet5.add(layers.Dense(120, activation='sigmoid'))
lenet5.add(layers.Dense(84, activation='sigmoid'))
lenet5.add(layers.Dense(10, activation='softmax'))
lenet5.summary()

# 훈련 데이터 로드
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
train_input = train_input.reshape(-1, 28, 28, 1) / 255.0
train_scaled, val_scaled, train_target, val_target = train_test_split(train_input, train_target, test_size=0.2, random_state=42)

# 콜백 함수 정의
checkpoint_cb = keras.callbacks.ModelCheckpoint('lenet5-model.keras', save_best_only=True)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2, restore_best_weights=True)

# LeNet-5 훈련
lenet5.compile(loss='sparse_categorical_crossentropy', metrics=['accuracy'])
hist = lenet5.fit(train_scaled, train_target, epochs=20, validation_data=(val_scaled, val_target), callbacks=[checkpoint_cb, early_stopping_cb])

# 예측 이미지 준비
image = cv2.imread('shoes.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.resize(image, (28, 28))
image = cv2.bitwise_not(image) # 이미지 반전

# Fashion MNIST 클래스 정의
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

# 예측
prediction = lenet5.predict(image.reshape(-1, 28, 28, 1) / 255.0)
print(prediction)

# 출력
max_index = np.argmax(prediction)
print('Max index: ', max_index, ', Probability: ', prediction[0][max_index] * 100)
print('Name: ', class_names[max_index])

 

shoes.jpg
0.26MB
tshirt.jpg
0.56MB

 

약 94%의 확률로 신발을 정확히 예측했다.

 

아래는 shoes.jpg, tshirt.jpg 그레이스케일 이미지를 (28X28) 사이즈로 변환 전 반전한 이미지다. 

 

 

 

 

이번엔 훈련 없이 위에서 저장한 가중치(lenet5-model.keras)를 로드하고 예측해 보자.

 

import numpy as np
import cv2
import keras
from keras import layers
from sklearn.model_selection import train_test_split

# Lenet5 정의 (로드할 가중치와 동일한 모델을 만들어야 한다)
lenet5 = keras.Sequential()
lenet5.add(layers.Input(shape=(28, 28, 1)))
lenet5.add(layers.Conv2D(filters=6, kernel_size=5, activation='sigmoid', padding='same'))
lenet5.add(layers.AveragePooling2D(pool_size=2))
lenet5.add(layers.Conv2D(filters=16, kernel_size=5, activation='sigmoid'))
lenet5.add(layers.AveragePooling2D(pool_size=2))
lenet5.add(layers.Flatten())
lenet5.add(layers.Dense(120, activation='sigmoid'))
lenet5.add(layers.Dense(84, activation='sigmoid'))
lenet5.add(layers.Dense(10, activation='softmax'))
#lenet5.summary()

# 저장한 가중치 로드
lenet5.load_weights('lenet5-model.keras')

# 예측 이미지 준비
image = cv2.imread('tshirt.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.resize(image, (28, 28))
image = cv2.bitwise_not(image) # 이미지 반전

# Fashion MNIST 클래스 정의
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

# 예측
prediction = lenet5.predict(image.reshape(-1, 28, 28, 1) / 255.0)
print(prediction)

# 출력
max_index = np.argmax(prediction)
print('Max index: ', max_index, ', Probability: ', prediction[0][max_index] * 100)
print('Name: ', class_names[max_index])

 

약 53%의 확률로 셔츠를 예측했다. 0번 인덱스의 T-shirt/top은 약 44%의 확률을 갖는다.

 

반응형

'AI, ML, DL' 카테고리의 다른 글

[Tensorflow] Kernel build 커널 빌드 및 확인  (0) 2026.03.01
[YOLO] YOLOs-CPP Simple Example  (0) 2026.02.15
[YOLO] YOLOs-CPP build 빌드하기  (0) 2026.02.15
[YOLO] 사용 장치 확인  (0) 2026.02.14
[YOLO] SAM(Segment Anything Model)  (0) 2026.02.13
Posted by J-sean
: