[딥러닝] CNN Feature map(특징 맵) 추출
특징 맵 추출 방법
모델 생성 후 모델의 입력과 특징 맵을 추출하고 싶은 레이어의 출력으로 특징 맵을 추출하는 모델 생성
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
데이터셋 준비
데이터셋: 패션 MNIST
fashion_mnist = tf.keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz 32768/29515 [=================================] - 0s 0us/step 40960/29515 [=========================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz 26427392/26421880 [==============================] - 0s 0us/step 26435584/26421880 [==============================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz 16384/5148 [===============================================================================================] - 0s 0us/step Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz 4423680/4422102 [==============================] - 0s 0us/step 4431872/4422102 [==============================] - 0s 0us/step
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
train_images.shape
(60000, 28, 28)
train_labels
array([9, 0, 0, ..., 3, 0, 5], dtype=uint8)
plt.figure()
plt.imshow(train_images[0], cmap="gray")
plt.colorbar()
plt.show()
픽셀 값을 0~1사이로 조정
train_images = train_images / 255.0
test_images = test_images / 255.0
plt.figure(figsize=(10,10))
for i in range(25):
plt.subplot(5,5,i+1)
plt.xticks([])
plt.yticks([])
plt.imshow(train_images[i], cmap=plt.cm.binary)
plt.xlabel(class_names[train_labels[i]])
plt.show()
모델 생성
inputs = tf.keras.layers.Input(shape=(28,28,1))
x = tf.keras.layers.Conv2D(32, kernel_size=3, strides=1, padding='same', activation='relu')(inputs)
x = tf.keras.layers.Conv2D(64, kernel_size=3, strides=2, padding='same', activation='relu')(x)
x = tf.keras.layers.Conv2D(128, kernel_size=3, strides=2, padding='same', activation='relu')(x)
x = tf.keras.layers.Flatten()(x)
x = tf.keras.layers.Dense(10, activation='softmax')(x)
model = tf.keras.models.Model(inputs, x)
model.summary()
Model: "model_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_8 (InputLayer) [(None, 28, 28, 1)] 0 conv2d_21 (Conv2D) (None, 28, 28, 32) 320 conv2d_22 (Conv2D) (None, 14, 14, 64) 18496 conv2d_23 (Conv2D) (None, 7, 7, 128) 73856 flatten_7 (Flatten) (None, 6272) 0 dense_6 (Dense) (None, 10) 62730 ================================================================= Total params: 155,402 Trainable params: 155,402 Non-trainable params: 0 _________________________________________________________________
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
모델 훈련
model.fit(train_images, train_labels, epochs=10)
Epoch 1/10
/usr/local/lib/python3.7/dist-packages/tensorflow/python/util/dispatch.py:1082: UserWarning: "`sparse_categorical_crossentropy` received `from_logits=True`, but the `output` argument was produced by a sigmoid or softmax activation and thus does not represent logits. Was this intended?" return dispatch_target(*args, **kwargs)
1875/1875 [==============================] - 84s 45ms/step - loss: 0.3981 - accuracy: 0.8581 Epoch 2/10 1875/1875 [==============================] - 87s 46ms/step - loss: 0.2638 - accuracy: 0.9048 Epoch 3/10 1875/1875 [==============================] - 87s 46ms/step - loss: 0.2181 - accuracy: 0.9207 Epoch 4/10 1875/1875 [==============================] - 81s 43ms/step - loss: 0.1803 - accuracy: 0.9332 Epoch 5/10 1875/1875 [==============================] - 84s 45ms/step - loss: 0.1542 - accuracy: 0.9443 Epoch 6/10 1875/1875 [==============================] - 88s 47ms/step - loss: 0.1271 - accuracy: 0.9544 Epoch 7/10 1875/1875 [==============================] - 89s 47ms/step - loss: 0.1047 - accuracy: 0.9618 Epoch 8/10 1875/1875 [==============================] - 82s 44ms/step - loss: 0.0882 - accuracy: 0.9682 Epoch 9/10 1875/1875 [==============================] - 84s 45ms/step - loss: 0.0739 - accuracy: 0.9737 Epoch 10/10 1875/1875 [==============================] - 90s 48ms/step - loss: 0.0653 - accuracy: 0.9766
<keras.callbacks.History at 0x7fb3dde86a90>
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest accuracy:', test_acc)
/usr/local/lib/python3.7/dist-packages/tensorflow/python/util/dispatch.py:1082: UserWarning: "`sparse_categorical_crossentropy` received `from_logits=True`, but the `output` argument was produced by a sigmoid or softmax activation and thus does not represent logits. Was this intended?" return dispatch_target(*args, **kwargs)
313/313 - 4s - loss: 0.3365 - accuracy: 0.9140 - 4s/epoch - 13ms/step Test accuracy: 0.9139999747276306
특징맵 모델 생성
ins = model.inputs
outs = model.layers[1].output
feature_map = tf.keras.models.Model(ins, outs)
feature_map.summary()
Model: "model_5" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_8 (InputLayer) [(None, 28, 28, 1)] 0 conv2d_21 (Conv2D) (None, 28, 28, 32) 320 ================================================================= Total params: 320 Trainable params: 320 Non-trainable params: 0 _________________________________________________________________
plt.figure()
plt.imshow(train_images[5], cmap="gray")
plt.colorbar()
plt.show()
input_img = np.expand_dims(train_images[5], axis=0)
feature = feature_map.predict(input_img)
print(feature.shape)
plt.figure(figsize=(25,25))
for i in range(16):
plt.subplot(4,4,i+1)
plt.imshow(feature[0,:,:,i], cmap="gray")
plt.show()
(1, 28, 28, 32)
특징 맵을 보면 첫번째 레이어는 옷의 선 같은 표면을 잘 학습한 것으로 보입니다.
모든 레이어 특징 맵 확인
def check_feature(num_layer, input_img):
ins = model.inputs
outs = model.layers[num_layer].output
feature_map = tf.keras.models.Model(ins, outs)
input_img = np.expand_dims(input_img, axis=0)
feature = feature_map.predict(input_img)
print(feature.shape)
plt.figure(figsize=(15,10))
for i in range(6):
plt.subplot(1,6, i+1)
plt.imshow(feature[0,:,:,i], cmap="gray")
plt.show()
plt.figure()
plt.imshow(train_images[600], cmap="gray")
plt.colorbar()
plt.show()
for i in range(1, 4):
check_feature(i, train_images[600])
(1, 28, 28, 32)
(1, 14, 14, 64)
(1, 7, 7, 128)
출력층에 가까울수록 원래 형태는 찾아볼 수 없고, 이미지 특징들만 전달되는 것을 확인할 수 있습니다.
댓글남기기