# 합성곱 신경망을 사용한 이미지 분류¶

## 패션 MNIST 데이터 불러오기¶

In [1]:
from tensorflow import keras
from sklearn.model_selection import train_test_split

(train_input, train_target), (test_input, test_target) = \

train_scaled = train_input.reshape(-1, 28, 28, 1) / 255.0

train_scaled, val_scaled, train_target, val_target = train_test_split(
train_scaled, train_target, test_size=0.2, random_state=42)

Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz
32768/29515 [=================================] - 0s 0us/step
26427392/26421880 [==============================] - 1s 0us/step
8192/5148 [===============================================] - 0s 0us/step
4423680/4422102 [==============================] - 0s 0us/step


## 합성곱 신경망 만들기¶

In [2]:
model = keras.Sequential()

In [3]:
model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu',

In [4]:
model.add(keras.layers.MaxPooling2D(2))

In [5]:
model.add(keras.layers.Conv2D(64, kernel_size=(3,3), activation='relu',

In [6]:
model.add(keras.layers.Flatten())

In [7]:
model.summary()

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d (Conv2D)              (None, 28, 28, 32)        320
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 14, 14, 32)        0
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 14, 14, 64)        18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 7, 7, 64)          0
_________________________________________________________________
flatten (Flatten)            (None, 3136)              0
_________________________________________________________________
dense (Dense)                (None, 100)               313700
_________________________________________________________________
dropout (Dropout)            (None, 100)               0
_________________________________________________________________
dense_1 (Dense)              (None, 10)                1010
=================================================================
Total params: 333,526
Trainable params: 333,526
Non-trainable params: 0
_________________________________________________________________

In [8]:
keras.utils.plot_model(model)

Out[8]:
In [9]:
keras.utils.plot_model(model, show_shapes=True, to_file='cnn-architecture.png', dpi=300)

Out[9]:

## 모델 컴파일과 훈련¶

In [10]:
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy',
metrics='accuracy')

checkpoint_cb = keras.callbacks.ModelCheckpoint('best-cnn-model.h5',
save_best_only=True)
early_stopping_cb = keras.callbacks.EarlyStopping(patience=2,
restore_best_weights=True)

history = model.fit(train_scaled, train_target, epochs=20,
validation_data=(val_scaled, val_target),
callbacks=[checkpoint_cb, early_stopping_cb])

Epoch 1/20
1500/1500 [==============================] - 36s 3ms/step - loss: 0.5223 - accuracy: 0.8119 - val_loss: 0.3308 - val_accuracy: 0.8744
Epoch 2/20
1500/1500 [==============================] - 4s 3ms/step - loss: 0.3400 - accuracy: 0.8781 - val_loss: 0.2821 - val_accuracy: 0.8956
Epoch 3/20
1500/1500 [==============================] - 4s 3ms/step - loss: 0.2915 - accuracy: 0.8939 - val_loss: 0.2502 - val_accuracy: 0.9061
Epoch 4/20
1500/1500 [==============================] - 4s 3ms/step - loss: 0.2586 - accuracy: 0.9057 - val_loss: 0.2412 - val_accuracy: 0.9090
Epoch 5/20
1500/1500 [==============================] - 5s 3ms/step - loss: 0.2358 - accuracy: 0.9143 - val_loss: 0.2195 - val_accuracy: 0.9179
Epoch 6/20
1500/1500 [==============================] - 5s 3ms/step - loss: 0.2154 - accuracy: 0.9202 - val_loss: 0.2275 - val_accuracy: 0.9165
Epoch 7/20
1500/1500 [==============================] - 4s 3ms/step - loss: 0.1961 - accuracy: 0.9268 - val_loss: 0.2292 - val_accuracy: 0.9170

In [11]:
import matplotlib.pyplot as plt

In [12]:
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train', 'val'])
plt.show()

In [13]:
model.evaluate(val_scaled, val_target)

375/375 [==============================] - 1s 2ms/step - loss: 0.2195 - accuracy: 0.9179

Out[13]:
[0.2194737195968628, 0.9179166555404663]
In [14]:
plt.imshow(val_scaled[0].reshape(28, 28), cmap='gray_r')
plt.show()

In [15]:
preds = model.predict(val_scaled[0:1])
print(preds)

[[1.8246358e-13 8.6280835e-21 8.9756789e-16 1.5351074e-15 7.8192093e-15
1.3402502e-11 2.1972722e-14 2.4236521e-10 1.0000000e+00 1.5653938e-11]]

In [16]:
plt.bar(range(1, 11), preds[0])
plt.xlabel('class')
plt.ylabel('prob.')
plt.show()

In [17]:
classes = ['티셔츠', '바지', '스웨터', '드레스', '코트',
'샌달', '셔츠', '스니커즈', '가방', '앵클 부츠']

In [18]:
import numpy as np
print(classes[np.argmax(preds)])

가방

In [19]:
test_scaled = test_input.reshape(-1, 28, 28, 1) / 255.0

In [20]:
model.evaluate(test_scaled, test_target)

313/313 [==============================] - 1s 3ms/step - loss: 0.2404 - accuracy: 0.9124

Out[20]:
[0.2403760552406311, 0.9124000072479248]