241104
In [ ]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import random as rd
import cv2, os # cv2 : OpenCV
from sklearn.model_selection import train_test_split
from sklearn.metrics import *
from keras.models import Sequential
from keras.layers import Dense, Flatten, Conv2D, MaxPooling2D, Input
from keras.backend import clear_session
from keras.optimizers import Adam
from keras.datasets import mnist, fashion_mnist
In [ ]:
CNN 모델
In [ ]:
(x_train, y_train), (x_val, y_val) = mnist.load_data()
x_train.shape, x_val.shape
Out[ ]:
((60000, 28, 28), (10000, 28, 28))
In [ ]:
# 데이터셋을 4차원으로 변환
x_train.reshape(60000,28,28,1) # (건수, 세로픽셀수, 가로픽셀수, 채널(컬러3, 흑백1))
x_val.reshape(10000,28,28,1)
# 스케일링
x_train = x_train / 255.
x_val = x_val / 255.
In [ ]:
# 모델링
clear_session()
model = Sequential([Input(shape = (28,28,1)),
Conv2D(16, kernel_size = 3, padding = 'same', activation ='relu', strides = 1), # 특징 추출
MaxPooling2D(pool_size = 2), # 요약
Flatten(),
Dense(10, activation = 'softmax')])
model.summary()
In [ ]:
# Conv2D의 strides default: 1
# MaxPooling2D strides default: pool_size
In [ ]:
# 컴파일, 학습
model.compile(optimizer = Adam(learning_rate = 0.001), loss = 'sparse_categorical_crossentropy')
hist = model.fit(x_train, y_train, epochs = 10, validation_split = 0.2).history
Epoch 1/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 23s 15ms/step - loss: 0.5289 - val_loss: 0.1423
Epoch 2/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 40s 14ms/step - loss: 0.1264 - val_loss: 0.0942
Epoch 3/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 40s 14ms/step - loss: 0.0827 - val_loss: 0.0883
Epoch 4/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 23s 15ms/step - loss: 0.0683 - val_loss: 0.0763
Epoch 5/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 20s 13ms/step - loss: 0.0554 - val_loss: 0.0717
Epoch 6/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 21s 14ms/step - loss: 0.0491 - val_loss: 0.0735
Epoch 7/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 20s 13ms/step - loss: 0.0422 - val_loss: 0.0717
Epoch 8/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 22s 14ms/step - loss: 0.0371 - val_loss: 0.0803
Epoch 9/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 20s 13ms/step - loss: 0.0335 - val_loss: 0.0707
Epoch 10/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 22s 15ms/step - loss: 0.0296 - val_loss: 0.0692
In [ ]:
# 시각화
plt.plot(hist['loss'], label='train_err', marker = ',')
plt.plot(hist['val_loss'], label='val_err', marker = ',')
plt.legend()
plt.grid()
plt.show()

