# 三、了解深度學習架構
本章將著重于理解當今深度學習中存在的各種架構。 神經網絡的許多成功都在于對神經網絡架構的精心設計。 自 1960 年代的傳統**人工神經網絡**(**ANNs**)以來,我們已經走了很長一段路。 在本書中,我們介紹了基本模型架構,例如完全連接的深度神經網絡,**卷積神經網絡**(**CNN**),**循環神經網絡**(**RNN**),**長短期記憶**(**LSTM**)網絡,以及最新的膠囊網絡。
在本章中,我們將介紹以下主題:
* 為什么神經網絡架構設計很重要
* 各種流行的架構設計和應用
# 神經網絡架構
**架構**一詞是指神經網絡的整體結構,包括其可以具有多少層以及各層中的單元應如何相互連接(例如,連續層中的單元可以完全連接) ,部分連接,或者甚至可以完全跳過下一層,然后再連接到網絡中更高級別的一層。 隨著模塊化深度學習框架(例如 Caffe,Torch 和 TensorFlow)的出現,復雜的神經網絡設計發生了革命性的變化。 現在,我們可以將神經網絡設計與 Lego 塊進行比較,在這里您可以構建幾乎可以想象的任何結構。 但是,這些設計不僅僅是隨機的猜測。 這些設計背后的直覺通常是由設計人員對問題的領域知識以及一些反復試驗來精調最終設計的結果所驅動。
# 為什么需要不同的架構
前饋多層神經網絡具有學習巨大的假設空間并提取每個非線性隱藏層中復雜特征的能力。 那么,為什么我們需要不同的架構? 讓我們嘗試理解這一點。
特征工程是**機器學習**(**ML**)中最重要的方面之一。 如果特征太少或不相關,則可能會導致擬合不足。 而且特征太多,可能會使數據過擬合。 創建一組好的手工制作的特征是一項繁瑣,耗時且重復的任務。
深度學習帶有一個希望,即給定足夠的數據,深度學習模型能夠自動確定正確的特征集,即復雜性不斷增加的特征層次。 好吧,深度學習的希望是真實的,并且會產生誤導。 深度學習確實在許多情況下簡化了特征工程,但是它并沒有完全消除對它的需求。 隨著手動特征工程的減少,神經網絡模型本身的架構變得越來越復雜。 特定架構旨在解決特定問題。 與手工特征工程相比,架構工程是一種更為通用的方法。 在架構工程中,與特征工程不同,領域知識不會硬編碼為特定特征,而只會在抽象級別使用。 例如,如果我們要處理圖像數據,則有關該數據的一個非常高級的信息是對象像素的二維局部性,而另一個是平移不變性。 換句話說,將貓的圖像平移幾個像素仍然可以保持貓的狀態。
在特征工程方法中,我們必須使用非常具體的特征(例如邊緣檢測器,拐角檢測器和各種平滑濾波器)來為任何圖像處理/計算機視覺任務構建分類器。 現在,對于神經網絡,我們如何編碼二維局部性和翻譯不變性信息? 如果將密集的完全連接層放置在輸入數據層之前,則圖像中的每個像素都將連接到密集層中的每個單元。 但是,來自兩個空間遙遠對象的像素不必連接到同一隱藏單元。 經過長時間的大量數據訓練后,具有很強的 L1 正則化能力的神經網絡可能能夠稀疏權重。 我們可以設計架構以僅將本地連接限制到下一層。 少量的相鄰像素(例如,像素的`10 x 10`子圖像)可能具有與隱藏層的一個單元的連接。 由于轉換不變,因此可以重用這些連接中使用的權重。 CNN 就是這樣做的。 這種權重重用策略還有其他好處,例如大大減少了模型參數的數量。 這有助于模型進行概括。
讓我們再舉一個例子,說明如何將抽象領域知識硬編碼到神經網絡中。 假設我們有時間數據或順序數據。 正常的前饋網絡會將每個輸入示例視為獨立于先前的輸入。 因此,學習到的任何隱藏特征表示也應取決于數據的最近歷史,而不僅僅是當前數據。 因此,神經網絡應該具有一些反饋回路或記憶。 這個關鍵思想產生了循環神經網絡架構及其現代的強大變體,例如 LSTM 網絡。
其他高級 ML 問題(例如語音翻譯,問題解答系統和關系建模)要求開發各種深度學習架構。
# 各種架構
現在讓我們看一些流行的神經網絡架構及其應用。 我們將從**多層感知器**(**MLP**)網絡開始。 我們已經介紹了單層感知器網絡,這是最基本的神經網絡架構。
# MLP 和深度神經網絡
**MLP** 或簡單的**深層神經網絡**(**DNNs**)是神經網絡架構的最基本形式。 神經單元一層又一層地排列,相鄰的網絡層彼此完全連接。 我們已經在上一章中對此進行了詳細討論:

# 自編碼器神經網絡
自編碼器通常用于減少神經網絡中數據的維數。 自編碼器也已成功用于異常檢測和新穎性檢測問題。 **自編碼器神經網絡**屬于無監督學習類別。 在此,目標值設置為等于輸入值。 換句話說,我們想學習單位特征。 通過這樣做,我們可以獲得數據的緊湊表示。
通過最小化輸入和輸出之間的差異來訓練網絡。 典型的自編碼器架構是 DNN 架構的略微變體,其中,每個隱藏層的單元數量逐漸減少,直到某個點,然后逐漸增加,最終層尺寸等于輸入尺寸。 其背后的關鍵思想是在網絡中引入瓶頸,并迫使其學習有意義的緊湊表示形式。 隱藏單元的中間層(瓶頸)基本上是輸入的降維編碼。 隱藏層的前半部分稱為**編碼器**,后半部分稱為**解碼器**。 下面描述了一個簡單的自編碼器架構。 名為`z`的層是此處的表示層:

[數據來源](https://cloud4scieng.org/manifold-learning-and-deep-autoencoders-in-science/)
# 變分自編碼器
深度很深的自編碼器很難訓練,并且容易過度安裝。 有許多改進了自編碼器訓練方式的開發,例如使用**受限玻爾茲曼機**(**RBM**)進行生成式預訓練。 **變分自編碼器**(**VAE**)也是生成模型,與其他深層生成模型相比,VAE 在計算上易于處理且穩定,可以通過有效的反向傳播算法進行估計。 它們受到貝葉斯分析中變分推理的啟發。
變分推理的概念如下:給定輸入分布`x`時,輸出`y`上的后驗概率分布太復雜而無法使用。 因此,讓我們用一個更簡單的分布`q(y)`來近似復雜的后驗`p(y|x)`。 在這里, `q`是從最接近后驗的分布族`Q`中選擇的。 例如,此技術用于訓練**潛在 Dirichlet 分配**(**LDA**)(它們對文本進行主題建模,并且是貝葉斯生成模型)。 但是,經典變分推論的一個關鍵局限性是需要對似然性和先驗共軛才能進行優化。 VAE 引入了使用神經網絡來輸出條件后驗的方法(Kingma 和 Welling,2013 年),從而允許使用**隨機梯度下降**(**SGD**)和反向傳播來優化變分推斷目標。 。 該方法稱為**重新參數化技巧**。
給定數據集`X`,VAE 可以生成與樣本`X`類似但不一定相等的新樣本。數據集`X`具有連續或離散隨機變量`x`的`N`個**獨立且完全相同的**樣本。 假設數據是通過某種隨機過程生成的,涉及一個未觀察到的連續隨機變量`z`。 在簡單自編碼器的此示例中,變量`z`是確定性的,并且是隨機變量。 數據生成是一個兩步過程:
1. `z`的值是根據先驗分布生成的,`ρ[θ](z)`
2. 根據條件分布生成`x`的值,`ρ[θ](x|z)`
因此, `p(x)`基本上是邊緣概率,計算公式為:

分布的參數`θ`和潛變量`z`都是未知的。 在此,`x`可以通過從邊際`p(x)`取樣來生成。 反向傳播無法處理網絡中的隨機變量`z`或隨機層`z`。 假設先驗分布`p(z)`為高斯分布,我們可以利用高斯分布的*位置尺度*屬性,并將隨機層重寫為`z =μ + σε`,其中`μ`是位置參數,`σ`是刻度,`ε`是白噪聲。 現在,我們可以獲得噪聲`ε`的多個樣本,并將它們作為確定性輸入提供給神經網絡。
然后,該模型成為端到端確定性深度神經網絡,如下所示:

在這里,解碼器部分與我們之前介紹的簡單自編碼器的情況相同。 訓練此網絡的損失函數如何? 因為這是一個概率模型,所以最直接的方法是通過邊際`p(x)`的最大似然來推導損失函數。 但是,該函數在計算上變得難以處理。 這樣,我們將變分推理技術應用于下限`L`。 導出邊際似然,然后通過最大化下限`L`導出損失函數。 可以在 Kingma 及其合作者的論文[《自編碼變分貝葉斯》](https://arxiv.org/abs/1312.6114)(ICLR,2014 年)。 VAE 已成功應用于各個領域。 例如,文本的深層語義哈希是由 VAE 完成的,其中將文本文檔轉換為二進制代碼。 同樣,相似的文檔具有相似的二進制地址。 這樣,這些代碼可用于更快,更有效的檢索,以及文檔的聚類和分類。
# 生成對抗網絡
自從 Ian Goodfellow 及其合著者在 2014 年 NIPS 論文中首次引入以來,**生成對抗網絡**(**GAN**)就[廣受青睞](https://arxiv.org/pdf/1406.2661.pdf)。 現在我們看到了 GAN 在各個領域的應用。 Insilico Medicine 的研究人員提出了一種使用 GAN 進行人工藥物發現的方法。 他們還發現了在圖像處理和視頻處理問題中的應用,例如圖像樣式轉換和**深度卷積生成對抗網絡**(**DCGAN**)。
顧名思義,這是使用神經網絡的另一種生成模型。 GAN 具有兩個主要組成部分:生成器神經網絡和判別器神經網絡。 生成器網絡采用隨機噪聲輸入,并嘗試生成數據樣本。 判別器網絡將生成的數據與真實數據進行比較,并使用 S 型輸出激活來解決生成的數據是否為偽造的二分類問題。 生成器和判別器都在不斷競爭,并試圖互相愚弄-這就是 GAN 也被稱為**對抗網絡**的原因。 這種競爭驅使兩個網絡都提高其權重,直到判別器開始輸出 0.5 的概率為止。 也就是說,直到生成器開始生成真實圖像為止。 通過反向傳播同時訓練兩個網絡。 這是 GAN 的高級結構圖:

訓練這些網絡的損失函數可以定義如下。 令`p(data)`為數據的概率分布,`p(g)`為生成器分布。 `D(x)`表示`x`來自`p(data)`而非來自`p(g)`的概率。 對`D`進行了訓練,以使將正確標簽分配給`G`的訓練示例和樣本的概率最大化。 同時,訓練`G`以最小化`log(1 - D(G(z)))*`。 因此,`D`和`G`玩一個具有值函數`V(D, G)`的兩人 minimax 游戲:

可以證明,對于`p(g) = p(data)`來說,這種極小極大游戲具有全局最優性。
以下是通過反向傳播訓練 GAN 以獲得所需結果的算法:
```py
for N epochs do:
#update discriminator net first
for k steps do:
Sample minibatch of m noise samples {z(1), , . . . , z
(m)} from noise prior pg(z).
Sample minibatch of m examples {x(1), . . . , x(m)} from
data generating distribution pdata(x).
Update the discriminator by:
end for
Sample minibatch of m noise samples {z(1) , . . . , z (m)}
from noise prior pg(z).
Update the generator by descending its stochastic gradient:
end for
```
# 使用 GAN 架構的文本到圖像合成
讓我們看看使用 GAN 從文本描述生成圖像。 下圖顯示了這種 GAN 的完整架構:

這是條件 GAN 的一種。 生成器網絡獲取帶有噪聲向量的輸入文本以生成圖像。 生成的圖像以輸入文本為條件。 使用嵌入層`φ(t)`將圖像描述轉換為密集向量。 使用完全連接的層對其進行壓縮,然后將其與噪聲向量連接。 檢測器網絡是 CNN,并且生成器網絡的架構使用具有與 CNN 網絡中使用的過濾器相同的過濾器的反卷積層。 反卷積基本上是轉置的卷積,我們將在后面討論。
# CNN
CNN 是專門設計用于識別形狀圖案的多層神經網絡,這些形狀圖案對于二維圖像數據的平移,縮放和旋轉具有高度不變性。 這些網絡需要以監督的方式進行訓練。 通常,提供一組標記的對象類(例如 MNIST 或 ImageNet)作為訓練集。 任何 CNN 模型的關鍵都在于卷積層和子采樣/合并層。 因此,讓我們詳細了解在這些層中執行的操作。
# 卷積運算符
CNN 背后的中心思想是**卷積**的數學運算,這是一種特殊的線性運算。 它廣泛用于物理,統計,計算機視覺以及圖像和信號處理等各個領域。 為了理解這一點,讓我們從一個例子開始。 *嘈雜的*激光傳感器正在跟蹤飛船的位置。 為了更好地估計飛船的位置,我們可以取幾個讀數的平均值,對最近的觀測結果給予更多的權重。 令`x(t)`代表時間位置,`t`,令`w(t)`為加權函數。
該職位的估計可以寫成:

這里,權重函數`w(t)`被稱為卷積的**內核**。 我們可以使用卷積計算位置傳感器數據的**簡單移動平均值**(**SMA**)。 令`m`為 SMA 的窗口大小。
內核定義為:

這是使用卷積的 SMA 的 NumPy 實現:
```py
x = [1, 2, 3, 4, 5, 6, 7]
m = 3 #moving average window size
sma = np.convolve(x, np.ones((m,))/m, mode='valid')
#Outputs
#array([ 2., 3., 4., 5., 6.])
```
在深度學習中,輸入通常是多維數據數組,而內核通常是由訓練算法學習的參數多維數組。 盡管我們在卷積公式中具有無限求和,但對于實際實現而言,權重函數的值僅在值的有限子集時才為非零(如 SMA 的情況)。 因此,公式中的求和變為有限求和。 卷積可應用于多個軸。 如果我們有一個二維圖像`I`和一個二維平滑核`K`,則卷積圖像的計算方式如下:

或者,也可以如下計算:

下圖說明了如何使用大小為 2 且步幅為 1 的內核來計算卷積層輸出:

# 卷積中的跨步和填充模式
卷積內核通過一次移動一列/行來圍繞輸入體積進行卷積。 濾波器移位的量稱為**跨度**。 在前面的場景中,將跨度隱式設置為 1。如果將內核跨度移動 2(兩列或兩行),則輸出單元的數量將減少:

卷積運算符減小了輸入的大小。 如果要保留輸入的大小,則需要在輸入周圍均勻填充零。 對于二維圖像,這意味著在圖像的四個側面周圍添加零像素的邊框。 邊框的粗細(即添加的像素行數)取決于所應用的內核大小。 任何卷積運算符實現通常都采用指定填充類型的模式參數。 有兩個這樣的參數:
* `SAME`:指定輸出大小與輸入大小相同。 這要求過濾器窗口滑到輸入圖的外部,因此需要填充。
* `VALID`:指定過濾器窗口停留在輸入圖內的有效位置,因此輸出大小縮小`filter_size`減一。 沒有填充發生。
在前面的一維卷積碼中,我們將模式設置為`VALID`,因此沒有填充發生。 您可以嘗試使用*相同的*填充。
# 卷積層
卷積層包括三個主要階段,每個階段在多層網絡上都構成一些結構約束:
* **特征提取**:每個單元都從上一層的本地接受域建立連接,從而迫使網絡提取本地特征。 如果我們有一個`32 x 32`的圖像,并且接收區域的大小為`4 x 4`,則一個隱藏層將連接到先前層中的 16 個單元,而我們總共將擁有`28 x 28`個隱藏單元。 因此,輸入層與隱藏層建立了`28 x 28 x 16`的連接,這是這兩層之間的參數數(每個連接的權重)。 如果它是一個完全連接的密集隱藏層,則將有`32 x 32 x 28 x 28`個參數。 因此,在這種架構約束下,我們大大減少了參數數量。 現在,此局部線性激活的輸出通過非線性激活函數(例如 ReLU)運行。 該階段有時稱為**檢測器階段**。 一旦學習了特征檢測器,只要保留其相對于其他特征的位置,該特征在看不見的圖像中的確切位置就不重要了。 與隱藏神經元的感受野相關的突觸權重是卷積的核心。
* **特征映射**:特征檢測器創建平面(綠色平面如下所示)形式的特征圖。 為了提取不同類型的局部特征并具有更豐富的數據表示,并行執行多個卷積以產生多個特征圖,如下所示:

* **通過合并**進行二次采樣:這是由計算層完成的,該計算層通過用附近單元的摘要統計替換某些位置的特征檢測器單元來對特征檢測器的輸出進行二次采樣。 摘要統計信息可以是最大值或平均值。 此操作降低了將特征圖輸出到簡單失真(例如線性移位和旋轉)的敏感性。 池引入不變性:

將這三個階段結合在一起,就可以為我們提供 CNN 中的一個復雜層,這三個階段中的每個本身就是簡單層:

可以通過將并排堆疊在一起的方式,將合并后的特征圖按一個體積進行排列,如下所示。 然后,我們可以再次對此應用下一個卷積級別。 現在,單個特征圖中隱藏單元的接受場將是神經單元的體積,如下圖所示。 但是,將在整個深度上使用同一組二維權重。 深度尺寸通常由通道組成。 如果我們有 RGB 輸入圖像,那么我們的輸入本身將具有三個通道。 但是,卷積是二維應用的,并且所有通道之間的權重相同:

# LeNet 架構
這是 LeCun 及其合作者于 1998 年設計的具有開創性的七級卷積網絡,用于數字分類。 后來,它被幾家銀行用來識別支票上的手寫數字。 網絡的較低層由交替的卷積和最大池化層組成。
上層是完全連接的密集 MLP(由隱藏層和邏輯回歸組成)。 第一個完全連接的層的輸入是上一層的所有特征圖的集合:

在將 CNN 成功應用于數字分類之后,研究人員將重點放在構建可以對 ImageNet 圖像進行分類的更復雜的架構上。 ImageNet 是根據 WordNet 層次結構(目前僅是名詞的層次結構)組織的圖像數據庫,其中層次結構的每個節點都由數百或數千個圖像表示。 ImageNet 項目每年舉辦一次軟件競賽 **ImageNet 大規模視覺識別挑戰賽**(**ILSVRC**),該競賽將大規模評估目標檢測和圖像分類的算法。 評估標準是前五名/最高分。 通過從最終的致密 softmax 層獲取 CNN 的預測來計算這些值。 如果目標標簽是前五個預測之一(概率最高的五個預測),則認為它是成功的。 前五名得分是通過將預測標簽(位于前 5 名)與目標標簽匹配的時間除以所評估圖像的數量得出的。
最高得分的計算方法與此類似。
# AlexNet
在 2012 年,AlexNet 的表現明顯優于所有先前的競爭對手,并通過將前 5 名的錯誤率降低到 15.3% 贏得了 ILSVRC,而亞軍則只有 26%。 這項工作推廣了 CNN 在計算機視覺中的應用。 AlexNet 與 LeNet 的架構非常相似,但是每層具有更多的過濾器,并且更深入。 而且,AlexNet 引入了使用棧式卷積的方法,而不是始終使用替代性卷積池。 小卷積的棧優于大卷積層的接收場,因為這會引入更多的非線性和更少的參數。
假設我們彼此之間具有三個`3 x 3`卷積層(在它們之間具有非線性或池化層)。 在此,第一卷積層上的每個神經元都具有輸入體積的`3 x 3`視圖。 第二卷積層上的神經元具有第一卷積層的`3 x 3`視圖,因此具有輸入體積的`5 x 5`視圖。 類似地,第三卷積層上的神經元具有第二卷積層的`3 x 3`視圖,因此具有輸入體積的`7 x 7`視圖。 顯然,與 3 個`3 x 3`卷積的`3 x (3 x 3) = 27`個參數相比,`7 x 7`接收場的參數數量是 49 倍。
# ZFNet
2013 年 ILSVRC 冠軍是 Matthew Zeiler 和 Rob Fergus 的 CNN。 它被稱為 **ZFNet** 。 通過調整架構的超參數,特別是通過擴展中間卷積層的大小并減小第一層的步幅和過濾器大小,它在 AlexNet 上得到了改進,從 AlexNet 的`11 x 11`步幅 4 變為`7 x 7`步幅。 ZFNet。 這背后的直覺是,在第一卷積層中使用較小的濾鏡尺寸有助于保留大量原始像素信息。 此外,AlexNet 接受了 1500 萬張圖像的訓練,而 ZFNet 接受了 130 萬張圖像的訓練:

# GoogLeNet(Inception)
2014 年 ILSVRC 獲獎者是來自 Google 的名為 **GoogLeNet** 的卷積網絡。 它的前 5 個錯誤率達到 6.67%! 這非常接近人類水平的表現。 排在第二位的是來自 Karen Simonyan 和 Andrew Zisserman 的網絡,稱為 **VGGNet** 。 GoogLeNet 使用 CNN 引入了一個稱為**初始層**的新架構組件。 初始層背后的直覺是使用較大的卷積,但對于圖像上的較小信息也要保持較高的分辨率。
因此,我們可以并行處理不同大小的內核,從`1 x 1`到更大的內核,例如`5 x 5`,然后將輸出級聯以產生下一層:

顯然,增加更多的層會爆炸參數空間。 為了控制這一點,使用了降維技巧。 請注意,`1 x 1`卷積基本上不會減小圖像的空間尺寸。 但是,我們可以使用`1 x 1`濾鏡減少特征圖的數量,并減少卷積層的深度,如下圖所示:

下圖描述了完整的 GoogLeNet 架構:

# VGG
牛津視覺幾何學組或簡稱為 **VGG** 的研究人員開發了 VGG 網絡,該網絡的特點是簡單,僅使用`3 x 3`卷積層并排疊加,且深度不斷增加。 減小卷大小由最大池化處理。 最后,兩個完全連接的層(每個層有 4,096 個節點)之后是 softmax 層。 對輸入進行的唯一預處理是從每個像素減去在訓練集上計算出的 RGB 平均值。
通過最大池化層執行池化,最大池化層跟隨一些卷積層。 并非所有卷積層都跟隨最大池化。 最大合并在`2 x 2`像素的窗口上執行,步幅為 2。每個隱藏層都使用 ReLU 激活。 在大多數 VGG 變體中,過濾器的數量隨深度的增加而增加。 下圖顯示了 16 層架構 VGG-16。 下一節顯示了具有均勻`3 x 3`x卷積(VGG-19)的 19 層架構。 VGG 模型的成功證實了深度在圖像表示中的重要性:

VGG-16:輸入大小為`224 x 224 x 3`的 RGB 圖像,每層中的濾鏡數量都被圈起來
# 殘差神經網絡
在 ILSVRC 2015 中,由 Kaiming He 及其來自 Microsoft Research Asia 的合著者介紹了一種具有*跳躍連接*和*批量歸一化*的新穎 CNN 架構,稱為**殘差神經網絡**(**ResNet**)。 這樣,他們就可以訓練一個具有 152 層(比 VGG 網絡深八倍)的神經網絡,同時仍比 VGG 網絡具有更低的復雜度。 它的前 5 個錯誤率達到 3.57%,在此數據集上超過了人類水平的表現。
該架構的主要思想如下。 他們沒有希望一組堆疊的層將直接適合所需的基礎映射`H(x)`,而是嘗試適應殘差映射。 更正式地講,他們讓堆疊的層集學習殘差`R(x) = H(x) - x`,隨后通過跳過連接獲得真實映射。 然后將輸入添加到學習的殘差`R(x) + x`。
同樣,在每次卷積之后和激活之前立即應用批量歸一化:

剩余網絡的一個組成部分
與 VGG-19 相比,這是完整的 ResNet 架構。 點綴的跳過連接顯示尺寸增加; 因此,為了使添加有效,不執行填充。 同樣,尺寸的增加由顏色的變化表示:

到目前為止,我們已經討論過的 CNN 模型的所有變體都可以在 Keras 和 TensorFlow 中作為預訓練模型使用。 我們將在我們的遷移學習應用中大量使用它們。 這是用于加載各種 VGG 模型的 Keras 代碼段。 可以在[這里](https://keras.io/applications/)中找到更多內容:
```py
from keras.applications.vgg16 import VGG16
model = VGG16()
print(model.summary())
```
# 膠囊網絡
我們已經討論了各種 CNN 架構是如何演變的,并且已經研究了它們的連續改進。 現在我們可以將 CNN 用于更高級的應用,例如**高級駕駛員輔助系統**(**ADAS**)和自動駕駛汽車嗎? 我們能否在現實世界中實時地檢測道路上的障礙物,行人和其他重疊物體? 也許不會! 我們還不在那里。 盡管 CNN 在 ImageNet 競賽中取得了巨大成功,但 CNN 仍然存在一些嚴重的局限性,將它們的適用性限制在更高級的現實問題中。 CNN 的翻譯不變性差,并且缺乏有關方向的信息(或*姿勢*)。
姿勢信息是指相對于觀看者的三維方向,還指照明和顏色。 旋轉物體或改變照明條件時,CNN 確實會帶來麻煩。 根據 Hinton 的說法,CNN 根本無法進行*順手性*檢測; 例如,即使他們都接受過這兩種訓練,他們也無法從右鞋中分辨出左鞋。 CNN 受到這些限制的原因之一是使用最大池化,這是引入不變性的粗略方法。 通過粗略不變性,我們的意思是,如果圖像*稍有*移位/旋轉,則最大合并的輸出不會發生太大變化。 實際上,我們不僅需要不變性,還需要**等價性**; 即,在圖像的**對稱** **變換**下的不變性。
邊緣檢測器是 CNN 中的第一層,其功能與人腦中的視覺皮層系統相同。 大腦和 CNN 之間的差異出現在較高水平。 有效地將低層視覺信息路由到高層信息,例如各種姿勢和顏色或各種比例和速度的對象,這是由皮質微柱完成的,Hinton 將其命名為*膠囊*。 這種*路由*機制使人的視覺系統比 CNN 更強大。
**膠囊網絡**(**CapsNets**)對 CNN 架構進行了兩個基本更改:首先,它們用向量輸出膠囊代替 CNN 的標量輸出特征檢測器; 其次,他們將最大池與按協議路由一起使用。 這是一個簡單的 CapsNet 架構:

這是一種淺薄的架構,需要根據 MNIST 數據(`28 x 28`個手寫數字圖像)進行訓練。 這具有兩個卷積層。 第一卷積層具有 256 個特征圖,具有`9 x 9`內核(步幅為 1)和 ReLu 激活。 因此,每個特征圖是`(28 - 9 + 1) x (28 - 9 + 1)`或`20 x 20`。第二個卷積層又具有 256 個特征圖,具有`9 x 9`個內核(步幅為 2)和 ReLu 激活。 這里每個特征圖是`6 x 6`,`6 = ((20 - 9) / 2 + 1)`。 對該層進行了重塑,或者將特征圖重新分組為 32 組,每組具有 8 個特征圖(`256 = 8 x 32`)。 分組過程旨在創建每個大小為 8 的特征向量。為了表示姿勢,向量表示是一種更自然的表示。 來自第二層的分組特征圖稱為**主膠囊**層。 我們有(`32 x 6 x 6`)八維膠囊向量,其中每個膠囊包含 8 個卷積單元,內核為`9 x 9`,步幅為 2。最后一個膠囊層(**DigitCaps**)對于每十個類別有一個十六維的膠囊,這些膠囊中的每一個都從主膠囊層中的所有膠囊接收輸入。
膠囊的輸出向量的長度表示由膠囊表示的實體存在于當前輸入中的概率。 膠囊向量的長度被歸一化,并保持在 0 到 1 之間。此外,在向量的范數上使用了壓縮函數,以使短向量縮小到幾乎零長度,而長向量縮小到略小于 1 的長度。
壓縮函數為:

其中`x`是向量的范數,因此`x > 0`(請參見下圖):

`W[ij]`是每個初級膠囊中`u[i]`,`i ∈ (1, 32 x 6 x 6)`和`v[j]`,在 DigitCaps 中`j ∈ (1, 10)`。 在此,`u_hat[j|i] = w[ij]u[i]`被稱為預測向量,并且像一個已轉換(旋轉/翻譯)的輸入膠囊向量`u[i]`。 膠囊的總輸入`s[j]`是來自下一層膠囊的所有預測向量的加權總和。 這些權重`c[ij]`的總和為 1,在 Hinton 中稱為**耦合系數**。 一開始,它假設膠囊`i`應該與母體膠囊`j`結合的對數先驗概率對于所有`i`和`j`都是相同的,用`b[ij]`表示。 因此,可以通過此眾所周知的 softmax 轉換來計算耦合系數:

通過稱為**協議路由**的算法,這些耦合系數與網絡的權重一起迭代更新。 簡而言之,它執行以下操作:如果主膠囊`i`的預測向量與可能的父級`j`的輸出具有大的標量積,則耦合系數`b[ij]`對于該父對象增加而對于其他父對象減少。
完整的路由算法在這里給出:

左側顯示了如何通過權重矩陣`W[ij]`將所有主膠囊連接到數字膠囊。 此外,它還描述了如何通過非線性壓縮函數計算耦合系數以及如何計算 DigitCaps 的十六維輸出。 在右側,假設主膠囊捕獲了兩個基本形狀:輸入圖像中的三角形和矩形。 旋轉后將它們對齊會根據旋轉量給出**房屋**或**帆船**。 很明顯,這兩個物體在極少或幾乎沒有旋轉的情況下結合在一起,形成了帆船。 即,兩個主膠囊比房屋更對準以形成船。 因此,路由算法應更新`b[i, 船]`的耦合系數:
```py
procedure routing (, r, l):
for all capsule i in layer l and capsule j in layer (l + 1): bij <- 0
for r iterations do:
for all capsule i in layer l: ci <- softmax (bi)
for all capsule j in layer (l + 1):
for all capsule j in layer (l + 1): vj <- squash (sj)
for all capsule i in layer l and capsule j in layer (l + 1):
return vj
```
最后,我們需要適當的損失函數來訓練該網絡。 在此,將*數字存在的余量損失*用作損失函數。 它還考慮了數字重疊的情況。 對于每個膠囊`k`,單獨的裕量損失`L[k]`用于允許檢測多個重疊的數字。 `L[k]`觀察膠囊向量的長度,對于`k`類的數字,第`k`個膠囊向量的長度應最大:

如果存在第`k`位,則`T[k] = 1`。 `m+ = 0.9`,`m- = 0.1`。 `λ`用于降低缺少數字類別的損失的權重。 與`L[k]`一起,圖像重建誤差損失被用作網絡的正則化。 如 CapsNet 架構所示,數字膠囊的輸出被饋送到由三個完全連接的層組成的解碼器中。 邏輯單元的輸出與原始圖像像素強度之間的平方差之和最小。 重建損失縮小了 0.0005 倍,因此在訓練過程中它不控制邊際損失。
[CapsNet 的 TensorFlow 實現在此處可用](https://github.com/naturomics/CapsNet-Tensorflow)。
# 循環神經網絡
**循環神經網絡**(**RNN**)專用于處理一系列值,如`x(1) ... x(t)`。 例如,如果要在給定序列的最新歷史的情況下預測序列中的下一項,或者將一種語言的單詞序列翻譯為另一種語言,則需要進行序列建模。 RNN 與前饋網絡的區別在于其架構中存在反饋環路。 人們常說 RNN 有記憶。 順序信息保留在 RNN 的隱藏狀態中。 因此,RNN 中的隱藏層是網絡的內存。 從理論上講,RNN 可以任意長的順序使用信息,但實際上,它們僅限于回顧一些步驟。
我們將在后面解釋:

通過展開網絡中的反饋回路,我們可以獲得前饋網絡。 例如,如果我們的輸入序列的長度為 4,則可以按以下方式展開網絡。 展開相同的權重集后,在所有步驟中共享`U`,`V`和`W`,與傳統 DNN 不同。 因此,實際上我們在每個步驟都執行相同的任務,只是輸入的內容不同。 這大大減少了我們需要學習的參數總數。 現在,要學習這些共享的權重,我們需要一個損失函數。 在每個時間步長處,我們都可以將網絡輸出`y(t)`與目標序列`s(t)`進行比較,并得出誤差`E(t)`。 因此,總誤差為:
:

讓我們看一下使用基于梯度的優化算法學習權重所需的總誤差導數。 我們有`h[t] = Uφh[t-1] + Wx[t]`,`Φ`是非線性激活,而`y[t] = Vφh[t]`。
現在是:

根據鏈式規則,我們有:

在此,雅可比行列式`?h[t]/?h[k]`,即層`t`相對于前一層`k`本身是雅可比行列式

的乘積。
使用前面的`h[t]`方程,我們有:

因此,雅可比式`?h[t]/?h[k]`的范數由乘積

給出。 如果數量`||?h[s]/?h[s-1]||`小于 1,則在較長的序列(例如 100 步)中,這些規范的乘積將趨于零。 同樣,如果范數大于 1,則長序列的乘積將成倍增長。 這些問題在 RNN 中稱為**消失梯度**和**梯度爆炸**。 因此,在實踐中,RNN 不能具有很長的記憶。
# LSTM
隨著時間的流逝,RNN 開始逐漸失去歷史背景,因此很難進行實際訓練。 這就是 LSTM 出現的地方! LSTM 由 Hochreiter 和 Schmidhuber 于 1997 年引入,可以記住來自非常長的基于序列的數據中的信息,并可以防止梯度消失等問題。 LSTM 通常由三個或四個門組成,包括輸入,輸出和忘記門。
下圖顯示了單個 LSTM 單元的高級表示:

輸入門通常可以允許或拒絕進入的信號或輸入以更改存儲單元狀態。 輸出門通常會根據需要將該值傳播到其他神經元。 遺忘門控制存儲單元的自循環連接以根據需要記住或忘記以前的狀態。 通常,將多個 LSTM 單元堆疊在任何深度學習網絡中,以解決現實世界中的問題,例如序列預測。 在下圖中,我們比較了 RNN 和 LSTM 的基本結構:

下圖顯示了 LSTM 單元和信息流的詳細架構。 令`t`表示一個時間步長; `C`為單元狀態;`h`為隱藏狀態。 通過稱為*門*的結構,LSTM 單元具有刪除信息或向單元狀態添加信息的能力。 門`i`,`f`和`o`分別代表輸入門,忘記門和輸出門,它們中的每一個都由 Sigmoid 層調制, 輸出從零到一的數字,控制這些門的輸出應通過多少。 因此,這有助于保護和控制單元狀態:

通過 LSTM 的信息流包括四個步驟:
1. **決定要從單元狀態中丟棄哪些信息**:該決定由稱為**遺忘門層**的 Sigmoid 決定。 將仿射變換應用于`h[t]`,`x[t-1]`,并將其輸出通過 Sigmoid 擠壓函數傳遞,以得到一個介于 0 和 1 之間的數字。 單元狀態`C[t-1]`。 1 表示應保留內存,零表示應完全擦除內存。
2. **決定將哪些新信息寫入內存**:這是一個兩步過程。 首先,使用一個稱為**輸入門層**的 Sigmoid 層,即`i[t]`來確定將信息寫入哪個位置。接下來,tanh 層將創建新的候選信息。 書面。
3. **更新內存狀態**:將舊的內存狀態乘以`f[t]`,擦除確定為可忘記的內容。 然后,在通過`i[t]`縮放它們之后,添加在*步驟 2* 中計算的新狀態信息。
4. **輸出存儲器狀態**:單元狀態的最終輸出取決于當前輸入和更新的單元開始。 首先,使用 Sigmoid 層來確定我們要輸出的單元狀態的哪些部分。 然后,單元狀態通過 tanh 并乘以 Sigmoid 門的輸出。
我建議您在查看 [Christophers 的博客](http://colah.github.io/posts/2015-08-Understanding-LSTMs/),以獲取有關 LSTM 步驟的更詳細說明。 我們在這里查看的大多數圖表均來自此。
LSTM 可以用于序列預測以及序列分類。 例如,我們可以預測未來的股價。 另外,我們可以使用 LSTM 構建分類器,以預測來自某些健康監控系統的輸入信號是致命還是非致命信號(二分類器)。 我們甚至可以使用 LSTM 構建文本文檔分類器。 單詞序列將作為 LSTM 層的輸入,LSTM 的隱藏狀態將連接到密集的 softmax 層作為分類器。
# 棧式 LSTM
如果我們想了解順序數據的分層表示,可以使用 LSTM 層的棧。 每個 LSTM 層輸出一個向量序列,而不是序列中每個項的單個向量,這些向量將用作后續 LSTM 層的輸入。 隱藏層的這種層次結構使我們的順序數據可以更復雜地表示。 堆疊的 LSTM 模型可用于對復雜的多元時間序列數據進行建模。
# 編碼器-解碼器 – 神經機器翻譯
機器翻譯是計算語言學的一個子領域,涉及將文本或語音從一種語言翻譯成另一種語言。 傳統的機器翻譯系統通常依賴于基于文本統計屬性的復雜特征工程。 最近,深度學習已被用于解決此問題,其方法稱為**神經機器翻譯**(**NMT**)。 NMT 系統通常由兩個模塊組成:編碼器和解碼器。
它首先使用*編碼器*讀取源句子,以構建思想向量:代表該句子含義的數字序列。 *解碼器*處理句子向量以發出對其他目標語言的翻譯。 這稱為編碼器-解碼器架構。 編碼器和解碼器通常是 RNN 的形式。 下圖顯示了使用堆疊 LSTM 的編碼器-解碼器架構。 在這里,第一層是一個嵌入層,用于通過密集的實向量來表示源語言中的單詞。 為源語言和目標語言都預定義了詞匯表。 不在詞匯表中的單詞由固定單詞`<未知>`表示,并由固定嵌入向量表示。 該網絡的輸入首先是源句子,然后是句子標記`<s>`的結尾,指示從編碼模式到解碼模式的轉換,然后饋入目標句子:

數據來源:https://www.tensorflow.org/tutorials/seq2seq
輸入嵌入層后面是兩個堆疊的 LSTM 層。 然后,投影層將最上面的隱藏狀態轉換為尺寸為`V`(目標語言的詞匯量)的對率向量。 這里,交叉熵損失用于通過反向傳播訓練網絡。 我們看到在訓練模式下,源句子和目標句子都被輸入到網絡中。 在推理模式下,我們只有源句。 在那種情況下,可以通過幾種方法來完成解碼,例如貪婪解碼,與貪婪解碼結合的注意力機制以及集束搜索解碼。 我們將在這里介紹前兩種方法:

在貪婪的解碼方案中(請參見前面兩個圖的左手圖),我們選擇最有可能的單詞(以最大對率值描述為發射的單詞),然后將其反饋給解碼器作為輸入。 繼續該解碼過程,直到產生句子結束標記`</s>`作為輸出符號。
由源句子的句子結尾標記生成的上下文向量必須對我們需要了解的有關源句子的所有內容進行編碼。 它必須充分體現其含義。 對于長句子,這意味著我們需要存儲非常長的記憶。 研究人員發現,反轉源序列或兩次饋入源序列有助于網絡更好地記憶事物。 對于與英語非常相似的法語和德語這樣的語言,反轉輸入是有意義的。 對于日語,句子的最后一個單詞可能會高度預測英語翻譯中的第一個單詞。 因此,這里的反轉會降低翻譯質量。 因此,一種替代解決方案是使用**注意機制**(如前兩個圖的右圖所示)。
現在,無需嘗試將完整的源句子編碼為固定長度的向量,而是允許解碼器在輸出生成的每個步驟中使*參與*到源句子的不同部分。 因此,我們將第`t`個目標語言單詞的基于注意力的上下文向量`c[t]`表示為所有先前源隱藏狀態的加權和:

注意權重為:

*得分*的計算如下:`sc(h[t], h[s]) = h[t] W h[s]`。
`W`是權重矩陣,將與 RNN 權重一起學習。 該得分函數稱為 **Luong 的**乘法樣式得分。 此分數還有其他一些變體。 最后,通過將上下文向量與當前目標隱藏狀態組合如下來計算**注意向量**,`a[t]`:

注意機制就像只讀存儲器,其中存儲了源的所有先前隱藏狀態,然后在解碼時讀取它們。 TensorFlow 中 NMT 的源代碼[可在此處獲得](https://github.com/tensorflow/nmt/)。
# 門控循環單元
**門控循環單元**(**GRU**)與 LSTM 相關,因為兩者均利用不同的門控信息方式來防止梯度消失和存儲長期記憶。 GRU 具有兩個門:重置門`r`和更新門`z`,如下圖所示。 復位門確定如何將新輸入與先前的隱藏狀態`h[t-1]`組合在一起,而更新門則確定要保留多少先前狀態信息。 如果我們將重置設置為全 1 并將更新門更新為全零,我們將得到一個簡單的 RNN 模型:

GRU 相對較新,其表現與 LSTM 相當,但由于結構更簡單,參數更少,因此它們在計算上更加高效。 這是 LSTM 和 GRU 之間的一些結構差異:
* 一個 GRU 有兩個門,而 LSTM 有三個門。 GRU 沒有 LSTM 中存在的輸出門。
* 除隱藏狀態外,GRU 沒有其他內部內存`C[t]`。
* 在 GRU 中,當計算輸出時,是非線性(tanh)的。
如果有足夠的數據,建議使用 LSTM,因為 LSTM 的更高表達能力可能會導致更好的結果。
# 記憶神經網絡
大多數機器學習模型無法讀取和寫入長期內存組件,也無法將舊內存與推理無縫結合。 RNN 及其變體(例如 LSTM)確實具有存儲組件。 但是,它們的內存(由隱藏狀態和權重編碼)通常太小,不像我們在現代計算機中發現的大塊數組(以 RAM 的形式)。 他們試圖將所有過去的知識壓縮為一個密集的向量-記憶狀態。 對于諸如虛擬協助或**問題解答**(**QA**)系統之類的復雜應用,該應用可能會受到很大限制,在這種系統中,長期記憶有效地充當了(動態)知識庫, 輸出是文本響應。 為了解決這個問題,Facebook AI 研究小組開發了**記憶神經網絡**(**MemNNs**)。 MemNN 的中心思想是將深度學習文獻中為推理而開發的成功學習策略與可以像 RAM 一樣讀寫的內存組件相結合。 同樣,模型被訓練以學習如何與存儲組件一起有效地操作。 存儲網絡由存儲器`m`,對象的索引數組(例如,向量或字符串數??組)和要學習的四個組件`I, G, O, R`組成:
* `I`:輸入特征映射`I`,它將輸入輸入轉換為內部特征表示。
* `G`:*通用化*組件,`G`,在輸入新輸入的情況下更新舊內存。 這被稱為**泛化**,因為網絡有機會在此階段壓縮和泛化其內存,以備將來使用。
* `O`:輸出特征圖`O`,在給定新輸入和*當前存儲狀態*的情況下,該特征圖空間中將生成新輸出。
* `R`:*響應*組件`R`,可將輸出轉換為所需的響應格式,例如文本響應或動作:

當分量`I`,`G`,`O`和`R`是*神經網絡*時,則所得系統稱為 **MemNN**。 讓我們嘗試通過示例質量檢查系統來理解這一點。 系統將獲得一系列事實和問題。 它將輸出該問題的答案。 我們有以下六個文本事實和一個問題,問:“牛奶現在在哪里?”:
* 喬去了廚房
* 弗雷德去了廚房
* 喬拿起牛奶
* 喬去了辦公室
* 喬離開了牛奶
* 喬去洗手間
請注意,語句的某些子集包含答案所需的信息,而其他子集本質上是無關緊要的。 我們將用 MemNN 模塊`I`,`G`,`O`和`R`來表示這一點。模塊`I`是一個簡單的嵌入模塊,它將文本轉換為二元詞袋向量。 文本以其原始形式存儲在下一個可用的存儲插槽中,因此`G`模塊非常簡單。 一旦去除了停用詞,給定事實中使用的單詞詞匯為`V = {喬, 弗雷德, 旅行, 撿起, 離開, 離開, 去辦公室, 洗手間, 廚房, 牛奶}`。 現在,這是所有文本存儲后的內存狀態:
| **內存位置序號** | 喬 | 弗雷德 | ... | 辦公室 | 浴室 | 廚房 | 牛奶 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 1 | 0 | | 0 | 0 | 1 | 0 |
| 2 | 0 | 1 | | 0 | 0 | 1 | 0 |
| 3 | 1 | 0 | | 0 | 0 | 0 | 1 |
| 4 | 1 | 0 | | 1 | 0 | 0 | 0 |
| 5 | 1 | 0 | | 0 | 0 | 0 | 1 |
| 6 | 1 | 0 | | 0 | 1 | 0 | 0 |
| 7 | | | | | | | |
`O`模塊通過在給定問題`q`的情況下找到`k`個支持存儲器來產生輸出特征。 對于`k = 2`,使用以下方法檢索最高得分的支持內存:

其中`s[0]`是輸入`q`和`m[i]`之間的評分函數,`o1`是具有最佳匹配的內存`m`的索引。 現在,使用查詢和第一個檢索到的內存,我們可以檢索下一個內存`m[o2]`,這兩個內存都很接近:

合并的查詢和內存結果為`o = [q, m[o1], m[o2]] = [現在牛奶在哪里, 喬離開了牛奶, 喬去了辦公室]`。 最后,模塊`R`需要產生文本響應`r`。 `R`模塊可以輸出一個單詞的答案,或者可以輸出一個完整句子的 RNN 模塊。 對于單字響應,令`r`是對`[q, m[o1], m[o2]]`和單詞`w`的回應。 因此,最后的回應`r`是辦公室一詞:

這種模型很難使用反向傳播來進行端到端訓練,并且需要在網絡的每個模塊上進行監督。 對此有一點修改,實際上是稱為**端到端存儲網絡**(**MemN2N**)的連續版本的存儲網絡。 該網絡可以通過反向傳播進行訓練。
# MemN2Ns
我們從一個查詢開始:牛奶現在在哪里? 使用大小為`V`的向量,用成袋的單詞進行編碼。 在最簡單的情況下,我們使用嵌入`B(d x V)`將向量轉換為大小為`d`的詞嵌入。 我們有`u = embeddingB(q)`:

輸入句子`x1, x2, ..., xi`通過使用另一個嵌入矩陣`A(d x V)`存儲在內存中,其大小與`B[mi] = embeddingA(x[i])`。 每個嵌入式查詢`u`與每個內存`m[i]`之間的相似度是通過取內積和 softmax 來計算的:`p[i] = softmax(u^T m[i])`。
輸出存儲器表示如下:每個`x[i]`具有對應的輸出向量`c[i]`,可以用另一個嵌入矩陣`C`表示。 然后,來自存儲器的響應向量`o`是`c[i]`上的總和,并由來自以下輸入的概率向量加權:

最后,將`o`和`u`之和與權重矩陣`W(V x d)`相乘。 結果傳遞到 softmax 函數以預測最終答案:

[MemN2N 的 TensorFlow 實現可在此處獲得](https://github.com/carpedm20/MemN2N-tensorflow)。
# 神經圖靈機
**神經圖靈機**(**NTM**)受到**圖靈機**(**TM**)的啟發:定義了一個抽象機。 TM 可以根據規則表來操作一條膠帶上的符號。 對于任何計算機算法,TM 都可以模擬該算法的邏輯。 機器將其頭放在單元格上方并在其中讀取或寫入符號。 此后,根據定義的規則,它可以向左或向右移動甚至停止程序。
NTM 架構包含兩個基本組件:神經網絡控制器和內存。 下圖顯示了 NTM 架構的高層表示:

控制器使用輸入和輸出向量與外部世界進行交互。 與標準神經網絡不同,此處的控制器還使用選擇性讀取和寫入操作與存儲矩陣進行交互。 內存是一個實值矩陣。 內存交互是端到端可區分的,因此可以使用梯度下降對其進行優化。 NTM 可以從輸入和輸出示例中學習簡單的算法,例如復制,排序和關聯召回。 而且,與 TM 不同,NTM 是可通過梯度下降訓練的可微分計算機,為學習程序提供了一種實用的機制。
控制器可以由 LSTM 建模,LSTM 具有自己的內部存儲器,可以補充矩陣中更大的存儲器。 可以將控制器與計算機中的 CPU 相比較,并且可以將存儲矩陣與計算機的 RAM 相比較。
讀寫頭選擇要讀取或寫入的內存部分。 可以通過神經網絡中的隱藏層(可能是 softmax 層)對它們進行建模,以便可以將它們視為外部存儲單元上的權重之和,這些權重之和為 1。此外,請注意,模型參數的數量是受控的,不會隨存儲容量的增長而增加。
# 選擇性注意力
控制器輸出用于確定要讀取或寫入的存儲器位置。 這由一組分布在所有內存位置上的權重定義,這些權重之和為 1。權重由以下兩種機制定義。 想法是為控制器提供幾種不同的讀取或寫入內存的模式,分別對應于不同的數據結構:
* **基于內容的**:使用相似度度量(例如余弦相似度)將控制器的鍵`k`輸出與所有存儲位置進行比較,然后所有距離均由 softmax 歸一化,得到和為一的權重:

在這種情況下,`β ≥ 1`稱為清晰度參數,并控制對特定位置的聚焦。 它還為網絡提供了一種方法來決定其希望內存位置訪問的精確度。 就像模糊均值聚類中的模糊系數。
* **基于位置的**:基于位置的尋址機制旨在跨存儲器位置的簡單迭代。 例如,如果當前權重完全集中在單個位置上,則旋轉 1 會將焦點移到下一個位置。 負移將使權重朝相反方向移動。 控制器輸出一個移位內核`s`(即`[-n, n]`上的 softmax),將其與先前計算的存儲器權重進行卷積以產生移位的存儲器位置,如下圖所示。 這種轉變是循環的; 也就是說,它環繞邊界。 下圖是內存的熱圖表示—較深的陰影表示更多的權重:

在應用旋轉移位之前,將內容尋址所給定的權重向量與先前的權重向量`w[t-1]`相結合,如下所示:

在此,`g[t]`是由控制器頭發出的標量*內插門*,范圍為`(0, 1)`。 如果`g[t] = 1`,則忽略先前迭代的加權。
# 讀操作
令`M[t]`為時間`t`的`N x M`存儲矩陣的內容,其中`N`是存儲位置的數量,`M`是每個位置的向量大小。 時間`t`的讀取頭由向量`w[t]`給出。

`M`讀取向量`r[t]`的長度定義為行向量`M[t](i)`的凸組合,在內存中:

# 寫操作
每個寫頭接收一個*擦除向量*, `e[t]`和一個*加性*向量,`a[t]`,以像 LSTM 單元一樣重置和寫入存儲器,如下所示:`M[t](i) ← M[t](i) [1 - e[t](i) w[t](i)] + w[t](i) a[t](i)`。
這是上述操作的偽代碼:
```py
mem_size = 128 #The size of memory
mem_dim = 16 #The dimensionality for memory
shift_range = 1 # defining shift[-1, 0, 1]
## last output layer from LSTM controller: last_output
## Previous memory state: M_prev
def Linear(input_, output_size, stddev=0.5):
'''Applies a linear transformation to the input data: input_
implements dense layer with tf.random_normal_initializer(stddev=stddev)
as weight initializer
''''
def get_controller_head(M_prev, last_output, is_read=True):
k = tf.tanh(Linear(last_output, mem_dim))
# Interpolation gate
g = tf.sigmoid(Linear(last_output, 1)
# shift weighting
w = Linear(last_output, 2 * shift_range + 1)
s_w = softmax(w)
# Cosine similarity
similarity = smooth_cosine_similarity(M_prev, k) # [mem_size x 1]
# Focusing by content
content_focused_w = softmax(scalar_mul(similarity, beta))
# Convolutional shifts
conv_w = circular_convolution(gated_w, s_w)
if is_read:
read = matmul(tf.transpose(M_prev), w)
return w, read
else:
erase = tf.sigmoid(Linear(last_output, mem_dim)
add = tf.tanh(Linear(last_output, mem_dim))
return w, add, erase
```
[NTM 的完整 TensorFlow 實現可在此處獲得](https://github.com/carpedm20/NTM-tensorflow)。 NTM 算法可以學習復制-他們可以學習復制隨機數序列的算法。 下面顯示了 NTM 如何使用內存讀寫頭并將其移位以實現復制算法:

類似地,給定一組隨機序列和相應的排序序列,NTM 可以從數據中高效地學習排序算法。
# 基于注意力的神經網絡模型
我們已經討論了基于注意力的機器翻譯模型。 基于注意力的模型的優點在于,它們提供了一種解釋模型并理解其工作方式的方式。 注意機制是記憶以前的內部狀態的一種形式。 這就像內部存儲器。 與典型的存儲器不同,這里的存儲器訪問機制是軟的,這意味著網絡將檢索所有存儲器位置的加權組合,而不是單個離散位置的值。 軟存儲器訪問使通過反向傳播訓練網絡變得可行。 基于注意的架構不僅用于機器翻譯,還可以用于自動生成圖像標題。
這項工作于 2016 年發表在論文[《Show,Attend and Tell:帶有視覺注意的神經圖像字幕生成》](https://arxiv.org/abs/1502.03044)上,作者是 Kelvin Xu 及其合著者。 在這里,從注意力權重來看,我們看到隨著模型生成每個單詞,其注意力發生變化以反映圖像的相關部分。 [此關注模型的 TensorFlow 實現可在此處獲得](https://github.com/yunjey/show-attend-and-tell):

# 總結
本章介紹了神經網絡架構的各種進展及其在各種實際問題中的應用。 我們討論了對這些架構的需求,以及為什么簡單的深度多層神經網絡不能充分解決各種問題,因為它具有強大的表達能力和豐富的假設空間。 討論遷移學習用例時,將在后面的章節中使用其中討論的許多架構。 提供了幾乎所有架構的 Python 代碼參考。 我們還試圖清楚地解釋一些最近的架構,例如 CapsNet,MemNN 和 NTM。 當您逐步學習遷移學習用例時,我們將經常參考本章。
下一章將介紹轉學的概念。
- TensorFlow 1.x 深度學習秘籍
- 零、前言
- 一、TensorFlow 簡介
- 二、回歸
- 三、神經網絡:感知器
- 四、卷積神經網絡
- 五、高級卷積神經網絡
- 六、循環神經網絡
- 七、無監督學習
- 八、自編碼器
- 九、強化學習
- 十、移動計算
- 十一、生成模型和 CapsNet
- 十二、分布式 TensorFlow 和云深度學習
- 十三、AutoML 和學習如何學習(元學習)
- 十四、TensorFlow 處理單元
- 使用 TensorFlow 構建機器學習項目中文版
- 一、探索和轉換數據
- 二、聚類
- 三、線性回歸
- 四、邏輯回歸
- 五、簡單的前饋神經網絡
- 六、卷積神經網絡
- 七、循環神經網絡和 LSTM
- 八、深度神經網絡
- 九、大規模運行模型 -- GPU 和服務
- 十、庫安裝和其他提示
- TensorFlow 深度學習中文第二版
- 一、人工神經網絡
- 二、TensorFlow v1.6 的新功能是什么?
- 三、實現前饋神經網絡
- 四、CNN 實戰
- 五、使用 TensorFlow 實現自編碼器
- 六、RNN 和梯度消失或爆炸問題
- 七、TensorFlow GPU 配置
- 八、TFLearn
- 九、使用協同過濾的電影推薦
- 十、OpenAI Gym
- TensorFlow 深度學習實戰指南中文版
- 一、入門
- 二、深度神經網絡
- 三、卷積神經網絡
- 四、循環神經網絡介紹
- 五、總結
- 精通 TensorFlow 1.x
- 一、TensorFlow 101
- 二、TensorFlow 的高級庫
- 三、Keras 101
- 四、TensorFlow 中的經典機器學習
- 五、TensorFlow 和 Keras 中的神經網絡和 MLP
- 六、TensorFlow 和 Keras 中的 RNN
- 七、TensorFlow 和 Keras 中的用于時間序列數據的 RNN
- 八、TensorFlow 和 Keras 中的用于文本數據的 RNN
- 九、TensorFlow 和 Keras 中的 CNN
- 十、TensorFlow 和 Keras 中的自編碼器
- 十一、TF 服務:生產中的 TensorFlow 模型
- 十二、遷移學習和預訓練模型
- 十三、深度強化學習
- 十四、生成對抗網絡
- 十五、TensorFlow 集群的分布式模型
- 十六、移動和嵌入式平臺上的 TensorFlow 模型
- 十七、R 中的 TensorFlow 和 Keras
- 十八、調試 TensorFlow 模型
- 十九、張量處理單元
- TensorFlow 機器學習秘籍中文第二版
- 一、TensorFlow 入門
- 二、TensorFlow 的方式
- 三、線性回歸
- 四、支持向量機
- 五、最近鄰方法
- 六、神經網絡
- 七、自然語言處理
- 八、卷積神經網絡
- 九、循環神經網絡
- 十、將 TensorFlow 投入生產
- 十一、更多 TensorFlow
- 與 TensorFlow 的初次接觸
- 前言
- 1.?TensorFlow 基礎知識
- 2. TensorFlow 中的線性回歸
- 3. TensorFlow 中的聚類
- 4. TensorFlow 中的單層神經網絡
- 5. TensorFlow 中的多層神經網絡
- 6. 并行
- 后記
- TensorFlow 學習指南
- 一、基礎
- 二、線性模型
- 三、學習
- 四、分布式
- TensorFlow Rager 教程
- 一、如何使用 TensorFlow Eager 構建簡單的神經網絡
- 二、在 Eager 模式中使用指標
- 三、如何保存和恢復訓練模型
- 四、文本序列到 TFRecords
- 五、如何將原始圖片數據轉換為 TFRecords
- 六、如何使用 TensorFlow Eager 從 TFRecords 批量讀取數據
- 七、使用 TensorFlow Eager 構建用于情感識別的卷積神經網絡(CNN)
- 八、用于 TensorFlow Eager 序列分類的動態循壞神經網絡
- 九、用于 TensorFlow Eager 時間序列回歸的遞歸神經網絡
- TensorFlow 高效編程
- 圖嵌入綜述:問題,技術與應用
- 一、引言
- 三、圖嵌入的問題設定
- 四、圖嵌入技術
- 基于邊重構的優化問題
- 應用
- 基于深度學習的推薦系統:綜述和新視角
- 引言
- 基于深度學習的推薦:最先進的技術
- 基于卷積神經網絡的推薦
- 關于卷積神經網絡我們理解了什么
- 第1章概論
- 第2章多層網絡
- 2.1.4生成對抗網絡
- 2.2.1最近ConvNets演變中的關鍵架構
- 2.2.2走向ConvNet不變性
- 2.3時空卷積網絡
- 第3章了解ConvNets構建塊
- 3.2整改
- 3.3規范化
- 3.4匯集
- 第四章現狀
- 4.2打開問題
- 參考
- 機器學習超級復習筆記
- Python 遷移學習實用指南
- 零、前言
- 一、機器學習基礎
- 二、深度學習基礎
- 三、了解深度學習架構
- 四、遷移學習基礎
- 五、釋放遷移學習的力量
- 六、圖像識別與分類
- 七、文本文件分類
- 八、音頻事件識別與分類
- 九、DeepDream
- 十、自動圖像字幕生成器
- 十一、圖像著色
- 面向計算機視覺的深度學習
- 零、前言
- 一、入門
- 二、圖像分類
- 三、圖像檢索
- 四、對象檢測
- 五、語義分割
- 六、相似性學習
- 七、圖像字幕
- 八、生成模型
- 九、視頻分類
- 十、部署
- 深度學習快速參考
- 零、前言
- 一、深度學習的基礎
- 二、使用深度學習解決回歸問題
- 三、使用 TensorBoard 監控網絡訓練
- 四、使用深度學習解決二分類問題
- 五、使用 Keras 解決多分類問題
- 六、超參數優化
- 七、從頭開始訓練 CNN
- 八、將預訓練的 CNN 用于遷移學習
- 九、從頭開始訓練 RNN
- 十、使用詞嵌入從頭開始訓練 LSTM
- 十一、訓練 Seq2Seq 模型
- 十二、深度強化學習
- 十三、生成對抗網絡
- TensorFlow 2.0 快速入門指南
- 零、前言
- 第 1 部分:TensorFlow 2.00 Alpha 簡介
- 一、TensorFlow 2 簡介
- 二、Keras:TensorFlow 2 的高級 API
- 三、TensorFlow 2 和 ANN 技術
- 第 2 部分:TensorFlow 2.00 Alpha 中的監督和無監督學習
- 四、TensorFlow 2 和監督機器學習
- 五、TensorFlow 2 和無監督學習
- 第 3 部分:TensorFlow 2.00 Alpha 的神經網絡應用
- 六、使用 TensorFlow 2 識別圖像
- 七、TensorFlow 2 和神經風格遷移
- 八、TensorFlow 2 和循環神經網絡
- 九、TensorFlow 估計器和 TensorFlow HUB
- 十、從 tf1.12 轉換為 tf2
- TensorFlow 入門
- 零、前言
- 一、TensorFlow 基本概念
- 二、TensorFlow 數學運算
- 三、機器學習入門
- 四、神經網絡簡介
- 五、深度學習
- 六、TensorFlow GPU 編程和服務
- TensorFlow 卷積神經網絡實用指南
- 零、前言
- 一、TensorFlow 的設置和介紹
- 二、深度學習和卷積神經網絡
- 三、TensorFlow 中的圖像分類
- 四、目標檢測與分割
- 五、VGG,Inception,ResNet 和 MobileNets
- 六、自編碼器,變分自編碼器和生成對抗網絡
- 七、遷移學習
- 八、機器學習最佳實踐和故障排除
- 九、大規模訓練
- 十、參考文獻