吳恩達深度學習:單層卷積網路

2020/2/28發表於2020-11-15

考研人資訊庫

此公眾號會發表計算機考研(初複試資訊)、夏令營等資料,方便考研人對資訊的獲取,節約自身查詢資料的時間,回覆408,可獲得資料結構、作業系統、計算機網路、計算機組成原理全科資料

單層卷積網路 (One Layer of a Convolutional Network)

今天我們要講的是如何構建卷積神經網路的卷積層,下面來看個例子。

在這裡插入圖片描述
上節課,我們已經講了如何通過兩個過濾器卷積處理一個三維影像,並輸出兩個不同的4×4矩陣。假設使用第一個過濾器進行卷積,得到第一個4×4矩陣。使用第二個過濾器進行卷積得到另外一個4×4矩陣。

在這裡插入圖片描述
最終各自形成一個卷積神經網路層,然後增加偏差,它是一個實數,通過Python的廣播機制給這16個元素都加上同一偏差。然後應用非線性函式,為了說明,它是一個非線性啟用函式ReLU,輸出結果是一個4×4矩陣。

對於第二個4×4矩陣,我們加上不同的偏差,它也是一個實數,16個數字都加上同一個實數,然後應用非線性函式,也就是一個非線性啟用函式ReLU,最終得到另一個4×4矩陣。然後重複我們之前的步驟,把這兩個矩陣堆疊起來,最終得到一個4×4×2的矩陣。我們通過計算,從6×6×3的輸入推匯出一個4×4×2矩陣,它是卷積神經網路的一層,把它對映到標準神經網路中四個卷積層中的某一層或者一個非卷積神經網路中。

在這裡插入圖片描述
注意前向傳播中一個操作就是 z [ 1 ] = W [ 1 ] a [ 0 ] + b [ 1 ] z^{[1]}=W^{[1]}a^{[0]}+b^{[1]} z[1]=W[1]a[0]+b[1] ,其中 a [ 0 ] = x a^{[0]}=x a[0]=x ,執行非線性函式得到 a [ 1 ] a^{[1]} a[1] ,即 a [ 1 ] = g ( z [ 1 ] ) a^{[1]}=g(z^{[1]}) a[1]=g(z[1]) 。這裡的輸入是 a [ 0 ] a^{[0]} a[0] ,也就是 x x x ,這些過濾器用變數 W [ 1 ] W^{[1]} W[1] 表示。在卷積過程中,我們對這27個數進行操作,其實是27×2,因為我們用了兩個過濾器,我們取這些數做乘法。實際執行了一個線性函式,得到一個4×4的矩陣。卷積操作的輸出結果是一個4×4的矩陣,它的作用類似於 W [ 1 ] a [ 0 ] W^{[1]}a^{[0]} W[1]a[0] ,也就是這兩個4×4矩陣的輸出結果,然後加上偏差。

在這裡插入圖片描述
這一部分(圖中藍色邊框標記的部分)就是應用啟用函式ReLU之前的值,它的作用類似於,最後應用非線性函式,得到的這個4×4×2矩陣,成為神經網路的下一層,也就是啟用層。

這就是 a [ 0 ] a^{[0]} a[0] 到 a [ 1 ] a^{[1]} a[1] 的演變過程,首先執行線性函式,然後所有元素相乘做卷積,具體做法是運用線性函式再加上偏差,然後應用啟用函式ReLU。這樣就通過神經網路的一層把一個6×6×3的維度 a [ 0 ] a^{[0]} a[0] 演化為一個4×4×2維度的 a [ 1 ] a^{[1]} a[1] ,這就是卷積神經網路的一層。

示例中我們有兩個過濾器,也就是有兩個特徵,因此我們才最終得到一個4×4×2的輸出。但如果我們用了10個過濾器,而不是2個,我們最後會得到一個4×4×10維度的輸出影像,因為我們選取了其中10個特徵對映,而不僅僅是2個,將它們堆疊在一起,形成一個4×4×10的輸出影像,也就是 a [ 1 ] a^{[1]} a[1] 。

在這裡插入圖片描述
為了加深理解,我們來做一個練習。假設你有10個過濾器,而不是2個,神經網路的一層是3×3×3,那麼,這一層有多少個引數呢?我們來計算一下,每一層都是一個3×3×3的矩陣,因此每個過濾器有27個引數,也就是27個數。然後加上一個偏差,用引數 b b b 表示,現在引數增加到28個。上一頁幻燈片裡我畫了2個過濾器,而現在我們有10個,加在一起是28×10,也就是280個引數。

