機器之心原創,作者:蔣思源。

本文討論並實現了用於序列模型的基本深度方法,其中迴圈網路主要介紹了傳統的 LSTM 與 GRU,而卷積網路主要介紹了最近 CMU 研究者提出的時間卷積網路與實證研究。相比於我們熟知的經典迴圈網路方法,用 CNN 實現序列建模可能會更有意思,因此本文的實現部分重點介紹了時間卷積網路的實現。

這是機器之心 GitHub 實現專案的第四期,前面幾期分別介紹了卷積神經網路、生成對抗網路與帶動態路由的 CapsNet。

機器之心專案地址:

https://

github。com/jiqizhixin/M

L-Tutorial-Experiment

文章結構

序列建模

迴圈網路

表示式

計算圖

LSTM

GRU

卷積與時間卷積網路

全卷積與因果卷積

空洞卷積

高速公路網路與殘差模組

實現

LSTM的語言建模

時間卷積網路的語言建模

序列建模廣泛存在於自然語言處理、語音識別和計算機視覺等領域,這種任務通常需要將輸入序列轉換為輸出序列,例如將輸入的英文語句轉換為輸出的中文語句。從實踐經驗上來說,一般我們都將迴圈神經網路視為序列建模的預設配置。甚至 Ian Goodfellow 在《深度學習》一書中使用「序列建模:迴圈和遞迴網路」作為章節名,這些都表明序列建模與迴圈架構有非常緊密的聯絡。

因此本文在前一部分主要介紹了迴圈網路的概念、表示式和計算圖,並著重描述了 LSTM 與 GRU 兩種流行的變體。在實現部分,我們將基於 TensorFlow 在語言建模任務中實現 LSTM 與 GRU。

但序列建模不僅僅只有 RNN,一個關鍵的想法是在一維時間序列上使用一維卷積運算。此外,最近的研究表明一些卷積架構能在音訊合成、語言建模和機器翻譯任務中達到頂尖的準確度。因此,我們是否能找到像 LSTM 那樣的一般架構處理時序問題就顯得十分重要。

為了瞭解這種用於序列建模的卷積網路,我們將解讀最近 Shaojie Bai 等人完成的架構與實驗,包括構建時間卷積網路的因果卷積、空洞卷積和殘差連線等。後面我們同樣會根據他們提出的 TCN 測試語言建模任務,並儘量保證引數數量和 LSTM 與 GRU 處於同一量級。

序列建模

序列建模即將一個輸入或觀測序列對映到一個輸出或標記序列,李航在《統計學習方法》中也將其稱為標註問題。他表明標註問題是分類問題的推廣,又是更復雜的結構預測問題的簡單形式。標註問題或序列建模的目的在於學習一個模型,從而能對觀測序列給出標記序列作為預測,即最大化機率 P(y_1,y_2,。。。,y_n | x_1,x_2,。。。,x_n)。在傳統機器學習方法中,序列建模常用的方法有隱馬爾可夫模型和條件隨機場等,但近來 RNN 等深度方法憑藉強大的表徵能力在序列建模問題上有非常突出的表現。

但根據 Shaojie Bai 等人的定義,序列建模應該是在給定時間步 t 的情況下,只使用 x_0 到 x_t 的序列資訊預測輸出 y_t。當然這只是一般化的定義,具體問題還需要具體分析,例如機器翻譯最好可以使用雙向 RNN 獲取整個句子的資訊再轉化為譯文。因此一般序列建模的形式化表述如下:

序列建模為任意滿足因果約束的對映函式 f: X^T+1 → Y^T +1,它僅依賴於 x_1,x_2,。。。,x_t 而不使用 x_t,x_t+1,。。。,x_T 的資訊預測 y_t。

迴圈網路

迴圈神經網路是一類用於處理序列問題的神經網路,迴圈網路可以擴充套件到更長的序列。迴圈網路相比經典的全連線網路有非常大的提升,例如引數共享和構建長期依賴關係等。對於語句的序列建模,全連線網路會給每個輸入特徵分配一個單獨的引數,所以它需要分別學習句子每個位置的所有語言規則。而迴圈神經網路會在多個時間步內共享相同的引數,因此不必學習句子每個位置的所有語言規則。此外,迴圈網路會有一個記憶機制為當前時間步的預測提供前面時間步的資訊。

