深度學習(四)卷積神經網絡-卷積神經網絡(1) -Andrew Ng

一、基礎知識

1.1 計算機視覺

視覺應用:

計算機視覺是一個飛速發展的一個領域,這多虧了深度學習。深度學習與計算機視覺可以幫助汽車,查明周圍的行人和汽車,並幫助汽車避開 它們。還使得人臉識別技術變得更加效率和精準,你們即將能夠體驗到或早已體驗過僅僅通過刷臉就能解鎖手機或者門鎖。當你解鎖了手機,我猜手機上一定有很多分享圖片的應用。 在上面,你能看到美食,酒店或美麗風景的圖片。有些公司在這些應用上使用了深度學習技 術來向你展示最爲生動美麗以及與你最爲相關的圖片。機器學習甚至還催生了新的藝術類型。

案例:圖片識別、目標檢測、圖片風格遷移

1)你應該早就聽說過圖片分類,或者說圖片識別。比如給出這張 64×64 的圖片,讓計算機去分辨出這是一隻貓。

                                                               

2)在計算機視覺中有個問題叫做目標檢測,比如在一個無人駕駛項目中, 你不一定非得識別出圖片中的物體是車輛,但你需要計算出其他車輛的位置,以確保自己能 夠避開它們。所以在目標檢測項目中,首先需要計算出圖中有哪些物體,比如汽車,還有圖 片中的其他東西,再將它們模擬成一個個盒子,或用一些其他的技術識別出它們在圖片中的 位置。注意在這個例子中,在一張圖片中同時有多個車輛,每輛車相對與你來說都有一個確切的距離。

                                                              

3)神經網絡實現的圖片風格遷移,比如說你有一張圖片,但 你想將這張圖片轉換爲另外一種風格。所以圖片風格遷移,就是你有一張滿意的圖片和一張 風格圖片,實際上右邊這幅畫是畢加索的畫作,而你可以利用神經網絡將它們融合到一起, 描繪出一張新的圖片。它的整體輪廓來自於左邊,卻是右邊的風格,最後生成下面這張圖片。 這種神奇的算法創造出了新的藝術風格,所以在這門課程中,你也能通過學習做到這樣的事情。

計算機視覺應用面臨的挑戰:

數據的輸入可能會非常大。舉個例子,在過去的課程中,你們一般操作的都是 64×64 的小圖片,實際上,它的數據量是 64×64×3,因爲每張圖片都有 3 個顏色通道。如果計算一下的話,可得知數據量爲 12288(特徵數目),所以我們的特徵向量𝑥維度爲 12288。這其實還好,因爲 64×64 真的是很小的一張圖片。

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

如果你要輸入 300 萬的數據量,這就意味着,特徵向量𝑥的維度高達 300 萬。所以在第 一隱藏層中,你也許會有 1000 個隱藏單元,而所有的權值組成了矩陣 𝑊[1]。如果你使用了標準的全連接網絡,就像我們在第一門和第二門的課程裏說的,這個矩陣的大小將會是 1000×300 萬。因爲現在𝑥的維度爲3𝑚,3𝑚通常用來表示 300 萬。這意味着矩陣𝑊[1]會有 30 億個參數,這是個非常巨大的數字。在參數如此大量的情況下,難以獲得足夠的數據來防止神經網絡發生過擬合和競爭需求,要處理包含 30 億參數的神經網絡,巨大的內存需求讓人不太能接受

解決措施:

但對於計算機視覺應用來說,你肯定不想它只處理小圖片,你希望它同時也要能處理大圖。爲此,你需要進行卷積計算,它是卷積神經網絡中非常重要的一塊。

1.2 邊緣檢測示例

卷積運算是卷積神經網絡最基本的組成部分,使用邊緣檢測作爲入門樣例。接下來,你會看到卷積是如何進行運算的。

檢測的順序:

我說過神經網絡的前幾層是如何檢測邊緣的,然後,後面的層有可能檢測到物體的部分區域,更靠後的一些層可能檢測到完整的物體,這個例子中就是人臉。接下來,你會看到如何在一張圖片中進行邊緣檢測。

利用邊緣監測算法我們可以檢測出圖片的橫邊和豎邊。

 

                                              

