[Tensorflow] Convolution 간단한 시각화

Journey log·2021년 1월 12일
0

Tensorflow

목록 보기
1/1
post-thumbnail

coursera의 Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning 강좌 내용 일부를 정리했습니다.

Convolution 은

단순히 이미지의 픽셀값만으로 분류하는 일반적인 신경망 모델과는 달리 컨볼루션 모델은 이미지의 특징을 필터링하여 분류한다.

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 : 신발, 

모델의 성능

  • train set에서의 정확도: 약 93%
  • test set에서의 정확도: 약 91%

레이블에 대한 클래스 정보는 다음과 같다.

test_images의 0번째, 7번째, 26번째 이미지를 가져와서 각 이미지들이 컨볼루션을 거치면서 어떤 특징을 추출하는지 시각화해보겠다.

Convolution 시각화

전체 모델에서 first Convolution > first Pooling > second Convolution > second Pooling 까지, 각 layer마다 output을 가져와 시각화하려 한다.

  • 참고로 padding은 하지 않았고, stride도 기본값=1이기 때문에 첫번째 층을 거친 이미지의 dimension은 (28,28)에서 ((283+1)/1(28-3+1)/1, (283+1)/1(28-3+1)/1) = (26,26)으로 줄어든다.

  • 총 64개의 필터를 이용했으므로 4D로 표현하면 (m, 26, 26, 64)이다. m은 이미지 개수, 64는 필터개수를 나타낸다.

  • CONVOLUTION_NUMBER=2064개의 필터중, 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)이다.
  • 두번째 layer와 네번째 layer는 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=40

40 번째 컨볼루션 필터(CONVOLUTION_NUMBER=40)은 '수직적인 라인의 특징을 detect'한다고 유추해 볼 수 있겠다.

profile
DEEP DIVER

0개의 댓글