表示式

其實迴圈神經網路的基本原理可使用非常優美的表示式展示,若考慮動態系統的經典形式:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

它其實也可以視為一個迴圈神經網路,因為本質上任何涉及迴圈的函式都可以視為一個迴圈神經網路。以上 s^t 可視為系統在第 t 步的狀態,因此後一步的系統狀態會取決於前一步的系統狀態。我們注意到每一個系統狀態的計算都會使用相同的函式與引數,這樣迴圈地向後計算就能構建一個迴圈系統。如下第三個時間步的系統狀態可以表示為:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

這樣的表示式其實就展示了迴圈網路的本質。若我們具體考慮迴圈網路每一個時間步都存在輸入,且使用變數 h 表示迴圈網路的隱藏狀態(代替上述系統的狀態),那麼我們可以將一般的迴圈神經網路抽象為以下表達式:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

其中 x^t 表示第 t 個時間步上的輸入,當前時間步的隱藏狀態取決於前一時間步的隱藏狀態、當前時間步和所有時間步都有相同的引數θ。我們同樣可以將該表示式展開,例如 h^3 = f(h^2, x^3; θ) = f(f(h^1, x^2; θ), x^3; θ)。

該 RNN 的抽象表示式也說明了它只會利用過去時間步的資訊來預測當前的狀態。此外,迴圈神經網路連續使用相同的函式 f 與引數θ來計算不同時間步的狀態,這種方式在多個時間步上共享了相同的引數而降低了模型規模。

迴圈神經網路與全連線網路的區別可以很直觀地從抽象表示式中看出來,因為有無權重共享機制是它們最重要的屬性。最基本的全連線網路可以抽象為一個簡單的複合函式,因為每一層全連線網路其實都可以看作一個函式逼近器。

以下展示了三層全連線網路的抽象表示,其中 f^1 表示第一層或輸入層,將第一層的值作為輸入並計算第二層的啟用值 f^2,然後將第二層的啟用值作為輸入計算第三層的啟用值。這種複合函式展示了全連線網路的前饋傳播過程,而將複合函式的鏈式求導法則作為反向傳播演算法也就顯得十分自然。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

根據上面的全連線表示式,我們清楚地瞭解到迴圈網路複合的函式都是一樣的,而全連線網路複合的函式是不一樣的,這也是迴圈體權重共享的特點。當然我們描述迴圈網路的表示式只是迴圈體的抽象,典型的迴圈網路會增加額外的架構特性,例如讀取狀態資訊 h 進行預測的輸出層或導師驅動過程等。而很多迴圈網路的修正都集中在改進迴圈體以關注長期依賴關係,例如 LSTM 和 GRU 等。

以上只是從概念上解釋迴圈網路,我們並沒有具體學習迴圈網路的架構與模組,下一部分我們將以計算圖的形式具體展示迴圈網路的結構,包括常見的展開式與不同的變體架構等。

計算圖

上一節的抽象表示式展示了迴圈體的本質,而它們可以直觀地用計算圖表示出來。計算圖是形式化一組計算結構的方式,一般情況下,我們看到的迴圈網路展開結構都是這種計算圖,這一章節展示的計算圖參考自《深度學習》。例如上一節中隱藏狀態 h^t = f(h^t-1, x^t; θ) 的計算圖可以表示為:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

該計算圖展示了一個不帶輸出單元的迴圈網路架構,它只使用前一個時間步的隱藏單元資訊和當前時間步的輸入資訊,並利用相同的函式計算下一個隱藏單元的值。此外,上圖從左到右分別為迴圈圖和展開圖,迴圈圖非常簡潔,但展開圖詳細描述了計算過程與資訊流動路徑。

上述的計算圖其實只描述了迴圈體,它缺少了輸出對映與輸出單元。一般迴圈神經網路根據輸出單元和迴圈結構可以分為三種,即 Elman Network 類、Jordan Network 類和 N 到 1 的網路。以下分別是這三種網路的計算圖,它們基本上構成了迴圈神經網路架構(雙向 RNN 可以是它們的反向疊加)。