請注意一點,不論輸入圖片有多大,1000×1000也好,5000×5000也好,引數始終都是280個。用這10個過濾器來提取特徵,如垂直邊緣,水平邊緣和其它特徵。即使這些圖片很大,引數卻很少,這就是卷積神經網路的一個特徵,叫作“避免過擬合”。你已經知道到如何提取10個特徵,可以應用到大圖片中,而引數數量固定不變,此例中只有28個,相對較少。

最後我們總結一下用於描述卷積神經網路中的一層(以 l l l 層為例),也就是卷積層的各種標記。

在這裡插入圖片描述
這一層是卷積層,用 f [ l ] f^{[l]} f[l] 表示過濾器大小,我們說過過濾器大小為 f ∗ f f*f f∗f ,上標 [ l ] {[l]} [l] 表示 l l l 層中過濾器大小為 f ∗ f f*f f∗f 。通常情況下,上標 [ l ] {[l]} [l] 用來標記 l l l 層。 p [ l ] p^{[l]} p[l] 用來標記padding的數量,padding數量也可指定為一個valid卷積,即無padding。或是same卷積,即選定padding,如此一來,輸出和輸入圖片的高度和寬度就相同了。用 s [ l ] s^{[l]} s[l] 標記步幅。

這一層的輸入會是某個維度的資料,表示為 n ∗ n ∗ n c n*n*n_c n∗n∗nc​ , n c n_c nc​ 某層上的顏色通道數。

我們要稍作修改,增加上標 [ l − 1 ] [l-1] [l−1] ,即 n [ l − 1 ] ∗ n [ l − 1 ] ∗ n c [ l − 1 ] n^{[l-1]}*n^{[l-1]}*n_c^{[l-1]} n[l−1]∗n[l−1]∗nc[l−1]​ ,因為它是上一層的啟用值。

此例中,所用圖片的高度和寬度都一樣,但它們也有可能不同,所以分別用上下標 H H H 和 W W W 來標記,即 n H [ l − 1 ] ∗ n W [ l − 1 ] ∗ n c [ l − 1 ] n_H^{[l-1]}*n_W^{[l-1]}*n_c^{[l-1]} nH[l−1]​∗nW[l−1]​∗nc[l−1]​ 。那麼在第 l l l 層,圖片大小為 n H [ l − 1 ] ∗ n W [ l − 1 ] ∗ n c [ l − 1 ] n_H^{[l-1]}*n_W^{[l-1]}*n_c^{[l-1]} nH[l−1]​∗nW[l−1]​∗nc[l−1]​ , l l l 層的輸入就是上一層的輸出,因此上標要用 [ l − 1 ] [l-1] [l−1] 。神經網路這一層中會有輸出,它本身會輸出影像。其大小為 n H [ l ] ∗ n W [ l ] ∗ n c [ l ] n_H^{[l]}*n_W^{[l]}*n_c^{[l]} nH[l]​∗nW[l]​∗nc[l]​ ,這就是輸出影像的大小。