In [ ]:
pred = model.predict(x_val)
pred = pred.argmax(axis = 1)
print(accuracy_score(y_val,pred))
print()
print(confusion_matrix(y_val, pred))
print()
print(classification_report(y_val, pred))
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 11ms/step
0.9791
[[ 970 0 2 0 0 1 2 1 3 1]
[ 0 1119 4 1 2 1 3 1 4 0]
[ 5 2 1004 2 1 0 0 5 12 1]
[ 0 0 5 996 0 4 0 1 3 1]
[ 0 0 1 0 967 0 2 2 2 8]
[ 2 0 1 7 0 878 3 0 1 0]
[ 6 2 0 0 3 4 938 0 5 0]
[ 1 4 12 6 1 1 0 992 7 4]
[ 6 0 3 0 0 1 0 2 960 2]
[ 4 2 2 6 5 5 0 7 11 967]]
precision recall f1-score support
0 0.98 0.99 0.98 980
1 0.99 0.99 0.99 1135
2 0.97 0.97 0.97 1032
3 0.98 0.99 0.98 1010
4 0.99 0.98 0.99 982
5 0.98 0.98 0.98 892
6 0.99 0.98 0.98 958
7 0.98 0.96 0.97 1028
8 0.95 0.99 0.97 974
9 0.98 0.96 0.97 1009
accuracy 0.98 10000
macro avg 0.98 0.98 0.98 10000
weighted avg 0.98 0.98 0.98 10000
CNN 모델2
In [ ]:
clear_session()
model = Sequential([Input(shape = (28,28,1)),
Conv2D(32, kernel_size = 3, padding = 'same', activation = 'relu'),
MaxPooling2D(pool_size = 2),
Flatten(),
Dense(128, activation = 'relu'),
Dense(10, activation = 'softmax')])
model.summary()
In [ ]:
# 컴파일, 학습
model.compile(optimizer = Adam(learning_rate = 0.001), loss = 'sparse_categorical_crossentropy')
history = model.fit(x_train, y_train, validation_split = 0.2, epochs = 10).history
Epoch 1/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 9s 3ms/step - loss: 0.3472 - val_loss: 0.0746
Epoch 2/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 4s 3ms/step - loss: 0.0594 - val_loss: 0.0609
Epoch 3/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 4s 3ms/step - loss: 0.0341 - val_loss: 0.0618
Epoch 4/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 3s 2ms/step - loss: 0.0212 - val_loss: 0.0507
Epoch 5/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 3s 2ms/step - loss: 0.0129 - val_loss: 0.0661
Epoch 6/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 6s 3ms/step - loss: 0.0100 - val_loss: 0.0529
Epoch 7/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 4s 2ms/step - loss: 0.0075 - val_loss: 0.0606
Epoch 8/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 3s 2ms/step - loss: 0.0060 - val_loss: 0.0599
Epoch 9/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 6s 3ms/step - loss: 0.0049 - val_loss: 0.0685
Epoch 10/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 4s 2ms/step - loss: 0.0035 - val_loss: 0.0707
In [ ]:
# 시각화
plt.plot(history['loss'], label='train_err', marker = ',')
plt.plot(history['val_loss'], label='val_err', marker = ',')
plt.legend()
plt.grid()
plt.show()