Elman Network 代表了一類迴圈網路,它的每一個時間步都有一個輸入與輸出,且迴圈連線發生在隱藏單元與隱藏單元之間。我們透過累積每一個預測 y hat 與 y 之間的誤差來確定損失函式 L,並執行沿時間的反向傳播訓練整個網路。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

以上展示了這種迴圈連線發生在隱藏層之間的網路,其中 x 和 y 分別代表資料點與對應的標註,h 為隱藏單元或迴圈體,L 是預測值與標註值之間的距離與損失。一般在第 t 個時間步,我們會輸入資料 x^t,並計算隱藏狀態 h^t = tanh(W*h^{t-1}+U*x^t),隨後 h^t 將傳入下一個時間步與當前時間步輸出的對數機率 o^t = c + V*h^t。最後我們就能根據輸出與標註值計算模型損失。

這種網路架構是非常經典的結構,我們可以將隱藏單元視為記憶的累積,即將過去的資訊傳遞到未來時間步。這種架構也非常容易擴充套件到深度架構,例如我們在 h 和 o 之間再加一個迴圈單元 h‘ 或在迴圈體中額外新增全連線結構等。如下展示了上述迴圈架構的計算式:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

其中在第 t 個時間步上的輸入 x^t 可以是一個詞嵌入向量或簡單地使用 One-hot 編碼。一般權重矩陣 U 的維度為 [詞嵌入長度 * 隱藏層的單元數],偏置向量 b 的維度等於隱藏層單元數。隱藏層輸出的向量(每一個元素為隱藏單元的啟用值),我們在將隱藏層向量執行仿射變換後,可將 o 視為未歸一化的對數機率,並計算 softmax 以和標註的詞嵌入向量進行對比。

Jordan Network 代表了一類迴圈網路,它的每一個時間步都有一個輸入與輸出,但迴圈連線只存在當前時間步的輸出和下一個時間步的隱藏單元之間。因為該架構在隱藏單元之間沒有迴圈連線,因此它沒有一個記憶機制來捕捉所有用於預測未來時間步的歷史資訊。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

這種架構雖然在能力上並沒有那麼強大,但它的優勢在於訓練過程中的解耦合與並行過程。因為既然我們使用 o^t 作為傳遞到後一步的資訊,那麼為什麼我們就不能使用標註 y^t 替換 o^t 而作為傳遞到後面的資訊呢?透過使用 y^t 替換 o^t,網路不再需要先計算前一時間步的隱藏狀態,再計算後一步的隱藏狀態,因此所有計算都能並行化。

Jordan Network 類的架構在推斷時還是會使用前一時間步的輸出值 o 來計算後一時間步的隱藏狀態。這種網路的一大缺點是,訓練過程中觀察到的資料與測試時看到的資料會有較大的不同。

最後一種架構會先讀取整個序列,然後再產生單個輸出,迴圈連線存在於隱藏單元之間。這種架構常用於閱讀理解等序列模型。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

這種架構只在最後一個隱藏單元輸出觀察值並給出預測,它可以概括序列併產生用於進一步運算的向量,例如在編碼器解碼器架構中,它可用於編碼整個序列並抽取上下文向量。

以上是迴圈神經網路抽象概念與基本的架構表示,它們非常有助於我們理解「迴圈」這個概念。但在實際建模中,RNN 經常出現梯度爆炸或梯度消失等問題,因此我們一般使用長短期記憶單元或門控迴圈單元代替基本的 RNN 迴圈體。它們引入了門控機制以遺忘或保留特定的資訊而加強模型對長期依賴關係的捕捉,它們同時也大大緩解了梯度爆炸或梯度消失的問題。

下面我們將簡要介紹這兩種非常流行的 RNN 變體,它們同樣希望生成透過時間的路徑,且導數既不會消失也不會爆炸。

LSTM