過濾器認識: 

看一個例子,這是一個 6×6 的灰度圖像。因爲是灰度圖像,所以它是 6×6×1 的矩陣,而 不是 6×6×3 的,因爲沒有 RGB 三通道。爲了檢測圖像中的垂直邊緣,你可以構造一個 3×3 矩陣。在共用習慣中,在卷積神經網絡的術語中,它被稱爲過濾器。我要構造一個 3×3 的過濾器,像這樣在論文它有時候會被稱爲核,而不是過濾器,但在這裏,我將使用過濾器這個術語。對這個 6×6 的圖像進行卷積運算,卷積運算用“∗”來表示,用 3×3 的過濾器對其進行卷積。

符號解釋:

關於符號表示,有一些問題,在數學中“∗”就是卷積的標準標誌,但是在 Python 中,這 個標識常常被用來表示乘法或者元素乘法。所以這個“∗”有多層含義,它是一個重載符號, 在這裏,當“∗”表示卷積的時候我會特別說明。                      

                                                    

卷積計算過程:

這個卷積運算的輸出將會是一個 4×4 的矩陣,你可以將它看成一個 4×4 的圖像。

爲了計算第一個元素,在 4×4 左上角的那個元素,使 用 3×3 的過濾器,將其覆蓋在輸入圖像,如下圖所示。然後進行元素乘法運算。

                                                        

然後將該矩陣每個元素相加得到最左上角的元素,即3 + 1 + 2 + 0 + 0 + 0 + (−1) + (−8) + (−2) = −5

把這 9 個數加起來得到-5,當然,你可以把這 9 個數按任何順序相加,我只是先寫了第 一列,然後第二列,第三列。

接下來,爲了弄明白第二個元素是什麼,你要把藍色的方塊,向右移動一步,像這樣, 把這些綠色的標記去掉:

                                              

繼續做同樣的元素乘法,然後加起來,所以是 0×1+5×1+7×1+1×0+8×0+ 2 × 0 + 2 × (−1) + 9 × (−1) + 5 × (−1) = −4。

                                           

接下來也是一樣,繼續右移一步,把 9 個數的點積加起來得到 0。

繼續移得到 8,驗證一下:2×1+9×1+5×1+7×0+3×0+1×0+4×(−1)+ 1 × (−1) + 3 × (−1) = 8。

                                          

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

                                  

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

                                     

爲了說得更清楚一點,這個-16 是通過底部右下角的 3×3 區域得到的。

垂直邊緣檢測器:

因此 6×6 矩陣和 3×3 矩陣進行卷積運算得到 4×4 矩陣。這些圖片和過濾器是不同維度的矩陣,但左邊矩陣容易被理解爲一張圖片,中間的這個被理解爲過濾器,右邊的圖片我們可以理解爲另一張圖片。這個就是垂直邊緣檢測器,

不同編程框架卷積運算函數

在 tensorflow 下,這個函數叫 tf.conv2d。在 Keras 這個框架,在這個框架下用 Conv2D 實現卷積運算。所有的編程框架都有一些函數來實現卷積運算。

爲什麼這個可以做垂直邊緣檢測呢?

示例:

                                                           

這是一個簡單的 6×6 圖像,左邊的一半是 10,右邊一般是 0。如果你把它當 成一個圖片,左邊那部分看起來是白色的,像素值 10 是比較亮的像素值,右邊像素值比較 暗,我使用灰色來表示 0,儘管它也可以被畫成黑的。圖片裏,有一個特別明顯的垂直邊緣在圖像中間,這條垂直線是從黑到白的過渡線,或者從白色到深色

                                              

所以,當你用一個 3×3 過濾器進行卷積運算的時候,這個 3×3 的過濾器可視化爲下面這個樣子,在左邊有明亮的像素,然後有一個過渡,0 在中間,然後右邊是深色的。卷積運算後,你得到的是右邊的矩陣。如果你願意,可以通過數學運算去驗證。舉例來說,最左上角的元素 0,就是由這個 3×3 塊(綠色方框標記)經過元素乘積運算再求和得到的,10 × 1 + 10 × 1 + 10 × 1 + 10 × 0 + 10 × 0 + 10 × 0 + 10 × (−1) + 10 × (−1) + 10 × (−1) = 0。相反這個 30 是由這個(紅色方框標記)得到的10×1+10×1+10×1+10×0+10×0+10×0+0×(−1)+0×(−1)+0× (−1) = 30。

                                            