In [ ]:
pred = model.predict(x_val)
pred = pred.argmax(axis=1)
print(accuracy_score(y_val,pred))
print('-'*60)
print(confusion_matrix(y_val, pred))
print('-'*60)
print(classification_report(y_val, pred))
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 3ms/step
0.9847
------------------------------------------------------------
[[ 970 0 0 1 0 1 6 0 1 1]
[ 0 1132 2 0 0 0 1 0 0 0]
[ 1 4 1011 5 2 0 1 5 3 0]
[ 0 0 0 1005 0 1 0 0 0 4]
[ 0 1 0 0 970 0 5 1 0 5]
[ 3 0 0 9 0 877 3 0 0 0]
[ 2 1 0 1 3 2 948 0 1 0]
[ 2 4 8 5 0 0 0 1002 3 4]
[ 4 1 1 5 2 7 3 2 941 8]
[ 0 3 0 2 7 5 0 1 0 991]]
------------------------------------------------------------
precision recall f1-score support
0 0.99 0.99 0.99 980
1 0.99 1.00 0.99 1135
2 0.99 0.98 0.98 1032
3 0.97 1.00 0.98 1010
4 0.99 0.99 0.99 982
5 0.98 0.98 0.98 892
6 0.98 0.99 0.98 958
7 0.99 0.97 0.98 1028
8 0.99 0.97 0.98 974
9 0.98 0.98 0.98 1009
accuracy 0.98 10000
macro avg 0.98 0.98 0.98 10000
weighted avg 0.98 0.98 0.98 10000
CNN 모델3
In [ ]:
# 3차원 구조의 이미지
# 4차원 데이터셋
x_train.shape, x_val.shape
Out[ ]:
((60000, 28, 28), (10000, 28, 28))
In [ ]:
# 데이터 4차원으로 변환
x_train = x_train.reshape(60000, 28, 28, 1)
x_val = x_val.reshape(10000, 28, 28, 1)
In [ ]:
# 최대값
x_train.max(), x_val.max()
Out[ ]:
(255, 255)
In [ ]:
# 스케일링
x_train = x_train/255.
x_val = x_val/255.
In [ ]:
# 모델링
clear_session()
model = Sequential([Input(shape = (28,28,1)),
Conv2D(32, input_shape = (28,28,1), kernel_size = 3, padding = 'same', activation = 'relu', strides = 1), # default strides == 1
MaxPooling2D(pool_size = 2, strides = 2),
Flatten(),
Dense(128, activation = 'relu'),
Dense(10, activation = 'softmax')]) # default strides == pool_size
model.summary()
/usr/local/lib/python3.10/dist-packages/keras/src/layers/convolutional/base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
In [ ]:
model.compile(optimizer=Adam(learning_rate=0.0001), loss='sparse_categorical_crossentropy')
history = model.fit(x_train, y_train, epochs = 10,
validation_split=0.2).history
Epoch 1/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 10s 4ms/step - loss: 0.7581 - val_loss: 0.1801
Epoch 2/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 8s 5ms/step - loss: 0.1773 - val_loss: 0.1221
Epoch 3/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 8s 4ms/step - loss: 0.1138 - val_loss: 0.0952
Epoch 4/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 10s 7ms/step - loss: 0.0883 - val_loss: 0.0846
Epoch 5/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 9s 6ms/step - loss: 0.0668 - val_loss: 0.0701
Epoch 6/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 4s 3ms/step - loss: 0.0559 - val_loss: 0.0685
Epoch 7/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step - loss: 0.0483 - val_loss: 0.0627
Epoch 8/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 8s 3ms/step - loss: 0.0446 - val_loss: 0.0582
Epoch 9/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 6s 3ms/step - loss: 0.0377 - val_loss: 0.0596
Epoch 10/10
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 9s 3ms/step - loss: 0.0338 - val_loss: 0.0566
In [ ]:
pred = model.predict(x_val)
pred = pred.argmax(axis=1)
print(accuracy_score(y_val,pred))
print('-'*60)
print(confusion_matrix(y_val, pred))
print('-'*60)
print(classification_report(y_val, pred))
313/313 ━━━━━━━━━━━━━━━━━━━━ 1s 2ms/step
0.9845
------------------------------------------------------------
[[ 973 1 2 0 0 2 1 1 0 0]
[ 0 1131 2 1 0 0 1 0 0 0]
[ 2 3 1015 3 1 0 1 3 3 1]
[ 0 0 3 1001 0 2 0 0 2 2]
[ 0 0 0 0 961 0 2 1 0 18]
[ 2 0 0 5 0 882 2 0 1 0]
[ 6 2 1 0 3 5 937 0 4 0]
[ 0 3 9 3 0 0 0 1006 3 4]
[ 3 0 2 2 0 2 0 3 954 8]
[ 3 4 0 2 3 4 0 7 1 985]]
------------------------------------------------------------
precision recall f1-score support
0 0.98 0.99 0.99 980
1 0.99 1.00 0.99 1135
2 0.98 0.98 0.98 1032
3 0.98 0.99 0.99 1010
4 0.99 0.98 0.99 982
5 0.98 0.99 0.99 892
6 0.99 0.98 0.99 958
7 0.99 0.98 0.98 1028
8 0.99 0.98 0.98 974
9 0.97 0.98 0.97 1009
accuracy 0.98 10000
macro avg 0.98 0.98 0.98 10000
weighted avg 0.98 0.98 0.98 10000
CNN 모델 (early stopping, dropout)
In [ ]:
from keras.layers import Dropout
from keras.callbacks import EarlyStopping
In [ ]:
# 모델링
dr = 0.3
clear_session()
model = Sequential([Input(shape = (28, 28,1)),
Conv2D(64, kernel_size = 3, padding = 'same', activation = 'relu'),
MaxPooling2D(pool_size = 2),
Dropout(dr),
Conv2D(128, kernel_size = 3, padding = 'same', activation = 'relu'),
MaxPooling2D(pool_size = 2),
Dropout(dr),
Flatten(),
Dense(128, activation = 'relu'),
Dense(128, activation = 'relu'),
Dense(64, activation = 'relu'),
Dense(10, activation = 'softmax')])
model.summary()
In [ ]:
es = EarlyStopping(monitor = 'val_loss', patience = 5)
model.compile(optimizer = Adam(learning_rate =0.001), loss = 'sparse_categorical_crossentropy', metrics = ['Accuracy'])
history = model.fit(x_train, y_train, validation_split = 0.2, epochs = 50, callbacks = [es]).history
Epoch 1/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 12s 4ms/step - Accuracy: 0.8743 - loss: 0.3782 - val_Accuracy: 0.9822 - val_loss: 0.0594
Epoch 2/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step - Accuracy: 0.9792 - loss: 0.0664 - val_Accuracy: 0.9847 - val_loss: 0.0492
Epoch 3/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 5s 3ms/step - Accuracy: 0.9853 - loss: 0.0467 - val_Accuracy: 0.9826 - val_loss: 0.0562
Epoch 4/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 7s 4ms/step - Accuracy: 0.9884 - loss: 0.0372 - val_Accuracy: 0.9865 - val_loss: 0.0462
Epoch 5/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 5s 3ms/step - Accuracy: 0.9893 - loss: 0.0353 - val_Accuracy: 0.9883 - val_loss: 0.0419
Epoch 6/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 6s 4ms/step - Accuracy: 0.9912 - loss: 0.0276 - val_Accuracy: 0.9900 - val_loss: 0.0377
Epoch 7/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 5s 4ms/step - Accuracy: 0.9930 - loss: 0.0241 - val_Accuracy: 0.9893 - val_loss: 0.0441
Epoch 8/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 11s 4ms/step - Accuracy: 0.9930 - loss: 0.0244 - val_Accuracy: 0.9913 - val_loss: 0.0321
Epoch 9/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 5s 3ms/step - Accuracy: 0.9929 - loss: 0.0210 - val_Accuracy: 0.9885 - val_loss: 0.0441
Epoch 10/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 6s 4ms/step - Accuracy: 0.9937 - loss: 0.0215 - val_Accuracy: 0.9898 - val_loss: 0.0401
Epoch 11/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 9s 3ms/step - Accuracy: 0.9954 - loss: 0.0157 - val_Accuracy: 0.9907 - val_loss: 0.0412
Epoch 12/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 10s 3ms/step - Accuracy: 0.9947 - loss: 0.0165 - val_Accuracy: 0.9898 - val_loss: 0.0430
Epoch 13/50
1500/1500 ━━━━━━━━━━━━━━━━━━━━ 10s 3ms/step - Accuracy: 0.9957 - loss: 0.0149 - val_Accuracy: 0.9904 - val_loss: 0.0388
In [ ]:
# 시각화
plt.plot(history['loss'], label='train_err', marker = ',')
plt.plot(history['val_loss'], label='val_err', marker = ',')
plt.legend()
plt.grid()
plt.show()