如前所示,迴圈網路的每一個隱藏層都有多個迴圈單元,隱藏層 h^t-1 的向量儲存了所有該層神經元在 t-1 步的啟用值。一般標準的迴圈網路會將該向量透過一個仿射變換並新增到下一層的輸入中,即 W*h^{t-1}+U*x^t。而這個簡單的計算過程由於重複使用 W 和 U 而會造成梯度爆炸或梯度消失。因此我們可以使用門控機制控制前一時間步隱藏層保留的資訊和當前時間步輸入的資訊,並選擇性地輸出一些值而作為該單元的啟用值。

一般而言,我們可以使用長短期記憶單元代替原版迴圈網路中的隱藏層單元而構建門控迴圈神經網路。以下兩張圖分別介紹了 LSTM 的基本概念和詳細的計算過程。

以下是 LSTM 單元的簡要結構,其中 Z 為輸入部分,Z_i、Z_o 和 Z_f 分別為控制三個門的值,即它們會透過啟用函式 f 對輸入資訊進行篩選。一般啟用函式可以選擇為 Sigmoid 函式,因為它的輸出值為 0 到 1,即表示這三個門被開啟的程度。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

圖片來源於李弘毅機器學習講義

若我們輸入 Z,那麼該輸入向量透過啟用函式得到的 g(Z) 和輸入門 f(Z_i ) 的乘積 g(Z)f(Z_i ) 就表示輸入資料經篩選後所保留的資訊。Z_f 控制的遺忘門將控制以前記憶的資訊到底需要保留多少,保留的記憶可以用方程 c*f(z_f)表示。以前保留的資訊加上當前輸入有意義的資訊將會保留至下一個 LSTM 單元,即我們可以用 c’ = g(Z)f(Z_i) + cf(z_f) 表示更新的記憶,更新的記憶 c‘ 也表示前面與當前所保留的全部有用資訊。我們再取這一更新記憶的啟用值 h(c’) 作為可能的輸出,一般可以選擇 tanh 啟用函式。最後剩下的就是由 Z_o 所控制的輸出門,它決定當前記憶所啟用的輸出到底哪些是有用的。因此最終 LSTM 的輸出就可以表示為 a = h(c‘)f(Z_o)。

上圖非常形象地展示了 LSTM 單元的工作原理,我們修改了《深度學習》一書中的結構圖,以更詳細地解釋該單元的計算過程。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

上圖詳細描述了 LSTM 單元的計算過程,其中 x^t 表示第 t 個時間步的輸入向量,一般可以是詞嵌入向量。h^t-1 為上一個時間步隱藏單元的輸出向量,該向量的元素個數等於該層神經元或 LSTM 單元的數量。U 和 W 分別是輸入資料和前一時間步隱藏單元輸出值的權重矩陣,一個 LSTM 單元因為不同的門控與輸入,需要 8 個不同的權重矩陣。此外,s^t 為第 t 個時間步的內部狀態或記憶,它會記住所有對於預測相關的資訊。最後,b 代表了各個門控和輸入的偏置項。

首先我們會向輸入門、遺忘門和輸出門饋送當前時間步的輸入 x^t 與前一步的隱藏單元 h^t-1,在對它們進行線性變換後,利用 Sigmoid 函式壓縮到區間(0, 1)以作為門控。這三個門控的計算式如上圖所示分別為 g^t、f^t 和 q^t,其中 i 表示該層級中的第 i 個 LSTM 單元。

我們將輸入與輸入門對應元素相乘,這就代表了當前時間步需要新增到記憶 s^t 的資訊。而前一時間步的記憶 s^t-1 與遺忘門 f^t 對應元素相乘就表示了需要保留或遺忘的歷史資訊是多少,最後將這兩部分的資訊相加在一起就更新了記憶 s^t,這一過程見上圖 s^t 的計算式。最後我們將記憶 s^t 的啟用值與輸出門 q^t 對應元素相乘,就能計算出當前時間步的 LSTM 單元輸出值,這一計算過程如上圖 h^t 所示。

Goodfellow 表示記憶 s^t-1 也可以用作門控單元的額外輸入(如上圖所示),但一般 LSTM 的門控單元只使用前一時間步的輸出 h^t-1 作為輸入,因此我們也不太確定怎樣才能使用 s^t-1 作為門控單元的額外輸入。

