iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0
AI Engineering

從 Pixel 到 AI:30 天影像辨識入門之路系列 第 13 篇

Day13 CNN 到底看到了什麼?Convolution、Kernel 與 Feature Map

  • 分享至 

  • xImage
  •  

上一篇我們知道,DNN 會先透過 Flatten 將圖片攤平成一串數字,而 CNN 則可以保留圖片原本的空間結構,從局部區域學習影像特徵
但這裡就出現了一個新的問題:CNN 到底是怎麼從圖片中找到這些特徵的?

我們常說 CNN 可以找到圖片中的「邊緣」、「紋理」或「形狀」,但電腦並不是真的用眼睛去看,CNN 最核心的秘密,其實就是今天要介紹的:Convolution(卷積)


一、先從一張很小的圖片開始

前面我們知道,圖片對電腦來說就是一個由數字組成的矩陣
假設今天有一張非常小的灰階圖片:

1   1   1   0   0
1   1   1   0   0
1   1   1   0   0
0   0   0   1   1
0   0   0   1   1

CNN 不會一次把整張圖片全部攤平,而是會拿一個比較小的矩陣,在圖片上逐步移動。這個小矩陣就叫做Kernel(卷積核),也常稱為 Filter(濾波器)


二、Kernel 是什麼?

假設我們現在有一個 3 × 3 的 Kernel:

1   0  -1
1   0  -1
1   0  -1

而圖片的其中一個 3 × 3 區域是:

1   1   1
1   1   1
1   1   1

Convolution 會把兩個矩陣對應位置的數值相乘,再全部加起來

(1×1) + (1×0) + (1×-1)
+
(1×1) + (1×0) + (1×-1)
+
(1×1) + (1×0) + (1×-1)
= 0

接著 Kernel 不會停在這裡,而是繼續往圖片的下一個位置移動,再進行相同的計算


三、Convolution 就像拿著小視窗掃過圖片

Kernel 會先看其中一個區域,計算完成之後,再往旁邊移,就像拿著一個小視窗,在圖片上一格一格地掃描,這也是 CNN 可以觀察局部區域的重要原因
https://ithelp.ithome.com.tw/upload/images/20260925/20169251cXqevkPL37.png


四、那 Kernel 裡面的數字是誰決定的?

說到這邊,你一定很好奇 Kernel 裡面的 1、0、-1 是我們自己設定的嗎?如果是傳統影像處理,我們確實可以人工設計 Kernel,例如用特定 Kernel 偵測邊緣,但在 CNN 中,Kernel 裡面的數值通常不是我們一個一個手動設定

它們是模型在訓練過程中學習出來的參數,一開始 Kernel 的 Weight 可以從初始化值開始,接著模型根據預測結果與正確 Label 之間的誤差,不斷更新這些數值,所以 CNN 真正學習的其中一部分,其實就是在判斷哪些 Kernel 數值可以找出對分類有幫助的特徵


五、Stride:Kernel 一次走幾格?

Kernel 在圖片上移動時,還有一個重要的設定就是Stride(步幅),Stride 代表 Kernel 每次移動多少格

例如:Stride = 1

就是每次移動一格,Stride 越大,Kernel 掃描的位置通常越少,最後產生的 Feature Map 空間尺寸也會比較小


六、最後得到的 Feature Map 是什麼?

Kernel 把整張圖片掃過一次之後,每一個位置都會得到一個新的數值,把這些數值重新排列起來,就會形成 Feature Map(特徵圖)

Feature Map 可以看成是圖片經過某個 Filter 處理後產生的新表示,其中會反映這個 Filter 對不同位置的反應程度

例如某個 Kernel 經過訓練後,可能會對某些邊緣特徵產生較強的反應,那麼這些位置在 Feature Map 中就會出現不同的數值


七、一個 Kernel 就夠了嗎?

以我們的資料為例,一張皮膚病灶圖片裡可能包含很多不同的資訊,例如:邊緣、紋理、顏色變化、局部形狀

所以 CNN 通常不會只有一個 Filter,而是會同時學習很多個不同的 Filter

每個 Filter 都有自己學習到的 Weight,因此可能會對不同的影像模式產生不同反應,這些 Feature Map 再繼續傳到下一層,讓後面的 CNN Layer 組合出更複雜的特徵
https://ithelp.ithome.com.tw/upload/images/20260925/20169251z8MckwZ5zR.png


八、在 TensorFlow 裡怎麼寫?

tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), activation="relu")

看完前面的,再來看看程式碼,是不是容易很多呢
filters=32 代表使用 32 個 Filter,會產生 32 個輸出 Feature Map
kernel_size=(3, 3)代表每個 Kernel 的空間大小是 3 × 3
strides=(1, 1)每次水平、垂直移動 1 格
activation="relu" 使用 ReLU Activation Function


上一篇
Day12 一般神經網路不夠嗎?CNN 為什麼特別適合看圖片?
下一篇
Day14 Pooling 為什麼要把圖片越變越小?
系列文
從 Pixel 到 AI:30 天影像辨識入門之路 共 15 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言