如果把最右邊的矩陣當成圖像,它是這個樣子。在中間有段亮一點的區域,對應檢查到 這個 6×6 圖像中間的垂直邊緣。這裏的維數似乎有點不正確,檢測到的邊緣太粗了。因爲在 這個例子中,圖片太小了。如果你用一個 1000×1000 的圖像,而不是 6×6 的圖片,你會發現其會很好地檢測出圖像中的垂直邊緣。

在這個例子中,在輸出圖像中間的亮處,表示在圖像中間有一個特別明顯的垂直邊緣。

從垂直邊緣檢測中可以得到的啓發是,因爲我們使用 3×3 的矩陣(過濾器),所以垂直邊緣是一個 3×3 的區域,左邊是明亮的像素,中間的並不需要 考慮,右邊是深色像素。在這個 6×6 圖像的中間部分,明亮的像素在左邊,深色的像素在右 邊,就被視爲一個垂直邊緣,卷積運算提供了一個方便的方法來發現圖像中的垂直邊緣。

1.3  更多邊緣檢測內容

圖片邊緣有兩種漸變方式,一種是由明變暗,另一種是由暗變明。以垂直邊緣檢測爲例,下圖展示了兩種方式的區別。實際應用中,這兩種漸變方式並不影響邊緣檢測結果,可以對輸出圖片取絕對值操作,得到同樣的結果。

                                                     

 

垂直邊緣檢測和水平邊緣檢測的濾波器算子如下所示:

                                                                

下圖展示一個水平邊緣檢測的例子:

                                            

除了上面提到的這種簡單的Vertical、Horizontal濾波器之外,還有其它常用的filters,例如Sobel filter和Scharr filter。這兩種濾波器的特點是增加圖片中心區域的權重。

                                                                

上圖展示的是垂直邊緣檢測算子,水平邊緣檢測算子只需將上圖順時針翻轉90度即可。

在深度學習中,如果我們想檢測圖片的各種邊緣特徵,而不僅限於垂直邊緣和水平邊緣,那麼filter的數值一般需要通過模型訓練得到,類似於標準神經網絡中的權重W一樣由梯度下降算法反覆迭代求得。CNN的主要目的就是計算出這些filter的數值。確定得到了這些filter後,CNN淺層網絡也就實現了對圖片所有邊緣特徵的檢測。
 

1.4 Padding

按照我們上面講的圖片卷積,如果原始圖片尺寸爲n x n,filter尺寸爲f x f,則卷積後的圖片尺寸爲(n-f+1) x (n-f+1),注意f一般爲奇數。這樣會帶來兩個問題:

  • 卷積運算後,輸出圖片尺寸縮小

  • 原始圖片邊緣信息對輸出貢獻得少,輸出圖片丟失邊緣信息

爲了解決圖片縮小的問題,可以使用padding方法,即把原始圖片尺寸進行擴展,擴展區域補零,用p來表示每個方向擴展的寬度。

                                     

經過padding之後,原始圖片尺寸爲(n+2p) x (n+2p),filter尺寸爲f x f,則卷積後的圖片尺寸爲(n+2p-f+1) x (n+2p-f+1)。若要保證卷積前後圖片尺寸不變,則p應滿足:

                                                                                  

沒有padding操作 ,我們稱之爲“Valid convolutions”(圖片變小);有padding操作,我們稱之爲“Same convolutions”(圖片不變)

f爲奇數的原因:

1)達到對稱填充

2)只有一箇中心點

1.5 卷積步長

Stride表示filter在原圖片中水平方向和垂直方向每次的步進長度。之前我們默認stride=1。若stride=2,則表示filter每次步進長度爲2,即隔一點移動一次。

                            

我們用s表示stride長度,p表示padding長度,如果原始圖片尺寸爲n x n,filter尺寸爲f x f,則卷積後的圖片尺寸爲:

                                                      

上式中,⌊⋯⌋表示向下取整。