GRU

GRU 背後的原理與 LSTM 非常相似,即用門控機制控制輸入、記憶等資訊而在當前時間步做出預測。GRU 有兩個有兩個門,即一個重置門(reset gate)和一個更新門(update gate)。這兩個門控機制的特殊之處在於,它們能夠儲存長期序列中的資訊,且不會隨時間而清除或因為與預測不相關而移除。

從直觀上來說,重置門決定了如何將新的輸入資訊與前面的記憶相結合,更新門定義了前面記憶儲存到當前時間步的量。如果我們將重置門設定為 1,更新門設定為 0,那麼我們將再次獲得標準 RNN 模型。使用門控機制學習長期依賴關係的基本思想和 LSTM 一致,但還是有一些關鍵區別:

GRU 有兩個門(重置門與更新門),而 LSTM 有三個門(輸入門、遺忘門和輸出門)。

GRU 並不會控制並保留內部記憶(c_t),且沒有 LSTM 中的輸出門。

LSTM 中的輸入與遺忘門對應於 GRU 的更新門,重置門直接作用於前面的隱藏狀態。

在 Kyunghyun Cho 等人第一次提出 GRU 的論文中,他們用下圖展示了門控迴圈單元的結構:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

上圖的更新 z 將選擇隱藏狀態 h 是否更新為新的 h tilde。重置門 r 將決定前面的隱藏狀態是否需要遺忘。下面我們將具體解釋這兩個門控與隱藏狀態。

以下將描述第 j 個隱藏單元啟用值的計算方式。首先重置門 r_j 的計算式可以表示為:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

其中 σ 為 Sigmoid 函式,[*]_j 向量中的第 j 個元素,x 和 h_t-1 分別為當前輸入和前面層級的隱藏狀態,W_r 和 U_r 分別為更新門的權重矩陣。這個門控將當前輸入與前面隱藏狀態分別執行一個線性變換,再將結果壓縮至 0 到 1 以決定到底有多少過去的資訊需要遺忘。同樣,更新門的計算式可以表示為:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

更新門控制了前面時間步的記憶資訊和當前時間步所記的資訊,並傳遞到當前時間步最終記憶的資訊,這一點在以下兩個計算式中有非常明確的展示。

首先我們需要確定當前時間步需要記憶的資訊,即前面隱藏層的資訊到底需要保留多少以作為這一步的記憶。如下所示重置門 r 透過 Hadamard 乘積確定需要遺忘的歷史資訊,如果門控 r 為 0,那麼該時間步記憶的內容就僅從輸入獲取,如果門控 r 為 1,那麼就將利用所有的歷史資訊作為該時間步的記憶。注意我們將 h tilde 理解為該時間步的記憶,如果我們將它和前面時間步的記憶 h_t-1 組合,那麼就能得出當前時間步的最終記憶。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

其中 Φ 為啟用函式,一般我們可以選擇 tanh。在計算 h tilde 後,我們可以根據下式組合它與前面時間步的隱藏狀態,而最終得到當前時間步下該單元的啟用值或隱藏狀態:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

上式將使用更新門 z 權衡前面時間步的記憶和這一時間步的記憶,並得出當前時間步的最終記憶或啟用值。

因此,重置門其實強制隱藏狀態遺忘一些歷史資訊,並利用當前輸入的資訊。這可以令隱藏狀態遺忘任何在未來發現與預測不相關的資訊,同時也允許構建更加緊緻的表徵。而更新門將控制前面隱藏狀態的資訊有多少會傳遞到當前隱藏狀態,這與 LSTM 網路中的記憶單元非常相似,它可以幫助 RNN 記住長期資訊。

由於每個單元都有獨立的重置門與更新門,每個隱藏單元將學習不同尺度上的依賴關係。那些學習捕捉短期依賴關係的單元將趨向於啟用重置門,而那些捕獲長期依賴關係的單元將常常啟用更新門。

卷積與時間卷積網路

