Numpy 筆記-#01 卷積神經網路的Padding

如果你有恆心、毅力僅使用Numpy打造自己的卷積神經網路(CNN)就一定會碰到一個問題,CNN裡面會用到的Padding該怎麼實作?其實Numpy已經幫你準備好這項功能(當然這個功能應該不僅止於此)。總之,本文就是來教該如何使用numpy.pad( )。

練習範例同步放置於GitHub:Learn NumPy – GitHub

語法

Padded_array=np.pad( array=欲加入padding的矩陣, pad_width=矩陣的哪些維度加入padding, mode=填充值的模式, constant_values=填充固定數值 ) :這就是用來加入padding的函數,其中特別需要注意的是constant_value,這是當 mode=’constant’ 的時候用來搭配使用的設定,用途就是填充『固定值』的用法,而填充固定值正是卷積神經網路的Padding會使用到的功能

然而,填充數值的方式還有很多種,建議各位可以先學會固定值模式,也有益於再去學習別種填充模式。

基礎-2維矩陣(無Channel)

我們使用一個 (3, 3) 的2維矩陣,在它的四周加入數值為0,大小=1的padding。
此例子需要填充固定值,所以這兩個設定基本上是不變的:mode=’constant’、constant_values=0

對於初次學習numpy.pad的人來說,學習重點將會在於pad_width的設定,也因此本文將會針對這個屬性設定的用法加以說明
此範例有2個維度,所以pad_width要有兩個維度的設定值,所以我們先建立一個2維度的tuple:( ( ), ( ) )。這個tuple內的數值設定有個原則,就是每個維度都要分別設定起始邊緣結束邊緣需要填充元素的數量。
依據此例子的需求,我們需要設定padding=1,就是起始與結束邊緣都填充1個元素,因此 pad_width=((1,1),(1,1))。

Output

中等-3維矩陣(Channel first)

Channel是啥?
Channel指的是圖片內的三原色(RGB)通道,假設一張$(5\times5)$的彩色圖片就會有3色通道,所以把這張圖片讀入python並轉成array,就會獲得一個$(5\times5\times3)$的矩陣,其中3就是channel。

那Channel first的意思?
指的是讀入Python的圖片矩陣的三原色通道是在第一個維度還是在最後的維度?以上述例子來說,$(5\times5\times3)$的矩陣就是Channel last,然而$(3\times5\times5)$的矩陣就代表了Channel first,另外值得一提的是圖片通常都是Channel last,但是如果直接將圖片矩陣以數值的形式print出來,則以Channel first比較易懂。

 

Channel$=1$

你可能會覺得 1 個Channel的$3\times3$圖片跟前一個例子有什麼差別?
差異可大了,因為多一個維度——Channel。
首先,我們要認清一點,Channel這個維度是不需要 padding 的,我們僅需要在『內容』的部分加入 padding,也就是在$3\times3$的像素邊緣加入 padding 就好。所以,pad_width 就需要在 Channel 的維度給予 (0,0) 的設定值囉。按照維度依序排列 pad_width=( (0,0), (1,1), (1,1) ),簡單吧!

Output

 

Channel$=3$

贊助廣告

本範例是 1 個 3-Channel 的範例,設定也跟上述一樣,因為只要僅有 1 張照片,要幾個 Channel 的設定都一樣並不會增加維度。
所以,pad_width=( (0,0), (1,1), (1,1) ),跟上一個例子一樣。

Output

 

多張Channel$=3$的照片(4維矩陣)

是的,多張照片的情況下,肯定會多 1 個維度,但是pad_width的設定原則很簡單,僅需在圖片像素的維度加入填充像素即可。因此,pad_width=( (0,0), (0,0), (1,1), (1,1) )

Output

高級-3維矩陣(Channel last)

Channel last

因為真的沒辦法直接 print 就能看出你的 padding 結果正確與否 😀

我會在此例子直接把 $(3\times3\times3)$ 的小圖顯示出來,作為padding正確與否的確認方式。我先設計了一張原始圖,原圖的中間都是白色的。最後在這個小圖的周圍填充 0 的邊緣,這個邊緣畫出來應該是黑色,因為色碼 #000000 為黑色,反之 #FFFFFF 即為白色。

然而,我們來分析此例子的矩陣維度配置順序 ( (圖片張數, 圖高, 圖寬, Channel) ),我們僅需要在圖片真正構成像素的部分進行填充像素即可,所以 pad_width=( (0,0), (1,1), (1,1), (0,0) )。是不是很簡單?? 😀

Output

Numpy padding example

 

Reference

numpy.pad – SciPy.org

Andy Wang

站在巨人的肩膀上仍須戰戰兢兢!

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料