值得一提的是,相關係數(cross-correlations)與卷積(convolutions)之間是有區別的。實際上,真正的卷積運算會先將filter繞其中心旋轉180度,然後再將旋轉後的filter在原始圖片上進行滑動計算。filter旋轉如下所示:
                                              

比較而言,相關係數的計算過程則不會對filter進行旋轉,而是直接在原始圖片上進行滑動計算。

其實,目前爲止我們介紹的CNN卷積實際上計算的是相關係數,而不是數學意義上的卷積。但是,爲了簡化計算,我們一般把CNN中的這種“相關係數”就稱作卷積運算。之所以可以這麼等效,是因爲濾波器算子一般是水平或垂直對稱的,180度旋轉影響不大;而且最終濾波器算子需要通過CNN網絡梯度下降算法計算得到,旋轉部分可以看作是包含在CNN模型算法中。總的來說,忽略旋轉運算可以大大提高CNN網絡運算速度,而且不影響模型性能。
 

1.6 三維卷積

我們瞭解了卷積的操作,那麼如何處理圖片的RGB數據呢?就是使用三維卷積,也就是可以理解成進行三次卷積操作

對於3通道的RGB圖片,其對應的濾波器算子同樣也是3通道的。例如一個圖片是6 x 6 x 3,分別表示圖片的高度(height)、寬度(weight)和通道(#channel)。

3通道圖片的卷積運算與單通道圖片的卷積運算基本一致。過程是將每個單通道(R,G,B)與對應的filter進行卷積運算求和,然後再將3通道的和相加,得到輸出圖片的一個像素值。
                                    

不同通道的濾波算子可以不相同。例如R通道filter實現垂直邊緣檢測,G和B通道不進行邊緣檢測,全部置零,或者將R,G,B三通道filter全部設置爲水平邊緣檢測。

爲了進行多個卷積運算,實現更多邊緣檢測,可以增加更多的濾波器組。例如設置第一個濾波器組實現垂直邊緣檢測,第二個濾波器組實現水平邊緣檢測。這樣,不同濾波器組卷積得到不同的輸出,個數由濾波器組決定。

                             

總結:

這個對立方體卷積的概念真的很有用,你現在可以用它的一小部分直接在三個通道的 RGB 圖像上進行操作。更重要的是,你可以檢測兩個特徵,比如垂直和水平邊緣或者 10 個 或者 128 個或者幾百個不同的特徵,並且輸出的通道數會等於你要檢測的特徵數

1.7  單層卷積網絡

卷積神經網絡的單層結構如下所示:

                 

相比之前的卷積過程,CNN的單層結構多了激活函數ReLU和偏移量b。整個過程與標準的神經網絡單層結構非常類似:

                                                                    

 

卷積運算對應着上式中的乘積運算,濾波器組數值對應着權重 W[l],所選的激活函數爲ReLU。

我們來計算一下上圖中參數的數目:每個濾波器組有3x3x3=27個參數,還有1個偏移量b,則每個濾波器組有27+1=28個參數,兩個濾波器組總共包含28x2=56個參數。我們發現,選定濾波器組後,參數數目與輸入圖片尺寸無關。所以,就不存在由於圖片尺寸過大,造成參數過多的情況。例如一張1000x1000x3的圖片,標準神經網絡輸入層的維度將達到3百萬,而在CNN中,參數數目只由濾波器組決定,數目相對來說要少得多,這是CNN的優勢之一。
最後,我們總結一下描述卷積神經網絡中的一層,以𝑙層爲例。也就是卷積層的各種標記。

   

其中:

                                                                          

1.8   簡單卷積網絡示例

下面介紹一個簡單的CNN網絡模型:

示例:通過卷積神經網絡圖片分類或圖片識別

圖片輸入定義爲𝑥,大小39×39×3,最終輸出結果用 0 或 1 表示,這是一個分類問題。

         這裏寫圖片描述

1)即高度和寬度都等於 39

      即 0 層的通道數爲3。

2)第一層我們用一個 3×3 的過濾器來提取特徵(每個過濾器組維度 3×3×3),那麼𝑓[1] = 3,因爲過濾器時 3×3 的矩陣。𝑠[1] =           1,𝑝[1] = 0,所以高度和寬度使用 same 卷積。如果有 10 個過濾器,神經網絡下一層的激活值爲 37×37×10,37 是公式      

     計算結果,它是一個 vaild 卷積,這是輸出結果的大小。

   第一層標記爲等於第一層中過濾器的個數,這(37×37×10)是第一層激活值的維度

