上一篇我們終於建立了第一個 DNN,成功將 HAM10000 的皮膚病灶圖片送進模型,並透過 Softmax 輸出 7 個類別的預測結果,不過,在建立模型時,我們使用了一個很重要的步驟:tf.keras.layers.Flatten()
它會將原本 (64, 64, 3) 的圖片攤平成 12,288 個數值,這樣確實可以讓 DNNk處理圖片,但問題來了,一張圖片不只是數字的集合,Pixel 之間的位置關係也很重要如果直接攤平成一長串數字,會不會失去一些重要資訊呢?
今天就從這個問題開始,認識專門用來處理影像的 CNN
先回顧上一篇建立的模型:
model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(64, 64, 3)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation="relu"),
tf.keras.layers.Dense(7, activation="softmax")
])
其中 Flatten() 會將圖片(64, 64, 3)轉換成一維資料(12288,),但假設我們正在觀察一張皮膚病灶圖片,病灶的邊界、形狀與周圍皮膚之間的差異,往往需要透過相鄰 Pixel 一起觀察才能發現
DNN雖然可以學習這些數值之間的關係,但 Flatten 之後,原本的二維排列不再被明確保留,模型也沒有特別針對相鄰 Pixel 的關係進行設計
而且,每個 Dense Neuron 都需要與前一層的所有輸入連接,例如上一篇的模型有12,288 個輸入 × 128 個 Neuron,光是這一層,就需要超過 157 萬個 Weight,因此,當圖片解析度越高,Dense Layer 需要學習的參數也可能快速增加
所以我們需要思考:有沒有一種模型,可以直接利用圖片原本的空間結構,而不是一開始就把它攤平?
Spatial Information(空間資訊),簡單來說就是圖片中各個 Pixel 之間的位置與排列關係,例如下面兩組數字:
圖片 A:
0 0 0
0 255 0
0 0 0
圖片 B:
255 0 0
0 0 0
0 0 0
兩張圖片都有一個數值為 255 的 Pixel,但因為它們的位置不同,呈現出來的圖案也不同,在真正的影像中,這種位置關係就更加重要,以皮膚病灶圖片為例,我們可能會想觀察:
這些特徵都和 Pixel 之間的空間關係有關,所以對影像辨識來說,不只是 Pixel 的數值重要,它們排列在什麼位置也同樣重要
CNN 的全名是Convolutional Neural Network(卷積神經網路)
它是一種特別適合處理影像等具有網格結構資料的神經網路,和前面直接使用 Flatten 的 Dense Neural Network 不同,CNN 可以先保留圖片的二維排列,透過 Convolution(卷積)逐步學習圖片中的局部特徵
例如,模型可以先從圖片中學習比較簡單的特徵從邊緣到紋理、局部形狀再到更複雜的影像特徵,最後再利用這些學到的特徵進行分類
以我們的 HAM10000 為例,CNN 的目的就是從圖片中學習有助於區分不同病灶類別的影像特徵,而不是只依靠人工指定每一張圖片要觀察什麼
| 比較項目 | Dense Neural Network | CNN |
|---|---|---|
| 圖片處理方式 | 通常先 Flatten | 先保留圖片的空間結構 |
| 特徵學習 | 從展平後的數值學習 | 從局部區域逐步學習 |
| 參數使用 | 每個 Neuron 連接所有輸入 | 卷積核可在不同位置重複使用 |
| 影像空間關係 | 沒有特別針對空間結構設計 | 專門利用局部空間關係 |
所以並不是 DNN不能處理圖片,而是 CNN 的模型設計更符合圖片本身具有空間結構的特性
前面講過DNN是怎麼便是圖片的,那麼 CNN 到底怎麼從一小塊 Pixel 中找到「邊緣」、「紋理」甚至更複雜的特徵?
這就會用到 CNN 最重要的核心之一:Convolution(卷積)
而在 Convolution 裡,我們又會遇到兩個很重要的名詞,Kernel(卷積核)與 Feature Map(特徵圖)
下一篇我們就可以直接從一個 3 × 3 Kernel 開始,看看它到底是怎麼在圖片上移動,又是怎麼從一堆 Pixel 中找出影像特徵的