In [ ]:
pred = model.predict(x_val)
pred = pred.argmax(axis=1)
print(accuracy_score(y_val,pred))
print('-'*60)
print(confusion_matrix(y_val, pred))
print('-'*60)
print(classification_report(y_val, pred))
313/313 ━━━━━━━━━━━━━━━━━━━━ 2s 4ms/step
0.9936
------------------------------------------------------------
[[ 977 0 0 0 0 0 1 1 1 0]
[ 0 1133 1 0 1 0 0 0 0 0]
[ 0 0 1030 0 0 0 0 2 0 0]
[ 0 0 2 1004 0 4 0 0 0 0]
[ 0 0 0 0 975 0 0 0 0 7]
[ 0 0 1 5 0 884 1 1 0 0]
[ 1 4 1 0 1 2 947 0 2 0]
[ 0 3 6 1 2 0 0 1015 0 1]
[ 1 0 0 0 0 0 0 0 971 2]
[ 0 0 0 0 4 3 0 2 0 1000]]
------------------------------------------------------------
precision recall f1-score support
0 1.00 1.00 1.00 980
1 0.99 1.00 1.00 1135
2 0.99 1.00 0.99 1032
3 0.99 0.99 0.99 1010
4 0.99 0.99 0.99 982
5 0.99 0.99 0.99 892
6 1.00 0.99 0.99 958
7 0.99 0.99 0.99 1028
8 1.00 1.00 1.00 974
9 0.99 0.99 0.99 1009
accuracy 0.99 10000
macro avg 0.99 0.99 0.99 10000
weighted avg 0.99 0.99 0.99 10000