3)第二層我們採用的過濾器是 5×5 的矩陣(每個過濾器組維度 5×5×10

    在標記法中,神經網絡下一層的𝑓 = 5,即𝑓[2] = 5步幅爲 2,即𝑠[2] = 2。padding 爲 0,即𝑝[2] = 0,且有 20 個過濾器。

    輸出結果會是一張新圖像,這次的輸出結果爲 17×17×20,因爲步幅是 2,維度縮小得很快,大小從 37×37 減小到 17×17,減小了一半還多,過濾器是 20 個,所以通道數也是 20,17×17×20 即激活值𝑎[2]的維度。因此

4)最後一個卷積層,假設過濾器還是 5×5,步幅爲 2,即𝑓[2] = 5,𝑠[3] = 2,計算過程我跳過了,最後輸出爲 7×7×40,假設使用        了 40 個過濾器。padding 爲 0,40 個過濾器,最後結果爲 7×7×40。

上述總結:

到此,這張 39×39×3 的輸入圖像就處理完畢了,爲圖片提取了 7×7×40 個特徵,計算出 來就是 1960 個特徵。然後對該卷積進行處理,可以將其平滑或展開成 1960 個單元。平滑處理後可以輸出一個向量,其填充內容是 logistic 迴歸單元還是 softmax 迴歸單元,完全取決於我們是想識圖片上有沒有貓,還是想識別𝐾種不同對象中的一種,用𝑦表示最終神經網絡 的預測輸出。

值得一提的是,隨着CNN層數增加,一般逐漸減小,而 

一般逐漸增大。

總結:

CNN有三種類型的layer:

  • Convolution層(CONV)

  • Pooling層(POOL)

  • Fully connected層(FC)

一個典型的卷積神經網絡通常有三層,一個是卷積層,我們常常用 Conv 來標註上一 個例子,我用的就是 CONV。

還有兩種常見類型的層,我們後面講。一個是池化層, 我們稱之爲 POOL。最後一個是全連接層,用 FC 表示。

雖然僅用卷積層也有可能構建出很好的神經網絡,但大部分神經網絡架構師依然會添加池化層和全連接層。幸運的是,池化層和全連接層比卷積層更容易設計。

1.9   池化層

Pooling layers是CNN中用來減小尺寸,提高運算速度的,同樣能減小noise影響,讓各特徵更具有健壯性。

Pooling layers的做法比convolution layers簡單許多,沒有卷積運算,僅僅是在濾波器算子滑動區域內取最大值,即max pooling,這是最常用的做法。注意,超參數p很少在pooling layers中使用。

                                              這裏寫圖片描述

Max pooling的好處是隻保留區域內的最大值(特徵),忽略其它值,降低noise影響,提高模型健壯性。而且,max pooling需要的超參數僅爲濾波器尺寸f和濾波器步進長度s,沒有其他參數需要模型訓練得到,計算量很小。

如果是多個通道,那麼就每個通道單獨進行max pooling操作。


除了max pooling之外,還有一種做法:average pooling。顧名思義,average pooling就是在濾波器算子滑動區域計算平均值。

                                               這裏寫圖片描述

實際應用中,max pooling比average pooling更爲常用。

1.10   卷積神經網絡示例

下面介紹一個簡單的數字識別的CNN例子:

這裏寫圖片描述

圖中,CON層後面緊接一個POOL層,CONV1和POOL1構成第一層,CONV2和POOL2構成第二層。特別注意的是FC3和FC4爲全連接層FC,它跟標準的神經網絡結構一致。最後的輸出層(softmax)由10個神經元構成。

參數選擇:

此例中的卷積神經網絡很典型,看上去它有很多超參數,關於如何選定這些參數,後面我提供更多建議。常規做法是,儘量不要自己設置超參數,而是查看文獻中別人採用了哪些超參數,選一個在別人任務中效果很好的架構,那麼它也有可能適用於你自己的應用程序。

