第十一節,卷積神經網絡之卷積、填充、步長介紹(一)


一 計算機視覺

把神經網絡應用於計算機視覺時,有一個很大的挑戰,就是數據的輸入可能會非常大。舉個例子,在過去的課程中,你們一般操作的都是 64×64 的小圖片,實際上,它的數據量是 64×64×3,因為每張圖片都有 3 個顏色通道。如果計算一下的話,可得知數據量為 12288,所以我們的特征向量。

如果你要操作更大的圖片,比如一張 1000×1000 的圖片,它足有 1 兆那么大,但是特征向量的維度達到了 1000×1000×3,因為有 3 RGB 通道,所以數字將會是 300 萬。

 

如果你要輸入 300萬的數據量,這就意味着,特征向量x的維度高達300萬,所以在第一隱藏層中,你也許會有1000 個隱藏單元,而所有的權值組成了矩陣W 1 ,如果你使用了標准的全連接網絡,這個矩陣的大小將會是1000×300萬。這意味着矩陣W 1 會有 30億個參數,這是個非常巨大的數字。在參數如此大量的情況下,難以獲得足夠的數據來防止神經網絡發生過擬合和競爭需求,要處理包含 30 億參數的神經網絡, 巨大的內存需求讓人不能接受。
但對於計算機視覺應用來說,你肯定不想它只處理小圖片,你希望它同時也要能處理大圖。為此,你需要進行卷積計算,它是卷積神經網絡中非常重要的一塊 。

二 邊緣檢測

如何在一張圖片中進行邊緣檢測。

讓我們舉個例子,給了這樣一張圖片,讓電腦去搞清楚這張照片里有什么物體,你可能做的第一件事是檢測圖片中的垂直邊緣。比如說,在這張圖片中的欄桿就對應垂直線,與此同時,這些行人的輪廓線某種程度上也是垂線,這些線是垂直邊緣檢測器的輸出。同樣,你可能也想檢測水平邊緣,比如說這些欄桿就是很明顯的水平線,它們也能被檢測到,結果在這。所以如何在圖像中檢測這些邊緣?

看一個例子,這是一個 6×6 的灰度圖像。因為是灰度圖像,所以它是 6×6×1 的矩陣,而不是 6×6×3 的,因為沒有 RGB 三通道。為了檢測圖像中的垂直邊緣,你可以構造一個 3×3矩陣。 對這個 6×6 的圖像進行卷積運算, 卷積運算用來表示, 用 3×3的過濾器對其進行卷積 。

 

這個卷積運算的輸出將會是一個 4×4 的矩陣,你可以將它看成一個 4×4 的圖像。下面來說明是如何計算得到這個 4×4 矩陣的。為了計算第一個元素,在 4×4 左上角的那個元素,使用 3×3 的過濾器,將其覆蓋在輸入圖像,如下圖所示。然后進行元素乘法(element-wiseproducts)運算 。計算如下3x1+0x0+1x(-1)+1x1+5x0+8x(-1)+2x1+7x0+2x(-1)=-5。

把藍色的方塊,向右移動一步,同理,我們就能夠得到第一行第二列的值。

 繼續向右移動,直到把藍色方塊移動到最右邊,到此,我們會得到如下結果:

接下來為了得到下一行的元素,現在把藍色塊下移,現在藍色塊在這個位置 :

重復進行元素乘法,然后加起來。通過這樣做得到-10。再將其右移得到-2,接着是 23。以此類推,這樣計算完矩陣中的其他元素。

為什么這個可以做垂直邊緣檢測呢?讓我們來看另外一個例子。為了講清楚,我會用一個簡單的例子。這是一個簡單的 6×6 圖像,左邊的一半是 10,右邊一般是 0。如果你把它當成一個圖片,左邊那部分看起來是白色的,像素值 10 是比較亮的像素值,右邊像素值比較暗,我使用灰色來表示 0,盡管它也可以被畫成黑的。圖片里,有一個特別明顯的垂直邊緣在圖像中間,這條垂直線是從黑到白的過渡線,或者從白色到深色。

所以,當你用一個 3×3 過濾器進行卷積運算的時候,這個 3×3 的過濾器可視化為下面這個樣子,在左邊有明亮的像素,然后有一個過渡, 0 在中間,然后右邊是深色的。如果把最右邊的矩陣當成圖像,它是這個樣子。在中間有段亮一點的區域,對應檢查到這個 6×6 圖像中間的垂直邊緣。這里的維數似乎有點不正確,檢測到的邊緣太粗了。因為在這個例子中,圖片太小了。如果你用一個 1000×1000 的圖像,而不是 6×6 的圖片,你會發現其會很好地檢測出圖像中的垂直邊緣。 在這個 6×6 圖像的中間部分,明亮的像素在左邊,深色的像素在右邊,就被視為一個垂直邊緣,卷積運算提供了一個方便的方法來發現圖像中的垂直邊緣 。