卷積神經網路,即至少在一層上使用卷積運算來代替一般的矩陣乘法運算的神經網路,一般我們認為卷積網路擅長處理「網格結構的資料」,例如影象就是二維的畫素網格。但其實時序資料同樣可以認為是在時間軸上有規律地取樣而形成的一維網格,根據 Shaojie Bai 等人的實驗結果,一般的時間卷積網路甚至比 LSTM 或 GRU 有更好的效能。

卷積的基本概念其實已經有非常多的入門教程,因此這裡只簡要說明一般的卷積運算與一維卷積。在卷積運算中,卷積核會在輸入影象上滑動以計算出對應的特徵圖。卷積層試圖將神經網路中的每一小塊進行更加深入的分析,從而得出抽象程度更高的特徵。一般來說透過卷積層處理的神經元結點矩陣會變得更深,即神經元的組織在第三個維度上會增加。

一般來說,卷積運算主要透過稀疏權重、引數共享和平移等變性等特性加強了機器學習系統。稀疏權重即卷積核大小會遠小於輸入影象的大小,這允許卷積網路儲存更少的引數和使用更少的計算而實現高效的效能。引數共享也是非常優秀的屬性,因為我們假設資料擁有區域性結構,那麼只需要在小範圍神經元中使用不同的引數,而大範圍內的神經元可共享引數。最後的平移不變性也建立在引數共享的基礎上,它可以直觀理解為若移動輸入中物件,那麼輸出中的表示也會移動同樣的量。

以下展示了簡單的一維卷積,適用於序列建模的卷積網路一般就是採用的這種架構。從一維卷積的連線方式可以清晰地瞭解權重共享的方式,圖中每個卷積層使用了一個大小為 3 的卷積核,即 k1、k2 和 k3 和 f1、f2 和 f3。下層每一個神經元只會和上層神經元部分連線,例如 h_3 只能由下層的區域性神經元 x_2、x_3 和 x_4 計算得出。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

在序列建模任務中,最下層的 x 可視為句子等輸入序列,最上層的 g 可視為輸出序列,中間的 h 即隱藏層。當然,這種一維卷積並沒有限制為只能檢視當前時間步以及之前資訊的因果卷積。越上層的神經元擁有越廣感受野,因此高層的卷積單元將有能力構建長期依賴關係。如上所示,g_3 可以觀察到輸入序列的所有資訊。

一維卷積從直觀上確實能實現序列建模,但我們經常使用的還是迴圈網路,尤其是 LSTM 或 GRU。不過在論文 An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling 中,作者表明他們所提出的時間卷積網路可作為一般的序列建模框架,且擁有非常好的效果。本文後面將介紹這種網路,並在 PTB 資料集上分別使用 RNN 與 TCN 構建語言模型。

時間卷積也是從一般的卷積運算中延伸得出,下面簡要介紹了卷積序列預測的一般架構。我們的目標是將卷積網路的最佳實踐經驗精煉為一個簡單的架構,它能便捷地處理時序建模問題。這種時間卷積網路(TCN)的顯著的特點有如下幾點,首先架構中的卷積存在因果關係,這意味著從未來到過去不會存在資訊「洩漏」。其次卷積架構可以將任意長度的序列對映到固定長度的序列。除此之外,TCN 還強調利用殘差模組和空洞卷積來構建長期依賴關係。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

TCN 論文圖 1:TCN 架構的組成元素。(a)為空洞係數 d=1, 2, 4、卷積核大小 k=3 的空洞因果卷積,感受野能覆蓋輸入序列中的所有值。(b)為 TCN 殘差塊,當殘差輸入和輸出有不同的維度,我們會新增一個 1x1 的卷積。(c)為 TCN 中的殘差連線示例,其中藍線為殘差函式中的卷積核,綠線為恆等對映。

全卷積與因果卷積

為了使用卷積運算處理時序資料,TCN 結合了一維全卷積與因果卷積兩種結構。透過使用一維全卷積網路,TCN 可以產生和輸入序列等長的輸出序列,且每一個隱藏層透過使用 Padding 可以保持和輸出層等長。而透過使用因果卷積,TCN 可以保證前面時間步的預測不會使用未來的資訊,因為時間步 t 的輸出只會根據 t-1 及之前時間步上的卷積運算得出。因此總的來說時間卷積網路簡單地組合一維全卷積和因果卷積而轉化為適合序列資料的模型。