前面我們提到過,這個公式給出了輸出圖片的大小,至少給出了高度和寬度, ⌊ n + 2 p − f s + 1 ⌋ \lfloor\frac{n+2p-f}{s}+1\rfloor ⌊sn+2p−f​+1⌋ (注意:( n + 2 p − f s + 1 \frac{n+2p-f}{s}+1 sn+2p−f​+1 直接用這個運算結果,也可以向下取整)。在這個新表示式中, l l l 層輸出影像的高度,即 n H [ l ] = ⌊ n H [ l − 1 ] + 2 p [ l ] − f [ l ] s [ l ] + 1 ⌋ n_H^{[l]}=\lfloor\frac{n_H^{[l-1]}+2p^{[l]}-f^{[l]}}{s^{[l]}}+1\rfloor nH[l]​=⌊s[l]nH[l−1]​+2p[l]−f[l]​+1⌋ ,同樣我們可以計算出影像的寬度,用 W W W 替換引數 H H H ,即 n W [ l ] = ⌊ n W [ l − 1 ] + 2 p [ l ] − f [ l ] s [ l ] + 1 ⌋ n_W^{[l]}=\lfloor\frac{n_W^{[l-1]}+2p^{[l]}-f^{[l]}}{s^{[l]}}+1\rfloor nW[l]​=⌊s[l]nW[l−1]​+2p[l]−f[l]​+1⌋ ,公式一樣,只要變化高度和寬度的引數我們便能計算輸出影像的高度或寬度。這就是由 n H [ l − 1 ] n_H^{[l-1]} nH[l−1]​ 推導 n H [ l ] n_H^{[l]} nH[l]​ 以及 n W [ l − 1 ] n_W^{[l-1]} nW[l−1]​ 推導 n W [ l ] n_W^{[l]} nW[l]​ 的過程。

那麼通道數量又是什麼?這些數字從哪兒來的?我們來看一下。輸出影像也具有深度,通過上一個示例,我們知道它等於該層中過濾器的數量,如果有2個過濾器,輸出影像就是4×4×2,它是二維的,如果有10個過濾器,輸出影像就是4×4×10。輸出影像中的通道數量就是神經網路中這一層所使用的過濾器的數量。如何確定過濾器的大小呢?我們知道卷積一個6×6×3的圖片需要一個3×3×3的過濾器,因此過濾器中通道的數量必須與輸入中通道的數量一致。因此,輸出通道數量就是輸入通道數量,所以過濾器維度等於 f [ l ] ∗ f [ l ] ∗ n c [ l − 1 ] f^{[l]}*f^{[l]}*n_c^{[l-1]} f[l]∗f[l]∗nc[l−1]​ 。

在這裡插入圖片描述
應用偏差和非線性函式之後,這一層的輸出等於它的啟用值 a [ l ] a^{[l]} a[l] ,也就是這個維度(輸出維度)。 a [ l ] a^{[l]} a[l] 是一個三維體,即 n H [ l ] ∗ n W [ l ] ∗ n c [ l ] n_H^{[l]}*n_W^{[l]}*n_c^{[l]} nH[l]​∗nW[l]​∗nc[l]​ 。當你執行批量梯度下降或小批量梯度下降時,如果有 m m m 個例子,就是有 m m m 個啟用值的集合,那麼輸出 A [ l ] = m ∗ n H [ l ] ∗ n W [ l ] ∗ n c [ l ] A^{[l]}=m*n_H^{[l]}*n_W^{[l]}*n_c^{[l]} A[l]=m∗nH[l]​∗nW[l]​∗nc[l]​ 。如果採用批量梯度下降,變數的排列順序如下,首先是索引和訓練示例,然後是其它三個變數。

該如何確定權重引數,即引數W呢?過濾器的維度已知,為 f [ l ] ∗ f [ l ] ∗ n c [ l − 1 ] f^{[l]}*f^{[l]}*n_c^{[l-1]} f[l]∗f[l]∗nc[l−1]​ ,這只是一個過濾器的維度,有多少個過濾器,這( n c [ l ] n_c^{[l]} nc[l]​ )是過濾器的數量,權重也就是所有過濾器的集合再乘以過濾器的總數量,即 f [ l ] ∗ f [ l ] ∗ n c [ l − 1 ] ∗ n c [ l ] f^{[l]}*f^{[l]}*n_c^{[l-1]}*n_c^{[l]} f[l]∗f[l]∗nc[l−1]​∗nc[l]​ ,損失數量L就是 l l l 層中過濾器的個數。

最後我們看看偏差引數,每個過濾器都有一個偏差引數,它是一個實數。偏差包含了這些變數,它是該維度上的一個向量。後續課程中我們會看到,為了方便,偏差在程式碼中表示為一個1×1×1× n c [ l ] n_c^{[l]} nc[l]​的四維向量或四維張量。

在這裡插入圖片描述
卷積有很多種標記方法,這是我們最常用的卷積符號。大家線上搜尋或檢視開原始碼時,關於高度,寬度和通道的順序並沒有完全統一的標準卷積,所以在檢視GitHub上的原始碼或閱讀一些開源實現的時候,你會發現有些作者會採用把通道放在首位的編碼標準,有時所有變數都採用這種標準。實際上在某些架構中,當檢索這些圖片時,會有一個變數或引數來標識計算通道數量和通道損失數量的先後順序。只要保持一致,這兩種卷積標準都可用。很遺憾,這只是一部分標記法,因為深度學習文獻並未對標記達成一致,但課上我會採用這種卷積標識法,按高度,寬度和通道損失數量的順序依次計算。

在這裡插入圖片描述
我知道,忽然間接觸到這麼多新的標記方法,你可能會說,這麼多怎麼記呢?別擔心,不用全都記住,你可以通過本週的練習來熟悉它們。而這節課我想講的重點是,卷積神經網路的某一卷積層的工作原理,以及如何計算某一卷積層的啟用函式,並對映到下一層的啟用值。瞭解了卷積神經網路中某一卷積層的工作原理,我們就可以把它們堆疊起來形成一個深度卷積神經網路,我們下節課再講。

相關文章