現在,我想指出的是,隨着神經網絡深度的加深,高度𝑛𝐻 和寬度𝑛𝑊 通常都會減少,前面我就提到過,從 32×32 到 28×28,到 14×14,到 10×10,再到 5×5。所以隨着層數增加,高度和寬度都會減小,而通道數量會增加,從 3 到 6 到 16 不斷增加,然後得到一個全連接層。

在神經網絡中,另一種常見模式就是一個或多個卷積後面跟隨一個池化層,然後一個或多個卷積層後面再跟一個池化層,然後是幾個全連接層,最後是一個 softmax。這是神經網絡的另一種常見模式。

神經網絡的激活值形狀,激活值大小和參數數量

                              在這裏插入圖片描述

幾點要注意,第一,池化層和最大池化層沒有參數;第二卷積層的參數相對較少,前面課上我們提到過,其實許多參數都存在於神經網絡的全連接層。觀察可發現,隨着神經網絡的加深,激活值尺寸會逐漸變小,如果激活值尺寸下降太快,也會影響神經網絡性能。示 例中,激活值尺寸在第一層爲 6000,然後減少到 1600,慢慢減少到 84,最後輸出 softmax 結果。我們發現,許多卷積網絡都具有這些屬性,模式上也相似。

總結:

一個卷積神經網絡包括卷積層、池化層和全 連接層。許多計算機視覺研究正在探索如何把這些基本模塊整合起來,構建高效的神經網絡, 整合這些基本模塊確實需要深入的理解。根據我的經驗,找到整合基本構造模塊最好方法就 是大量閱讀別人的案例。

1.11  爲什麼使用卷積

相比標準神經網絡,CNN的優勢之一就是參數數目要少得多。參數數目少的原因有兩個:

  • 參數共享:一個特徵檢測器(例如垂直邊緣檢測)對圖片某塊區域有用,同時也可能作用在圖片其它區域。

  • 連接的稀疏性:因爲濾波器算子尺寸限制,每一層的每個輸出只與輸入部分區域內有關。

除此之外,由於CNN參數數目較小,所需的訓練樣本就相對較少,從而一定程度上不容易發生過擬合現象。而且,CNN比較擅長捕捉區域位置偏移。也就是說CNN進行物體檢測時,不太受物體所處圖片位置的影響,增加檢測的準確性和系統的健壯性。

二、測驗

1. 你認爲把下面這個過濾器應用到灰度圖像會怎麼樣?

   

  1. 會檢測45度邊緣
  2. 會檢測垂直邊緣
  3. 會檢測水平邊緣
  4. 會檢測圖像對比度

2

2. 假設你的輸入是一個300×300的彩色(RGB)圖像,而你沒有使用卷積神經網絡。 如果第一個隱藏層有100個神經元,每個神經元與輸入層進行全連接,那麼這個隱藏層有多少個參數(包括偏置參數)?

27,000,100 (300*300*3*100+100(偏置))

3. 假設你的輸入是300×300彩色(RGB)圖像,並且你使用卷積層和100個過濾器,每個過濾器都是5×5的大小,請問這個隱藏層有多少個參數(包括偏置參數)?

7600( (5*5*3+1)*100 )

4. 你有一個63x63x16的輸入,並使用大小爲7×7的32個過濾器進行卷積,使用步幅爲2和無填充,請問輸出是多少?

29*29*32 【(( 63+2*0-7 )/2)+1】0是padding

5. 你有一個15x15x8的輸入,並使用“pad = 2”進行填充,填充後的尺寸是多少?

19*19*8

6. 你有一個63x63x16的輸入,有32個過濾器進行卷積,每個過濾器的大小爲7×7,步幅爲1,你想要使用“same”的卷積方式,請問pad的值是多少?

3【(7-1)/2】

7. 你有一個32x32x16的輸入,並使用步幅爲2、過濾器大小爲2的最大化池,請問輸出是多少?

16*16*16

8. 因爲池化層不具有參數,所以它們不影響反向傳播的計算。

錯誤。