全卷積網路最開始在論文 Fully Convolutional Networks for Semantic Segmentation(2015)中提出,它將傳統卷積神經網路最後幾個全連線層替換為卷積層。一般卷積網路會使用全連線層將特徵圖對映為固定長度的向量,且每一個元素代表一個類別。這種結構相當於將卷積抽取的高階特徵實現線性組合而最終預測類別,但它的侷限性體現在只能對整張影象或整段序列做分類處理。

因此引入全卷積的意義在於它能實現密集型的預測,即在二維卷積下對影象實現畫素級的分類,在一維卷積下對序列實現元素級的預測。此外,由於低層的卷積運算感受野較小,對於特徵的位置變化不敏感,而高層的卷積網路感受野非常大,對特徵的變化也非常敏感。因此 TCN 用一維卷積替代最後幾個全連線層有助於感受整個輸入序列的資訊,這對於構建長期記憶非常有幫助。以下展示了帶全連線層的卷積網路和全卷積網路的區別:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

如上所示,全卷積網路將預測類別機率(上)轉化為畫素級的預測(下)。

因果卷積首次是在 WaveNet(van den Oord et al。, 2016)論文中提出,從直觀上來說,它類似於將卷積運算「劈」去一半,令其只能對過去時間步的輸入進行運算。對於 TCN 所使用的一維卷積來說,因果卷積可以簡單將一般卷積的輸出移動幾個時間步而實現。在訓練過程中,所有過去時間步的卷積預測可以並行化,因為它們的輸入和標註真值都是已知的,所以這相對於迴圈網路在訓練上有非常大的優勢。因果卷積的結構將結合空洞卷積一起展示。

空洞卷積(Dilated Convolutions)

因果卷積其實還有一個問題,它需要非常多的層級數或較大的卷積核來擴寬感受野,而較大的感受野正式構建長期記憶所必須的。因此,如果我們不希望透過前面兩種會增加計算量的方法擴充套件感受野,那我們就需要使用空洞卷積(或稱擴張卷積)增加數個量級的感受野。

空洞卷積最大的特性就是擴張感受野,它不是在畫素間插入空白畫素,而是略過一些已有的畫素。當然,我們也可以理解為保持輸入不變,並向卷積核中新增一些值為零的權重,從而在計算量基本不變的情況下增加網路觀察到的影象範圍或序列長度。此外,如果我們將一般卷積運算的步幅增大,那同樣也能起到增加感受野的效果,但卷積步幅大於 1 就會起到降取樣的效果,輸出的序列長度會減小。如下展示了因果卷積結合空洞卷積的效果:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

如上所示,一維卷積的卷積核大小為 2,第一層使用的 dilation 為 1,即常規的卷積運算。而後面層級的空洞大小依次加大,常規卷積只能從右到左觀察到 5 個輸入資料,而空洞卷積可以觀察到所有 16 個輸入資料。

形式上,對於 1 維的輸入序列 x ∈ R^n 和卷積核 f : {0, 。 。 。 , k − 1} → R,空洞卷積運算 F 可以定義為:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

其中 d 為擴張係數、k 為卷積核大小,s − d · i 計算了採用上層哪一個單元。擴張係數控制了每兩個卷積核間會插入多少零值,當 d=1 時,空洞卷積就會退化為一般的卷積運算。使用較大的擴張係數允許輸出端的神經元表徵更大範圍的輸入序列,因此能有效擴張感受野。

一般在使用空洞卷積時,我們將隨著網路深度 i 的增加而指數級地增大 d,即 d=O(2^i)。這確保了卷積核在有效歷史資訊中覆蓋了所有的輸入,同樣也確保了使用深度網路能產生極其長的有效歷史資訊。

高速公路網路與殘差連線

殘差網路在計算機視覺中有非常強大的表達能力,它因為解決了深層網路的訓練問題而可以大大增加網路的層數。但要理解殘差網路與殘差連線,我們需要先理解高速公路網路(Highway Networks)。