三 更多邊緣檢測

上一小節中,你已經見識到用卷積運算實現垂直邊緣檢測,在本節,你將學習如何區分正邊和負邊,這實際就是由亮到暗與由暗到亮的區別,也就是邊緣的過渡。你還能了解到其他類型的邊緣檢測以及如何去實現這些算法,而不要總想着去自己編寫一個邊緣檢測程序,讓我們開始吧。

還是上一個小節中的例子,這張 6×6 的圖片,左邊較亮,而右邊較暗,將它與垂直邊緣檢測濾波器進行卷積,檢測結果就顯示在了右邊這幅圖的中間部分。

現在這幅圖有什么變化呢?它的顏色被翻轉了,變成了左邊比較暗,而右邊比較亮。現在亮度為 10 的點跑到了右邊,為 0 的點則跑到了左邊。如果你用它與相同的過濾器進行卷積,最后得到的圖中間會是-30,而不是 30。如果你將矩陣轉換為圖片,就會是該矩陣下面圖片的樣子。現在中間的過渡部分被翻轉了,之前的 30 翻轉成了-30,表明是由暗向亮過渡,而不是由亮向暗過渡

之前我們講解的3x3的過濾器,能夠對垂直邊緣進行檢測,現在我們再來看看右邊這個過濾器,我想你應該猜出來了,它能讓你檢測出水平的邊緣。提醒一下,一個垂直邊緣過濾器是一個 3×3 的區域,它的左邊相對較亮,而右邊相對較暗。相似的,右邊這個水平邊緣過濾器也是一個 3×3 的區域,它的上邊相對較亮,而下方相對較暗 。

這里還有個更復雜的例子,左上方和右下方都是亮度為 10 的點。如果你將它繪成圖片,右上角是比較暗的地方,這邊都是亮度為 0 的點,我把這些比較暗的區域都加上陰影。而左上方和右下方都會相對較亮。如果你用這幅圖與水平邊緣過濾器卷積,就會得到右邊這個矩陣。

再舉個例子,這里的 30(右邊矩陣中綠色方框標記元素)代表了左邊這塊 3×3 的區域(左邊矩陣綠色方框標記部分),這塊區域確實是上邊比較亮,而下邊比較暗的,所以它在這里發現了一條正邊緣。而這里的-30(右邊矩陣中紫色方框標記元素)又代表了左邊另一塊區域(左邊矩陣紫色方框標記部分),這塊區域確實是底部比較亮,而上邊則比較暗,所以在這里它是一條負邊。

再次強調,我們現在所使用的都是相對很小的圖片,僅有 6×6。但這些中間的數值,比如說這個 10(右邊矩陣中黃色方框標記元素)代表的是左邊這塊區域(左邊 6×6 矩陣中黃色方框標記的部分)。這塊區域左邊兩列是正邊,右邊一列是負邊, 正邊和負邊的值加在一 起得到了一個中間值。但假如這個一個非常大的 1000×1000 的類似這樣棋盤風格的大圖,就不會出現這些亮度為 10 的過渡帶了,因為圖片尺寸很大,這些中間值就會變得非常小。

總而言之,通過使用不同的過濾器,你可以找出垂直的或是水平的邊緣。但事實上,對於這個 3×3 的過濾器來說,我們使用了其中的一種數字組合 。

但在歷史上,在計算機視覺的文獻中,曾公平地爭論過怎樣的數字組合才是最好的,上圖中間的叫做 Sobel 的過濾器,它的優點在於增加了中間一行元素的權重,這使得結果的魯棒性會更高一些。 但計算機視覺的研究者們也會經常使用其他的數字組合,比如上圖右邊這個,這叫做 Scharr 過濾器,它有着和之前完全不同的特性,實際上也是一種垂直邊緣檢測,如果你將其翻轉 90 度,你就能得到對應水平邊緣檢測。
隨着深度學習的發展,我們學習的其中一件事就是當你真正想去檢測出復雜圖像的邊緣,你不一定要去使用那些研究者們所選擇的這九個數字,但你可以從中獲益匪淺。把這矩陣中的 9 個數字當成 9 個參數,並且在之后你可以學習使用反向傳播算法,其目標就是去理解這9 個參數 。通過數據反饋,讓神經網絡自動去學習它們,我們會發現神經網絡可以學習一些低級的特征,例如這些邊緣的特征。盡管比起那些研究者們,我們要更費勁一些,但確實可以動手寫出這些東西。不過構成這些計算的基礎依然是卷積運算,使得反向傳播算法能夠讓神經網絡學習任何它所需要的 3×3 的過濾器,並在整幅圖片上去應用它。

