Visualizing Kernels and Feature Maps in Deep Learning Model (CNN)

Pattharadet Vachirapuchai
7 min readOct 20, 2020

CNN (Convolutional Neural Network) เป็นโครงสร้างภายใน Deep Learning Model ที่ใช้แนวคิดของ Convolution ในการทำงานกับข้อมูล 2 มิติ เช่น Image Data ซึ่งแต่ละ Pixel ของ Image จะมีความสัมพันธ์กันในเชิงพื้นที่ (Spatial Relationship)

ด้วยลักษณะโครงสร้างของ CNN ที่ถูกออกแบบมาเพื่อทำงานกับ Image Data ในตอนเริ่มต้น เราจึงสามารถแสดงข้อมูลที่เป็นองค์ประกอบของการตัดสินใจหรือการทำนายของ Model ด้วยภาพได้ดีกว่า Neural Network ชนิดอื่นๆ ที่จะไม่สามารถแสดงให้เห็นและอธิบายเหตุผลได้ว่าทำไมมันจึงมีการตัดสินใจหรือคาดคะเนผลลัพธ์ออกมาแบบนั้น

CNN ประกอบด้วย Kernel และผลลัพธ์จากการกระทำทางคณิตศาสตร์ของ Kernel กับ Input Image ที่เรียกว่า Activation Map หรือ Feature Map โดยทั้ง Kernel และ Feature Map นั้นสามารถแสดงผลได้ด้วยภาพ

2D Convolution เป็นการนำ Matrix ขนาดเล็ก ของ Weight หรือที่เรียกว่า Kernel มา Slide ไปบน 2D Input Image (สีฟ้าด้านบนซ้ายมือ) โดยขณะที่มีการทาบ Kernel บน Input Image มันจะคูณค่าแต่ละ Pixel ของ Input Image กับ Kernel แล้วนำผลลัพธ์ทั้งหมดมาบวกกันเป็น 1 จุด Pixel ของ Feature Map (สีเขียวขวามือ)

2D Convolution ที่มีการสร้าง Feature Map ขึ้นมาด้วยการนำ Kernel Slide ไปบน Input Image จะใช้ Parameter น้อยกว่า Fully Connected Layer

Padding

ตามภาพด้านบน ขณะที่มีการ Slide Kernel เราจะเห็นว่า Pixel ตรงขอบภาพสีฟ้าจะไม่มีทางอยู่ตรงกลาง Kernel ตอนที่มันทาบลงไป เพราะเราไม่สามารถขยาย Kernel ให้เลยออกไปนอกขอบของภาพ จึงทำให้ Feature Map ที่ได้มีขนาดเล็กกว่า Input Image

ดังนั้น เพื่อจะทำให้ Feature Map มีขนาดเท่ากับ Input Image และ Pixel ที่ขอบภาพอยู่ตรงกลาง Kernel ตอนที่มันทาบลงไป เราจะต้องมีการทำ Padding โดยการเสริมกรอบด้วยการเติม 0 (Zero Padding) รอบๆ ภาพเดิม

Striding

การ Striding เป็นกระบวนการในการทำ Convolution โดยการเลื่อนแผ่น Kernel ไปบน Input Image ซึ่งโดย Default ของ Convolution แล้ว Stride จะมีค่าเท่ากับ 1 คือจะมีการเลื่อน Kernel ไปบน Input Image ครั้งละ 1 Pixel

เราสามารถลดขนาดของภาพที่แต่ละ Pixel มีความสัมพันธ์กันในเชิงพื้นที่ได้โดยการเพิ่มค่า Stride ซึ่งเมื่อมีการกำหนดค่า Stride มากขึ้น จะทำให้การเลื่อมกันของ Kernel ตอนที่มีการทาบกับ Input Image และขนาดของ Feature Map ลดลง

เมื่อกำหนด Stride เท่ากับ 2 แล้ว Kernel ขนาด 3x3 จะถูก Slide ข้าม Pixel ของ Input Image ขนาด 5x5 ทีละ 2 Pixel ทำให้ได้ Feature Map ขนาด 2x2 ดังภาพด้านล่าง

Pooling

นอกจากการลดขนาดของภาพด้วยการเพิ่มค่า Stride โดยการ Slide Kernel ข้าม Pixel ของ Input Image ตามระยะทางที่กำหนดแล้ว ยังมีอีกวิธีหนึ่งในการลดขนาดของภาพ คือการทำ Max Pooling หรือ Average Pooling โดย Pooling จะเป็นกระบวนการทำงานภายนอก CNN Layer

Max Pooling หรือ Average Pooling จะเป็นการเลือกตัวแทนของภาพด้วยการหาค่ามากที่สุด หรือค่าเฉลี่ยจาก Pixel ใน Window ตามขนาดที่กำหนด เช่น ขนาด 2x2 ซึ่งจะทำให้มีการลดขนาดของภาพลงได้ครึ่งหนึ่งดังตัวอย่างด้านบน

Multi-channel

ใช้จัดการกับ Input Image แบบ 3 Channel เช่นภาพสีในระบบ RGB จะต้องใช้ Kernel จำนวน 3 ตัว ในการ Slide ไปบน Input Image แต่ละ Channel ซึ่งเราเรียก Kernel ทั้ง 3 ตัวว่า Filter (ในที่นี้ 1 Filter ประกอบด้วย 3 Kernel)

Feature Map แต่ละ Version ขนาด 3x3 ที่เกิดจากการ Slide Kernel ไปบน Input Channel ขนาด 5x5 จะถูกนำมารวมกันเป็น Output Channel 1 Channel เพื่อจะส่งต่อไปยัง Neural Network Layer ถัดไป

Output Channel จะถูกนำมาบวกกับ Bias ในขั้นตอนสุดท้ายของกระบวนการทำ Convolution

การสร้าง Output Channel 1 Channel ตามภาพด้านบน จะต้องใช้ Filter 1 Filter ซึ่งแต่ละ Filter ก็จะประกอบด้วยจำนวน Kernel 3 Kernel ดังนั้นถ้าต้องการสร้าง Output Channel หลาย Channel เราจะต้องมีจำนวน Filter หลาย Filter

มาเริ่มกันเลยครับ

เข้า Google Colab

Import Library

from tensorflow.keras.layers import Dense, Flatten, Conv2D, Dropout, Activation, BatchNormalization, MaxPooling2D

from tensorflow.keras.models import Sequential

from tensorflow.keras.optimizers import Adam

import tensorflow as tf

from tensorflow.keras.datasets import fashion_mnist

from tensorflow.keras.utils import to_categorical

from tensorflow.keras.preprocessing.image import ImageDataGenerator

from tensorflow.keras.callbacks import ModelCheckpoint

from tensorflow.python.keras.models import load_model

from sklearn.model_selection import train_test_split

import numpy as np

import matplotlib.pyplot as plt

import plotly.graph_objs as go

from plotly import tools

import plotly

import cv2

from keras.callbacks import ModelCheckpoint

%matplotlib inline

อ่านไฟล์ภาพ

cat = cv2.imread(‘cat.jpg’)
cat.shape

แปลงระบบสีจาก BGR ซึ่งเป็นค่า Default ของ OpenCV Library เป็น RGB

cat = cv2.cvtColor(cat, cv2.COLOR_RGB2BGR)

Plot รูป

plt.figure(dpi=100)
plt.imshow(cat)
cat.shape

Create a Model with 2D CNN Layer

  • นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,440x1,080 Pixel แบบ 3 Channel โดยมี Filter ขนาด 3x3 จำนวน 3 Filter เพื่อนำไป Slide บน Input Image ของแต่ละ Channel

Model ของเราจะมีจำนวน Parameter เท่ากับ (Filter + Bias) 3x3x3x3 + 3 = 84 Parameter

model = Sequential()
model.add(Conv2D(3, # number of filter layers
(3, # y dimension of kernel
3), # x dimension of kernel
input_shape=cat.shape))
model.summary()

ขยายมิติของภาพจาก 3 มิติเป็น 4 มิติ เพื่อเตรียมนำเข้า Predict Function

cat_batch = np.expand_dims(cat,axis=0)
cat_batch.shape

predict Model โดยใช้ค่า Weight และ Bias แบบสุ่มในตอนเริ่มต้น โดยยังไม่มีการ Train Model

conv_cat = model.predict(cat_batch)
conv_cat.shape

นิยาม visualize_cat Function ที่รับภาพเป็น Matrix, ขยายภาพเป็น 4 มิติ แล้ว Predict ภาพ ก่อนจะหดให้เหลือ 3 มิติเท่าเดิมเพื่อจะ Plot ภาพต่อไป

def visualize_cat(model, cat):
cat_batch = np.expand_dims(cat,axis=0)
conv_cat = model.predict(cat_batch)
conv_cat = np.squeeze(conv_cat, axis=0)
print(conv_cat.shape)
conv_cat = cv2.cvtColor(conv_cat, cv2.COLOR_RGB2BGR)
plt.imshow(conv_cat)

Plot รูป

visualize_cat(model, cat)

นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,440x1,080 Pixel แบบ 3 Channel โดยมี Filter ขนาด 10x10 จำนวน 3 Filter เพื่อนำไป Slide บน Input Image แต่ละ Channel

model = Sequential()
model.add(Conv2D(3,(10, 10), input_shape=cat.shape))
model.summary()

จากภาพ Model จะเห็นว่ามีจำนวน Parameter เท่ากับ (Filter + Bias) (10x10x3x3) + 3 = 903 Parameter

Plot รูป

visualize_cat(model, cat)

นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,440x1,080 Pixel แบบ 3 Channel โดยมี Filter ขนาด 3x3 จำนวน 1 Filter

model = Sequential()
model.add(Conv2D(1,(3,3),input_shape=cat.shape))
model.summary()

จากภาพ Model จะเห็นว่ามีจำนวน Parameter เท่ากับ (Filter + Bias) (3x3x3x1) + 1= 28 Parameter

นิยาม visualize_cat_one_channel Function ที่รับภาพเป็น Matrix ขยายภาพเป็น 4 มิติ แล้ว Predict ภาพ ก่อนจะหดให้เหลือ 2 มิติ เพื่อจะ Plot ภาพ แบบ 1 Channel ต่อไป

def visualize_cat_one_channel(model, cat):
cat_batch = np.expand_dims(cat,axis=0)
conv_cat2 = model.predict(cat_batch)
conv_cat2 = np.squeeze(conv_cat2, axis=0)
conv_cat2 = conv_cat2.reshape(conv_cat2.shape[:2])
plt.imshow(conv_cat2)

Plot รูป

visualize_cat(model, cat)

นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,440x1,080 Pixel แบบ 3 Channel โดยมี Filter ขนาด 20x20 จำนวน 1 Filter

model = Sequential()
model.add(Conv2D(1,(20,20),input_shape=cat.shape))
model.summary()

จากภาพ Model จะเห็นว่ามีจำนวน Parameter เท่ากับ (Filter + Bias) (20x20x3x1) + 1= 1201 Parameter

Plot รูป

visualize_cat_one_channel(model, cat)

นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,440x1,080 Pixel แบบ 3 Channel โดยมี Filter ขนาด 20x20 จำนวน 1 Filter และเพิ่ม ReLu Activation Function

model = Sequential()
model.add(Conv2D(1,(20,20),input_shape=cat.shape))model.add(Activation('relu'))
model.summary()

Plot รูป

visualize_cat_one_channel(model, cat)

นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,440x1,080 Pixel แบบ 3 Channel โดยมี Filter ขนาด 3x3 จำนวน 1 Filter และเพิ่ม Max Pooling ขนาด 5x5

model = Sequential()

model.add(Conv2D(1,(3,3),input_shape=cat.shape))

model.add(Activation(‘relu’))

model.add(MaxPooling2D(pool_size=(5,5)))

Plot รูป

visualize_cat_one_channel(model, cat)

นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,440x1,080 Pixel แบบ 3 Channel โดยมี Filter ขนาด 3x3 จำนวน 1 Filter เพิ่ม ReLu Activation Function และ Max Pooling ขนาด 5x5

model = Sequential()

model.add(Conv2D(1,(3,3),input_shape=cat.shape))

model.add(MaxPooling2D(pool_size=(5,5)))

model.summary()

Plot รูป

visualize_cat_one_channel(model, cat)

นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,440x1,080 Pixel แบบ 3 Channel โดยมี Filter ขนาด 3x3 จำนวน 1 Filter เพิ่ม ReLu Activation Function และ Max Pooling ขนาด 5x5

model = Sequential()

model.add(Conv2D(1,(3,3),input_shape=cat.shape))

model.add(Activation(‘relu’))

model.add(MaxPooling2D(pool_size=(5,5)))

Plot รูป

visualize_cat_one_channel(model, cat)

จบแลล้วนะครับสำหรับ Visualizing Kernels and Feature Maps in Deep Learning Model (CNN)

--

--