9. 在視頻中,我們談到了“參數共享”是使用卷積網絡的好處。關於參數共享的下列哪個陳述是正確的?(檢查所有選項。)

  1. 它減少了參數的總數,從而減少過擬合。
  2. 它允許在整個輸入值的多個位置使用特徵檢測器。
  3. 它允許爲一項任務學習的參數即使對於不同的任務也可以共享(遷移學習)。
  4. 它允許梯度下降將許多參數設置爲零,從而使得連接稀疏。

2,4。

10. 在課堂上,我們討論了“稀疏連接”是使用卷積層的好處。這是什麼意思?

  1. 正則化導致梯度下降將許多參數設置爲零。
  2. 每個過濾器都連接到上一層的每個通道。
  3. 下一層中的每個激活只依賴於前一層的少量激活。
  4. 卷積網絡中的每一層只連接到另外兩層。

3。

三、編程作業

3.1 一步步實現卷積神經網絡

下面將用 numpy實現卷積(CONV)和池化(POOL)層,包括正向傳播和向後傳播。

符號:

上標[𝑙] 表示第 𝑙𝑡ℎ層對象,例如:𝑎[4] 是 第四層激活,𝑊[5] 和 𝑏[5]是第五層參數。

上標 (i)表示第 i個示例,例如:𝑥(𝑖)是第 i個訓練樣本輸入。

3.1.1 導包

numpy是使用Python進行科學計算的基本軟件包。
matplotlib是一個用於在Python中繪製圖形的庫。
np.random.seed(1)用於使所有隨機函數調用保持一致。

3.1.2 作業大綱

您將實現卷積神經網絡的構建模塊!

  • Convolution functions, including:
    • Zero Padding
    • Convolve window 
    • Convolution forward
    • Convolution backward (optional)
  • Pooling functions, including:
    • Pooling forward
    • Create mask 
    • Distribute value
    • Pooling backward (optional)

這裏需要您從頭開始在numpy中實現這些功能。 在下一個目錄中,您將使用這些函數的TensorFlow等效項來構建以下模型。

                                        

注意,對於每個正向功能,都有其對應的向後等效項。 因此,在正向傳播中的每一步中,您都需要將一些參數存儲在緩存中。 這些參數用於在反向傳播期間計算梯度。 

3.1.3 卷積神經網絡

儘管編程框架使卷積易於使用,但它們仍然是深度學習中最難理解的概念之一。 卷積層將輸入體積轉換爲不同大小的輸出體積,如下所示。

                                                      

在這一部分,您將構建卷積層的每個步驟。 您將首先實現兩個輔助函數:

一個用於零填充,

另一個用於計算卷積函數本身。

3.1.4 零填充

零填充會在圖像的邊界周圍添加零:

                               

填充的主要好處如下:

  • 它使您可以使用CONV層而不必縮小卷的高度和寬度。 這對於構建更深的網絡很重要,因爲否則高度/寬度會隨着您進入更深的層而縮小。 一個重要的特殊情況是“相同”卷積,其中高度/寬度在下一層之後被精確保留。
  • 它可以幫助我們將更多信息保留在圖像的邊緣。 如果不進行填充,則下一層的值很少會受到像素作爲圖像邊緣的影響。

 

我們使用numpy提供的pad參數來進行padding操作,需要傳的幾個參數分別是array,然後就是三個維度上分別擴展多少位(arr3D爲一個三維數組,我們不希望變成4維所以第一個均爲0,然後第二維第三維上下左右分別加上幾個0),然後constant表示填充(默認填充0)。

import numpy as np

# 填充
arr3D = np.array([[[1, 1, 2, 2, 3, 4],
                   [1, 1, 2, 2, 3, 4],
                   [1, 1, 2, 2, 3, 4]],

                  [[0, 1, 2, 3, 4, 5],
                   [0, 1, 2, 3, 4, 5],
                   [0, 1, 2, 3, 4, 5]],

                  [[1, 1, 2, 2, 3, 4],
                   [1, 1, 2, 2, 3, 4],
                   [1, 1, 2, 2, 3, 4]]])

print('constant:  \n' + str(np.pad(arr3D, ((0, 0), (1, 1), (2, 2)), 'constant')))


#輸出結果

[[[0 0 0 0 0 0 0 0 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 0 0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0 0 0 0]
  [0 0 0 1 2 3 4 5 0 0]
  [0 0 0 1 2 3 4 5 0 0]
  [0 0 0 1 2 3 4 5 0 0]
  [0 0 0 0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0 0 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 0 0 0 0 0 0 0 0]]]