高速公路網路受到 LSTM 的啟發,它透過門控令資訊在多個神經網路層級中可以高效流動,從而能使用傳統基於梯度的方法快速訓練深度網路。一般而言,若每一層的卷積運算可以用隱藏函式 H 表示,那麼給定該層的輸入 x 與權重矩陣 W_H,輸出可以表示為 y = H(x, W_H)。在高速公路網路中,傳入後一層的資訊不僅是當前層的計算結果,同時還包含了前面層級的計算結果。高速公路網路會使用門控機制控制每一層向後傳遞的資訊:

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

其中 H(x, W_H) 表示當前層傳統卷積運算的結果,而非線性函式 T(x, W_T) 表示轉換門,它控制了當前層的卷積運算結果對當前層輸出的貢獻大小。C(x,W_C) 表示攜帶門,它控制了當前層的輸入資訊最終不經過計算直接傳到輸出端的大小。高速公路網路一般採用 1-T(x, W_T) 代替 C(x,W_C) 而減少門控的數量,且門控透過 Sigmoid 函式實現。

由於增加了復原輸入資訊的可能性,模型會更加靈活,且當 T=1 而 C=0 時,高速公路網路就退化為了常規的卷積網路。而殘差網路與殘差連線正是這種架構的特例,如果我們令上式的 T 和 C 都等於 1,那麼它就代表了一個殘差模組,即 y = H(x, W_H) + x。因為我們要學的是卷積核的權重 W_H,因此經過簡單的變形可得 H(x, W_H) = y-x。由此可知,我們實際需要學習的函式 H 是由殘差項 y-x 而得出,這也就是我們稱之為殘差網路的原因。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

上圖為原論文中的殘差塊結構,其中 F(x) 和前面 H(x, W_H) 表示相同的過程。殘差塊的輸出結合了輸入資訊與內部卷積運算的輸出資訊,這種殘差連線或恆等對映表示深層模型至少不能低於淺層網路的準確度。

原論文展示了實踐中的兩種殘差塊,下圖左邊是一種採用堆疊兩個 3×3 的卷積運算方法,它在深層網路中表現並不是很好。右邊為一種瓶頸殘差網路,第一個 1×1 的卷積可以視為對輸入進行降維處理,因此中間的 3×3 卷積層將有更少的計算量,而後面的 1×1 卷積可以升維或恢復所有的資訊。瓶頸殘差網路有更高的計算效率,因此在非常深的網路中能大量減小計算量。

機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘

由於 TCN 的感受野取決於網路深度 n、卷積核大小 k 和空洞卷積中的擴張係數 d,因此更深的 TCN 有更強的穩定性要求。例如在預測依賴於 2^12 歷史時間步和高維輸入空間下,網路需要達到 12 層。且每一層需要多個卷積核執行特徵抽取,在 TCN 論文作者設計的模型中,它使用了殘差模組來加深卷積網路。

在 TCN 的殘差模組內,有兩層空洞卷積和 ReLU 非線性函式,且卷積核的權重都經過了權重歸一化。此外,TCN 在殘差模組內的每個空洞卷積後都添加了 Dropout 以實現正則化。

然而在標準的 ResNet 中,輸入可以直接加上殘差函式的輸出向量。而在 TCN 中,輸入與輸出有不同的維度,因此我們需要使用額外的 1×1 卷積來確保 F(x) 與 x 間對應畫素相加有相同的維度。

然而,在標準 ResNet 中,輸入直接新增到殘餘函式的輸出中,在 TCN 中(通常是 ConvNets),輸入和輸出可以有不同的寬度。為了解決輸入輸出寬度的差異,我們使用額外的 1x1 卷積來確保元素相加⊕接收相同形狀的張量。

最後,時間卷積網路即結合了一維因果卷積和空洞卷積作為標準卷積層,而每兩個這樣的卷積層與恆等對映可以封裝為一個殘差模組。這樣由殘差模組堆疊起一個深度網路,並在最後幾層使用卷積層代替全連線層而構建完整的全卷積網路。

注:

由於原文字數超過了知乎的限制,所以

“實現部分”

請移步原文閱讀,感謝理解。原文連結:機器之心GitHub專案:從迴圈到卷積,探索序列建模的奧秘。