coursera의 Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning 강좌 내용 일부를 정리했습니다.
단순히 이미지의 픽셀값만으로 분류하는 일반적인 신경망 모델과는 달리 컨볼루션 모델은 이미지의 특징을 필터링하여 분류한다.
Q.컨볼루션은 신발 이미지에서 어떤 특징을 찾을까?
1. 신발끈
2. 밑창
3. 두 켤레
정답은 '알 수 없다😲'
딥러닝 모델은 미리 정해진 분류 규칙에 따라 분류하는 것이 아니라, 주어진 이미지와 레이블만을 가지고 분류 규칙을 학습한다. 밑창과 신발끈이 보이면 신발로 분류해. 라고 모델에 시키는 대신, 여러 장의 사진을 준비하고 이를 학습할 세팅을 해주고 나면, 그다음은 모델이 알아서 신발로 분류하는 규칙을 찾아내는 것이다.
하지만 컨볼루션 레이어를 시각화해서 대충 그 '규칙'이 무엇인지 유추해볼 수 있다. 다음은 컨볼루션을 이용한 간단한 분류예시다. 데이터는 keras의 fashion_mnist
를 이용했다.
import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(60000, 28, 28, 1)
test_images = test_images.reshape(10000, 28, 28, 1)
# normalizing(정규화)
training_images, test_images =training_images / 255.0, test_images/255.0
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
model.fit(training_images, training_labels, epochs=5)
test_loss, test_acc = model.evaluate(test_images, test_labels)
print(test_acc)
print(test_labels[:50]) # 9 : 신발,
모델의 성능
레이블에 대한 클래스 정보는 다음과 같다.
test_images
의 0번째, 7번째, 26번째 이미지를 가져와서 각 이미지들이 컨볼루션을 거치면서 어떤 특징을 추출하는지 시각화해보겠다.
전체 모델에서 first Convolution
> first Pooling
> second Convolution
> second Pooling
까지, 각 layer마다 output을 가져와 시각화하려 한다.
참고로 padding은 하지 않았고, stride도 기본값=1이기 때문에 첫번째 층을 거친 이미지의 dimension은 (28,28)에서 (, ) = (26,26)으로 줄어든다.
총 64개의 필터를 이용했으므로 4D로 표현하면 (m, 26, 26, 64)이다. m은 이미지 개수, 64는 필터개수를 나타낸다.
CONVOLUTION_NUMBER=20
은 64개의 필터중, 20 번째 필터가 어떤 특징을 추출하는지 확인하고자 함이다.
activation_model.predict(x[m])[l]
은 l
번째 레이어의 activation 값을 나타낸다. (x[m]은 m번째 이미지)import matplotlib.pyplot as plt
f, axarr = plt.subplot(3,4) # 이미지는 총 3개, 컨볼루션과 맥스풀링 층은 총 4개
FIRST_IMAGE=0
SECOND_IMAGE=7
THIRD_IMAGE=26
CONVOLUTION_NUMBER = 20 # 20번째 컨볼루션은 어떤 특징을 추출하는지 시각화하겠다.
from tensorflow.keras import models
layer_outputs = [layer.output for layer in model.layers]
activation_model = tf.keras.models.Model(inputs = model.input, outputs = layer_outputs)
for x in range(0,4):
f1 = activation_model.predict(test_images[FIRST_IMAGE].reshape(1, 28, 28, 1))[x]
axarr[0,x].imshow(f1[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
axarr[0,x].grid(False)
f2 = activation_model.predict(test_images[SECOND_IMAGE].reshape(1, 28, 28, 1))[x]
axarr[1,x].imshow(f2[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
axarr[1,x].grid(False)
f3 = activation_model.predict(test_images[THIRD_IMAGE].reshape(1, 28, 28, 1))[x]
axarr[2,x].imshow(f3[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
axarr[2,x].grid(False)
test_images[0]
이미지가 총 4개의 layer를 거친 과정을 나타낸다. test_labels[0]
는 9(Ankle boot)이다.test_images[7]
이미지가 총 4개의 layer를 거친 과정을 나타낸다. test_labels[7]
는 6(Shirt)이다.test_images[26]
이미지가 총 4개의 layer를 거친 과정을 나타낸다. test_labels[26]
는 6(Shirt)이다.MaxPooling layer
로, 축의 범위를 보면 각각 이전 층에 비해 이미지 사이즈가 줄어들었음을 확인할 수 있다.두번째 레이어까지는 큰 차이가 없지만 세번째 레이어부터 Ankle boot와 Shirt이미지에서 추출되는 특징이 달라보인다.
FIRST_IMAGE
=0(Ankle boot), SECOND_IMAGE
=28(Ankle boot), THIRD_IMAGE
=26(Shirt)마찬가지로 두번째 레이어까지는 큰 차이가 없지만 세번째 레이어부터 Ankle boot와 Shirt이미지에서 추출되는 특징이 달라보인다.
따라서 20 번째 컨볼루션 필터(CONVOLUTION_NUMBER
=20)는 '신발끈 부분의 특징을 detect'한다고 유추해 볼 수도 있겠다.
CONVOLUTION_NUMBER
를 바꿔보겠다.FIRST_IMAGE
=0(Ankle boot), SECOND_IMAGE
=2(Trouser), THIRD_IMAGE
=3(Trouser), CONVOLUTION_NUMBER
=4040 번째 컨볼루션 필터(CONVOLUTION_NUMBER
=40)은 '수직적인 라인의 특징을 detect'한다고 유추해 볼 수 있겠다.