修改 print('constant:  \n' + str(np.pad(arr3D, ((1, 1), (1, 1), (2, 2)), 'constant')))

輸出結果:

[[[0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0 0 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 0 0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0 0 0 0]
  [0 0 0 1 2 3 4 5 0 0]
  [0 0 0 1 2 3 4 5 0 0]
  [0 0 0 1 2 3 4 5 0 0]
  [0 0 0 0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0 0 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 1 1 2 2 3 4 0 0]
  [0 0 0 0 0 0 0 0 0 0]]

 [[0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0]
  [0 0 0 0 0 0 0 0 0 0]]]

具體解釋參考博客:https://blog.csdn.net/yangshaojun1992/article/details/105648121

我們試着可視化一下:

import numpy as np
import h5py
import matplotlib.pyplot as plt

def zero_pad(X, pad):
    """
    Pad with zeros all images of the dataset X. The padding is applied to the height and width of an image,
    as illustrated in Figure 1.

    Argument:
    X -- python numpy array of shape (m, n_H, n_W, n_C) representing a batch of m images
    pad -- integer, amount of padding around each image on vertical and horizontal dimensions

    Returns:
    X_pad -- padded image of shape (m, n_H + 2*pad, n_W + 2*pad, n_C)
    """
    X_pad = np.pad(X, ((0, 0), (pad, pad), (pad, pad), (0, 0)), 'constant', constant_values=0)
    return X_pad

if __name__ == '__main__':
    np.random.seed(1)
    x = np.random.randn(4, 3, 3, 2) # 生成四維數組
    x_paded = zero_pad(x, 2)
    # # 繪製圖
    fig, axarr = plt.subplots(1, 2)  # 一行兩列
    axarr[0].set_title('x')
    axarr[0].imshow(x[0, :, :, 0]) # 3 X 3
    axarr[1].set_title('x_paded')
    axarr[1].imshow(x_paded[0, :, :, 0])
    plt.show()

輸出結果:

                                               

3.1.5 卷積的第一步

在這一部分中,實現卷積的單個步驟,其中將過濾器應用於輸入的單個位置。 這將用於構建卷積單元,該卷積單元:

  • Takes an input volume 
  • Applies a filter at every position of the input
  • Outputs another volume (usually of different size)   

                                                                

在計算機視覺應用程序中,左側矩陣中的每個值都對應一個像素值,我們應用3x3 過濾器將元素的值與原始矩陣相乘,然後將它們相加進行卷積。 在練習的第一步中,您將實現卷積的單個步驟,相當於僅對一個位置應用過濾器以獲得單個實值輸出。

在本筆記本的後面,您將將此功能應用於輸入的多個位置以實現完整的卷積運算。

練習:實現conv_single_step()

def conv_single_step(a_slice_prev, W, b):
    """
    Apply one filter defined by parameters W on a single slice (a_slice_prev) of the output activation
    of the previous layer.

    Arguments:
    a_slice_prev -- slice of input data of shape (f, f, n_C_prev)
    W -- Weight parameters contained in a window - matrix of shape (f, f, n_C_prev)
    b -- Bias parameters contained in a window - matrix of shape (1, 1, 1)

    Returns:
    Z -- a scalar value, result of convolving the sliding window (W, b) on a slice x of the input data
    """

    s = np.multiply(a_slice_prev, W) + b
    Z = np.sum(s)

    return Z

if __name__ == '__main__':

    np.random.seed(1)
    a_slice_prev = np.random.randn(4, 4, 3)
    W = np.random.randn(4, 4, 3)
    b = np.random.randn(1, 1, 1)
    Z = conv_single_step(a_slice_prev, W, b)
    print("Z =", Z)

輸出結果:

Z = -23.16021220252078

3.1.6 卷積神經網絡-前向傳播

在前向傳遞中,您將使用許多過濾器並將它們卷積在輸入上。 每個“卷積”都會爲您提供2D矩陣輸出。 然後,您將堆疊這些輸出以獲得3D輸出:

                                    

計算卷積後圖片大小公式如下:

                                                           

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章