除了檢測邊緣外,我們想檢測到更多的特征怎么辦?多個隱藏層讓深度神經網絡能夠表示數據中更為復雜的特征,例如:在用深度卷積神經網絡(CNN)進行人臉識別時,較為底層的隱藏層首先提取的是圖片中一些邊緣和界面的特征,隨着層級的提高,圖片中一些紋理的特征可能會顯現,而隨着層級繼續提高,一些具體的對象將會顯現,例如:眼睛、鼻子、耳朵等,再到更高層時,整個人臉的特征也就被提取了出來。在一個深度神經網絡上,較高層的特征是低層特征的組合,而隨着神經網絡從低層到高層,其提取的特征也越來越抽象、越來越涉及“整體”的性質。 

四 Padding

為了構建深度神經網絡,你需要學會使用的一個基本的卷積操作就是 padding,讓我們來看看它是如何工作的。

之前我們講到,如果你用一個 3×3 的過濾器卷積一個 6×6 的圖像,你最后會得到一個 4×4 的輸出,也就是一個 4×4 矩陣。這背后的數學解釋是,如果我們有一個nxn的圖像,用fxf的濾波器 做卷積,最后你會得到一個(n-f+1)x(n-f+1)的輸出。

這么做會有兩個缺點:

  • 第一個缺點是每次做卷積操作,你的圖像就會縮小
  • 第二個缺點時,如果你注意角落邊緣的像素,這個像素點(綠色陰影標記)只被一個輸出所觸碰或者使用,因為它位於這個 3×3 的區域的一角。但如果是在中間的像素點,比如這個(紅色方框標記),就會有許多 3×3 的區域與之重疊。所以那些在角落或者邊緣區域的像素點在輸出中采用較少,意味着你丟掉了圖像邊緣位置的許多信息

為了解決這些問題,你可以在卷積操作之前填充這幅圖像。 在這個案例中,你可以沿着圖像邊緣再填充一層像素。

習慣上,你可以用 0 去填充,如果 p是填充數量,在這個案例中p=1,因為我們在周圍都填充了一個像素點,輸出也就變成了 (n+2p-f+1)x(n+2p-f+1),即6x6輸出和輸入一樣。這個塗綠的像素點(左邊矩陣)影響了輸出中的這些格子(右邊矩陣)。這樣一來,丟失信息或者更准確來說角落或圖像邊緣的信息發揮的作用較小的這一缺點就被削弱了。
如果你想的話,也可以填充兩個像素點, 實際上你還可以填充更多像素 。

至於選擇填充多少像素,通常有兩個選擇,分別叫做 Valid 卷積和 Same 卷積。

Valid 卷積意味着不填充,這樣的話,如果你有一個nxn的圖像,和f xf的過濾器做卷積,你會得到(n-f+1)x(n-f+1)維的輸出。

Same 卷積,那意味你填充后,你的輸出大小和輸入大小是一樣的 。根據公式n-f+1,當你填充p個像素點,圖像原有的n變成了n+2p,最后輸出變成了n+2p-f+1。因此如果你有一個nxn的圖像,用p個像素填充,輸出的大小就是(n+2p-f+1)x(n+2p-f+1)。如果要是使n+2p-f+1=n,那么p=(f-1)/2,所以當f是一個奇數的時候,只要選擇相應的填充尺寸,你就能確保得到和輸入相同尺寸的輸出。 (推薦使用奇數的過濾器)

 五 卷積步長

卷積中的步幅是另一個構建卷積神經網絡的基本操作。 

如果你想用 3×3 的過濾器卷積這個 7×7 的圖像,和之前不同的是,我們把步幅設置成了2。你還和之前一樣取左上方的 3×3 區域的元素的乘積,再加起來,最后結果為 91 。

只是之前我們移動藍框的步長是 1,現在移動的步長是 2,我們讓過濾器跳過 2 個步長,注意一下左上角,這個點移動到其后兩格的點,跳過了一個位置。然后你還是將每個元素相乘並求和,你將會得到的結果是 100

現在我們繼續,將藍色框移動兩個步長,你將會得到 83 的結果。當你移動到下一行的 時候,你也是使用步長 2 而不是步長 1,所以我們將藍色框移動到這里:

注意到我們跳過了一個位置,得到 69 的結果,現在你繼續移動兩個步長,會得到 91127,最后一行分別是 447274

所以在這個例子中,我們用 3×3 的矩陣卷積一個 7×7 的矩陣,得到一個 3×3 的輸出。輸入和輸出的維度是由下面的公式決定的。 如果你用一個 fxf的過濾器和nxn的圖像做卷積,padding設置為p,stride設置為s,輸出則為(n+2p-f)/s+1 x (n+2p-f)/s+1



現在只剩下最后的一個細節了,如果商不是一個整數怎么辦?在這種情況下,我們向下取整,即 向下取整到最近的整數 ,這個原則實現的方式是,你只在藍框完全包括在圖像或填充完的圖像內部時,才對它進行運算。如果有任意一個藍框移動到了外面,那你就不要進行相乘操作。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM