Visualizing Kernels and Feature Maps in Deep Learning Model (CNN) with Google Colab(Python Language)
Convolutional Neural Network (CNN) หรือ โครงข่ายประสาทแบบคอนโวลูชัน เป็นโครงข่ายประสาทเทียมโดยที่ CNN จะจำลองการมองเห็นของมนุษย์ที่มองพื้นที่เป็นที่ย่อยๆ และนำกลุ่มของพื้นที่ย่อยๆมาผสานกัน เพื่อดูว่าสิ่งที่เห็นอยู่คืออะไร
การมองพื้นที่ย่อยของมนุษย์จะมีการแยกคุณลักษณะ (feature) ของพื้นที่
ย่อยนั้น เช่น ลายเส้น และการตัดกันของสี ซึ่งการที่มนุษย์รู้ว่าพื้นที่ตรงนี้เป็นเส้นตรงหรือสีตัดกัน เพราะมนุษย์ดูทั้งจุดที่สนใจและบริเวณรอบ ๆ ประกอบกัน
การทำงานของ CNN
Convolutional Neural Network คือ Deep Learning อัลกอริทึม ที่จะรับ Input เป็นรูปภาพ แล้วเรียนรู้ Feature ต่าง ๆ ของรูปภาพเหล่านั้น ในแต่ละ Layer ต่อยอดขึ้นไปเรื่อย ๆ ตั้งแต่ จุด, เส้นแนวตั้ง, เส้นแนวนอน, เส้นแนวทแยง, กากบาท, มุม, เส้นโค้ง, วงกลม, พื้นผิว, ลวดลาย, ดวงตา, ใบหน้า, … ไปจนถึง วัตถุที่เรากำหนด
Input Image
MNIST Data Number 8 in Grayscale Pixel Value 0–1
รูปภาพที่อยู่ในคอมพิวเตอร์ ในกรณีรูปขาวดำ ก็คือ ข้อมูลตัวเลขความสว่าง 0–255 ที่นำมาจัดเรียงเป็น Matrix กว้าง x ยาว (Width x Height) จากตัวอย่าง MNIST ด้านบน ถ้าเป็นรูปสี ก็จะเป็น 3 Channel RGB กว้าง x ยาว x ลึก (Widgh x Height x Depth)
Feature Extraction
เริ่มจากการกำหนดค่าใน ตัวกรอง (filter) หรือ เคอร์เนล (kernel) ที่ช่วยดึงคุณลักษณะที่ใช้ในการรู้จำวัตถุออก โดยปกติตัวกรอง/เคอร์เนลอันหนึ่งจะดึงคุณลักษณะที่สนใจออกมาได้หนึ่งอย่าง เราจึงจำเป็นต้องตัวกรองหลายตัวกรองด้วย เพื่อหาคุณลักษณะทางพื้นที่หลายอย่างประกอบกัน
Filter
สำหรับ Filter ของภาพดิจิทัลนั้น โดยปกติแล้วจะเป็นตารางสองมิติที่มีขนาดตามพื้นที่ย่อยๆที่เราอยากพิจารณา
สมมุติว่าถ้าเราต้องการหาเส้นตรงทะแยงสีขาว ตัวกรองของเราอาจจะอยู่ในลักษณะนี้
ตำแหน่งตรงกลางที่มีกรอบสีฟ้าคือ Anchor ที่เอาไว้ทาบบนพิกเซลของภาพข้อมูลเข้า ตัวกรองจะถูกทาบลงในพิกเซลแรกของภาพข้อมูลเข้า จากนั้นจะถูกเลื่อนไปทาบ
บนพิกเซลอื่นในภาพทีละพิกเซลจนครบทุกพิกเซลในภาพ เราอาจจะไม่ทาบตัวกรองบนพิกเซลที่อยู่ใกล้กรอบภาพ เพราะตัวกรองจะล้นออกไปนอกภาพ เมื่อเราเลื่อนตัวกรองไปเรื่อยๆจนครบทุกพิกเซลที่สามารถเลื่อนได้ในภาพ สิ่งที่เราได้นั้นจะเป็นสิ่งที่เรียกว่า ผังคุณลักษณะ (feature map)
Padding
Padding จากรูปด้านล่างเราจะเติมพื้นที่สีเทารอบๆ Input โดยอาจจะเติมค่า 0 หรือค่าต่างๆเข้าไป เพื่อให้เวลาในการทำ CNN นั้น Feature Map ที่ได้ยังคงมีขนาดเท่ากับ Input
Striding
Striding เป็นตัวกำหนดว่าเราจะเลื่อนตัวกรอง (filter) ไปด้วย Step เท่าไร (ตัวอย่างด้านล่างกำหนด Stride เท่ากับ 1)
เราสามารถกำหนดค่าของ Stride ให้มากขึ้นได้ ถ้าเราต้องการให้การคำนวนหาคุณลักษณะมีพื้นที่ทับซ้อนกันน้อยขึ้น แต่อย่างไรก็ตามการกำหนดค่าของ Stride ที่มากขึ้นจะทำให้เราได้ผังคุณลักษณะ (feature map) ที่มีขนาดเล็กลง
Pooling
ความสามารถในการย่อรูปแบบหนึ่ง คือ Max Pooling หรือ Average Pooling
Max Pooling เป็นตัวกรองแบบหนึ่งที่หาค่าสูงสุดในบริเวณที่ตัวกรองทาบอยู่มาเป็นผลลัพธ์ใหม่ และจะเลื่อนตัวกรองไปตาม Stride
Multi-channel
การจัดการกับ Input Image แบบ 3 Channel อย่างเช่นภาพสีในระบบ RGB หรือก็คือ Rad Green Blue มีสามสีนั้นเอง ซึ่งเราจะต้องใช้ Kernel จำนวน 3 ตัว ในการ Slide ไปบน Input Image
วิธีการคำนวนเหมือนกับ single channel เลย
และหลัง kernel คำนวนเสร็จจะนำผลลัพธ์มารวมกันเป็นแผ่นเดียว เราจะเรียกว่า Output Channel 1 Channel ดังภาพด้านล่างนี้
ต่อไป Output Channel จะถูกนำมาบวกกับ Bias ในขั้นตอนสุดท้ายของกระบวนการทำ Convolution
Source: https://towardsdatascience.com
Visualizing CNN
- หากมี GPU สามารถ Config การใช้งาน ด้วยคำสั่งต่อไปนี้
!nvidia-smi -Limport tensorflow as tf
tf.__version__config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.compat.v1.Session(config=config)print( 'Tensorflow Version:', tf.__version__)
print("GPU Available::", tf.config.list_physical_devices('GPU'))
- Import library ที่จำเป็น
from tensorflow.python.keras.layers import Dense, Flatten, Conv2D, Dropout, Activation, BatchNormalization, MaxPooling2Dfrom tensorflow.python.keras.models import Sequentialfrom tensorflow.keras.optimizers import Adamfrom tensorflow.keras import Modelimport tensorflow as tffrom tensorflow.keras.datasets import fashion_mnistfrom tensorflow.keras.utils import to_categoricalfrom tensorflow.keras.preprocessing.image import ImageDataGeneratorfrom tensorflow.keras.callbacks import ModelCheckpointfrom tensorflow.python.keras.models import load_modelfrom sklearn.model_selection import train_test_splitimport numpy as npimport matplotlib.pyplot as pltimport plotly.graph_objs as gofrom plotly import toolsimport plotlyimport cv2from keras.callbacks import ModelCheckpoint%matplotlib inline
- อ่านภาพน้องแมว
import pathlibpath = "drive/My Drive/Colab Notebooks/aicat.jpg"data_dir = pathlib.Path(path)cat = cv2.imread(path)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,124x843 Pixelแบบ 3 Channel โดยมี Filter ขนาด 3x3 จำนวน 3 Filter เพื่อนำไป Slide บน Input Image ของแต่ละ Channel
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()
- นิยาม 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,124x843 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()
- Plot ภาพน้องแมว
visualize_cat(model, cat)
- นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,124x843 Pixel แบบ 3 Channel โดยมี Filter ขนาด 3x3 จำนวน 1 Filter
model = Sequential()
model.add(Conv2D(1,(3,3),input_shape=cat.shape))
model.summary()
- นิยาม 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_one_channel(model, cat)
- นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,124x843 Pixel แบบ 3 Channel โดยมี Filter ขนาด 20x20 จำนวน 1 Filter
model = Sequential()
model.add(Conv2D(1,(20,20),input_shape=cat.shape))
model.summary()
- Plot ภาพน้องแมว
visualize_cat_one_channel(model, cat)
- นิยาม Model แบบ 2D Convolution โดยรับ Input Image ขนาด 1,124x843 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,124x843 Pixelแบบ 3 Channel โดยมี Filter ขนาด 3x3 จำนวน 1 Filter และเพิ่ม 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,124x843 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)))
model.summary()
- Plot ภาพน้องตังค์ฟูล
visualize_cat_one_channel(model, cat)
- นิยาม Model แบบ 2D Convolution, ReLu Activation Function และ Max Pooling อย่างละ 2 Layer
model = Sequential()
model.add(Conv2D(1,(3,3),input_shape=cat.shape))model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(3,3)))model.add(Conv2D(1,(3,3)))model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(3,3)))
model.summary()
- Plot ภาพน้องแมว
visualize_cat_one_channel(model, cat)
ขอบคุณผู้อ่านทุกท่านที่อ่านมาจนถึงตรงนี้(งานเผาล้วนๆ) ขอตัวลาไปก่อน สวัสดีค่ะ