一提起 RNN,我們最容易想到的實現就是 LSTM + attention。LSTM 作為經典的網絡結構可謂是老當益壯,而另一方面注意力機制過于常見,我們甚至會覺得它是「理所當然的」。但其實注意力機制其實并不是唯一一種網絡增強的方式。這篇 Distill.pub 博客的文章就帶我們重溫了包括注意力在內的多種網絡增強方式,它們側重的方向不一樣,也就方便研究/開發人員們按照自己的實際需求進行選取。
循環神經網絡(RNN)是深度學習技術中十分重要的一類模型,它讓神經網絡能夠處理文本、音頻和視頻等序列數據。人們可以用循環神經網絡將一個序列歸結為一個高級的理解模式,從而對序列進行標注,甚至從頭開始生成一個新的序列。
基本的 RNN 設計過程需要對棘手的長序列進行處理,但是一種特殊的RNN 變體——LSTM(long short-term memory,長短期記憶網絡)可以在這種情況下很好地工作。人們發現這些模型十分強大,能夠在包括機器翻譯、語音識別和圖像理解(看圖說話)等許多任務中取得非常好的效果。因此,在過去的幾年里,循環神經網絡已經被廣泛使用。
隨著人們對循環神經網絡的研究越來越深入,我們已經看到越來越多的人試圖用一些新的特性來增強循環神經網絡。有四個方向的改進特別令人激動:
這些技術中,每一項技術都對神經網絡有很大的提升。然而,真正炫酷的是,這些技術還能結合在一起使用,而且現有的這些技術似乎都只是廣闊的研究空間中的一葉扁舟。此外,它們都依賴于同樣的底層技術——注意力機制,從而發揮作用。
神經圖靈機
神經圖靈機[2] 將 RNN 與外部存儲單元相結合。由于向量是自然語言在神經網絡中的表現形式,所以存儲單元中的內容是一組向量:
但是對神經圖靈機的讀寫的工作方式是怎樣的呢?真正的挑戰是,我們需要讓它們可微。特別是,我們需要讓它們對于我們讀和寫的位置可微,從而讓我們學會在哪里進行讀寫操作的。由于存儲地址在根本上是離散的,要讓它們可微是十分困難的。為此,神經圖靈機采取了一種很聰明的解決方案:在每一步操作中,它們會在存儲單元的所有位置進行讀寫,只是程度不同而已。
舉例而言,讓我們重點關注讀操作。RNN 并沒有指定一個特定的讀取位置,而是輸出了一個「注意力分布」,它描述了我們對于不同的存儲位置關注程度的分布情況。由此得到的讀操作的結果就是一個加權和。
類似地,我們也會以不同程度在存儲單元中的各個位置進行寫操作。我們再次用一個注意力分布描述我們在每個位置寫入了多少內容。我們通過使存儲單元中每個位置的新值成為舊存儲內容和新寫入的值的凸組合來做到這一點,而舊的存儲內容和新值之間的位置取決于注意力權重。
但是,神經圖靈機是如何確定應該將注意力集中在存儲單元的哪些位置上呢?實際上,它們采用了兩種不同方法的組合:基于內容的注意力機制和基于位置的注意力機制。基于內容的注意力機制使神經圖靈機可以在他們的存儲器中進行搜索并重點關注于他們所尋找的目標相匹配的位置,而基于位置的注意力機制則使存儲單元中注意力的相對運動成為了可能,使神經圖靈機能夠循環。
這種讀寫能力使得神經圖靈機能夠執行許多簡單的算法,而不僅限于神經網絡范疇。例如,它們可以學習在存儲單元中存放一個長的序列,然后對其反復進行循環操作。當它們這樣做的時候,我們可以看到他們在哪些位置執行了讀寫操作,以便更好地理解他們在做什么:
你可以在[3]中查看更多的實驗結果。上圖是基于重復的復制實驗得出的。
它們還可以學會模仿查表法,甚至學著對數字進行排序(盡管采取了一些投機取巧的方法)!另一方面,有時他們面對一些很基礎的工作也會無能為力,比如對數字進行加法或乘法運算。
自從最原始的神經圖靈機論文發表后,相繼涌現了一大批在相關領域取得激動人心的研究進展的論文。神經 GPU[4] 解決了神經圖靈機無法對數字進行加法和乘法運算的問。
Zaremba 和 Sutskever 等人[5]使用強化學習代替了最原始的神經圖靈機中使用的可微的讀寫技術來訓練神經機器翻譯。神經隨機存取存儲器(NRAM)是基于指針工作的。目前,一些論文已經對棧和隊列這種可微的數據結構進行了探究[7,8]。而記憶網絡[9,10](memory networks)則是另一種解決類似問題的方法。
從某種客觀意義上來講,這些模型可以執行的許多任務(例如學會如何對數字做加法),并不是十分困難。對于傳統的編程技術說,這些任務可以說是小菜一碟。但是神經網絡可以處理許多其他的問題,而目前像神經圖靈機這樣的模型的能力似乎仍然收到了很大限制,沒有被完全開發出來。
代碼
這些模型有許多開源的實現版本。神經圖靈機的開源實現有 Taehoon Kim(Tensorflow 版,https://github.com/carpedm20/NTM-tensorflow )、Shanwn(Theano 版,https://github.com/shawntan/neural-turing-machines )、Fumin(Go 版,https://github.com/fumin/ntm )、Kai Sheng(Torch 版,https://github.com/kaishengtai/torch-ntm )、Snip(Lasagne 版,https://github.com/snipsco/ntm-lasagne )等人的版本。神經 GPU 代碼是開源的,并已經被 TensorFlow 的模型庫囊括了進去(https://github.com/tensorflow/models/tree/master/neural_gpu )。記憶網絡的開源實現包含Facebook(Torch/Matlab 版,https://github.com/facebook/MemNN )、YerevaNN(Theano 版,https://github.com/YerevaNN/Dynamic-memory-networks-in-Theano )、Taehoon Kim(TensorFlow 版,https://github.com/carpedm20/MemN2N-tensorflow )等人的版本。
注意力機制
當我們翻譯一個句子時,我們會特別注意當前翻譯的單詞。當我們轉錄一段錄音時,我們會仔細聽我們正努力寫下的章節。如果你要我描述我所坐的房間,我會在描述的時候看看周圍的物體。
神經網絡使用注意力機制實現同樣的行為,專注于整個環境中所獲的的信息的一部分。例如,RNN 可以處理另一個 RNN 的輸出。在每一個時間步上,帶注意力機制的 RNN 都會關注另一個 RNN 的不同位置上的內容。
我們希望注意力機制是可微的,這樣我們就可以學到重點關注什么位置上的內容。為了做到這一點,我們獎使用和神經圖靈機一樣的技術:我們關注所有的位置,只是關注的程度不同罷了。
注意力分布通常是由基于內容的注意力機制生成的。我們用來操作的RNN 會生成一個搜索詞描述它想要關注的位置。每一項都會與搜索詞進行點乘從而產生一個得分,該得分將描述其與搜索詞的匹配程度。這個得分將作為輸入送給Softmax 函數,用來創建注意力分布。
在RNN 之間應用注意力機制的一個場景是機器翻譯[11]。一個傳統的序列到序列(Seq2Seq)的模型必須將整個輸入歸結為一個單一的向量,然后將其反向擴展得到翻譯結果。注意力機制通過使RNN 能夠處理輸入來傳遞它所看到的每一個單詞信息,然后在生成輸出的RNN 中將注意力集中在相關的單詞上。
圖片來源:Bahdanau 等人于2014 年發表的論文中的圖3(https://arxiv.org/pdf/1409.0473.pdf )
這種 RNN 之間的注意力機制已經有許多其它的應用場景。它能夠在語音識別[12]中被使用,使一個 RNN 能夠處理音頻信息,然后讓另一個 RNN 能夠瀏覽它,在它生成音頻相應的文字時將注意力放在相關的部分上。
圖片來源:Chan 等人于2015 年發表的論文(https://arxiv.org/pdf/1508.01211.pdf)。
這種注意力機制其它的應用還包括文本解析[13],這時注意力機制讓模型能夠在生成解析樹時對單詞進行掃描。而在對話建模[14]任務中,注意力機制使模型能在生成回應文字時,重點關注對話前面相關求的內容。
注意力機制還可以用在卷積神經網絡和循環神經網絡之間的接口上。這里的注意力機制使 RNN 能夠在每一步關注圖像上的不同位置。這種注意力機制的一個流行的應用場景是「看圖說話」。首先,一個卷積網絡會對圖片進行處理從而抽取高級特征;接著會運行一個 RNN 生成對圖像的描述。當它生成描述中的每個單詞時,RNN 會關注卷積神經網絡對圖像相關部分的解釋。我們可以用下圖顯示地可視化這個過程:
圖片來源:(arXiv preprint arXiv:1502.03044, Vol 2(3), pp. 5. CoRR.)
更廣泛地說,當我們想要與一個在輸出中有重復結構的神經網絡對接時,可以使用注意力接口。
人們發現注意力接口是一種極具通用價值并且十分強大的技術,并且正在被越來越廣泛地使用。
自適應計算時間
標準的 RNN 在每個時間步上執行相同數量的計算。這似乎并不符合直覺。當然,我們要處理的問題變得更加復雜時,人們是否應該再多考慮考慮呢?此外,標準 RNN 還將其操作長度為 n 的序列的時間復雜度限制為 O(n)。
自適應計算時間[15]是一種讓 RNN 能夠在每一步之行不同數量的計算的方法。大體的思路很簡單:它讓RNN 能在每個時間步上進行多步計算。
為了讓網絡學習需要計算多少步,我們希望步驟的數量可微。我們用我們曾經使用過的技術來實現這一點:我們并不運行離散數量的步驟,而是對運行的步數使用了一個注意力分布。它的輸出是每個步驟的輸出的加權組合。
上圖還忽略了一些更多的細節。下圖是在一個時間步上包含三個計算步驟的完整示意圖:
此圖描述的計算過程有些復雜,所以讓我們一步步地分析它。在高層,我們仍然運行RNN 并輸出一個狀態的加權組合:
每一個計算步驟的權重都由一個「緩沖神經元」決定。它是一種能夠觀察RNN 的狀態并給出一個緩沖權重的sigmoid 神經元,我們可以認為它是我們應該在這一步停下來的概率。
我們對于緩沖權重的總預算上限為1,接著我們根據下圖最上面一行的計算流程進行計算(從1 開始,每一步減去相應的值)。當它變得小于epsilon 時,我們就停止計算。
當我們停下來時,可能還會有一些在緩沖預算之外還沒有計算完的部分,這是因為我們在其小于 epsilon 時就會停止計算。我們該如何處理這種情況呢?從技術上講,它被賦予了未來可以繼續計算的步驟,而我們現在并不想計算它,因此我們將現在的狀態定義為最后一步。
當我們訓練自適應計算時間模型時,可以在損失函數中添加一項「思考成本」(ponder cost),用來懲罰模型的累積計算時間。這一項越大,就會更加因為降低計算時間而降低性能,達到折中的目的。
自適應計算時間是一種非常新的想法,但是我們相信它和類似的思想都是非常重要的。
代碼
目前唯一的「自適應計算時間」模型的開源代碼似乎是Mark Neumann的版本(TensorFlow 版,https://github.com/DeNeutoy/act-tensorflow)。
神經網絡編程器
神經網絡在許多任務上的表現都非常出色,但它們又是也很難做到一些基本的事情。比如算術對于神經網絡就很困難,而這對于普通的計算方法是輕而易舉的。如果有一種方法可以將神經網絡與普通的編程方法融合在一起,就會取得最大的雙贏局面。
神經網絡編程器[16]是一種解決該問題的方法。它會學著創建程序來解決這個問題。事實上,它能在不需要正確的程序實例范本的情況下生成這樣的程序。它會發現要想完成某種任務,做為手段,需要如何生產出程序。
論文中實際的模型通過生成類 SQL 程序查詢表格來回答這個問題。然而,這種環境下的大量細節讓它變得有些復雜。所以我們不妨從想象一個稍微簡單一點的模型開始,它給出了一個算術表達式,并生成了一個模型來評估它。
生成的程序是一個操作序列。每個操作都被定義為對過去操作的輸出進行操作。因此,一個操作可能類似于「將兩步前的操作的輸出和一步前的操作的輸出相加」。它更像是一個Unix 管道,而不是一個擁有被賦值并被讀取的變量的程序。
該程序由控制器RNN 一次生成一個操作。在每個步驟中,控制器RNN都會輸出下一個操作應該是什么的概率分布。例如,這個概率可以用來模擬:我們可能非常確定我們想要在第一個時間步上執行加法,然后在決定我們是否需要在第二步執行乘法或除法的時候會很艱難,等等…
現在,最終得出的操作的分布可以被我們評估。我們并不是在每一步運行一個操作,而是采用了普遍使用的注意力技巧,同時運行所有的操作,再根據我們執行這些操作的概率作為權重對所有的輸出一起取平均。
只要我們能夠通過這些操作定義導數,程序的輸出在概率上就是可微的。接著,我們可以定義一個損失函數,訓練神經網絡生成給出正確答案的程序。這樣一來,神經網絡編程器就學會了在沒有正確程序范例的情況下生成程序。唯一的監督信息就是程序應該產生的返回值。
這就是神經網絡編程器的核心思想,但是論文中的版本回答了關于表的問題,而不是關于算術表達式。下面我們還將給出一些實用的小技巧:
多種數據類型:神經網絡編程器中的許多操作都會處理除標量值之外的其他類型的數據。一些操作輸出選中的表的列或者選中的單元格。只有相同類型的輸出才能被合并到一起。
參考輸入:神經網絡編程器需要回答類似于「有多少個人口超過1 百萬人的城市?」為了使回答這種問題更加容易,一些操作允許網絡參考他們正在回答的問題中的常量,或者列的名字。這種參考是由于注意力機制發生的,就像指針網絡[17]。
神經網絡編程器并不是讓神經網絡生成程序的唯一途徑。另一種好方法是神經網絡編程器-解釋器[18],他可以完成很多有趣的任務,但是需要正以確程序作為監督信息。
我們認為,這種彌合傳統編程和神經網絡之間差距的一般空間是非常重要的。雖然神經網絡編程器顯然不是最終的解決方案,我單們認為有很多重要的經驗教訓可以從中學到。
代碼
最新版本的用于問答的神經網絡編程器(https://openreview.net/pdf?id=ry2YOrcge )已經被其作者開源,并且可以作為 TensorFlow 模型獲取(https://github.com/tensorflow/models/tree/master/neural_programmer )。而神經網絡編程器-解釋器也有由Ken Morishita編寫的Keras 版本(https://github.com/mokemokechicken/keras_npi )。
整體把握
從某種意義上說,一個人類拿著一張紙,比沒有紙的人聰明得多。一個有數學符號的人可以解決他們不能解決的問題。使用電腦使我們能夠做出不可思議的壯舉,否則它們將遠遠超出我們的能力范圍。
一般來說,很多有趣的智力形式似乎是人類的創造性啟發式直覺和一些更加直觀具體的媒介之間的相互作用,如語言或方程式。有時,媒介是客觀存在的東西,為我們儲存信息,防止我們犯錯誤,或者執行繁瑣的計算任務。在其他情況下,媒介是我們在腦海中操縱的一個模型。無論如何,這對于智能來說都是至關重要的。
最近機器學習的結果已經開始有了這種味道,將神經網絡的直覺和其他東西結合起來。其中一種方法就是人們所說的「啟發式搜索」。例如,AlphaGo [19]有一個關于圍棋如何工作的模型,并且探索了在神經網絡直覺指導下如何玩這個游戲的模型。類似地,DeepMath [20]利用神經網絡表征操作數學表達式的直覺。我們在本文中談到的「增強的RNN」是另一種方法,將RNN 連接到專門設計的媒介上,以提高它們的泛化能力。
與媒介的相互作用自然包括「采取一系列行動、進行觀察、再采取進一步的行動」。在這里,我們面臨著一個巨大的挑戰:我們如何學習應該采取怎樣的行動?這聽起來是個強化學習問題,我們當然可以采用這樣的做法。但是,強化學習技術實際上是解決該問題最復雜的版本,而且這種解決方案很難使用。注意力機制的精妙之處在于,它使我們能夠更容易地通過對部分位置以不同程度執行所有的動作來解決這個問題。這是因為我們可以設計像神經圖靈機這樣的存儲結構使我們能進行細微的操作,并且使該問題可微。強化學習讓我們采取一條單一的解決路徑,并且試著從中學到知識。注意力機制則在每一個選擇的交叉口采取了各個方向的動作,并最終將各條路徑的結果合并在一起。
注意力機制的一個主要的缺點是,我們必須在每一步上采取「動作」。由于我們會進行進行增加神經圖靈機中的存儲單元等操作,這會導致計算開銷直線上升。可以想到的解決方法就是讓你的注意力模型變得稀疏一些,這樣以來你就只需要對一部分存儲單元進行操作。然而,這仍然是具有挑戰性的,因為你可能想要讓你的注意力模型依賴于存儲單元的內容,而這樣做會令你不得不查看每一個存儲單元。我們已經觀察到,目前有一些初步的工作在常識解決這個問題,例如[21] ,但是似乎還有許多工作有待探索。如果我們真的能做出這樣的在次線性時間復雜度內的注意力機制的工作,這種模型會變得非常強大!
增強的循環神經網絡和注意力機制的底層技術是如此令人激動!我們期待著這個領域有更多的新技術涌現出來!
-
神經網絡
+關注
關注
42文章
4814瀏覽量
103552 -
機器學習
+關注
關注
66文章
8501瀏覽量
134576
原文標題:循環神經網絡的增強方法:注意力機制以及更多
文章出處:【微信號:worldofai,微信公眾號:worldofai】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
評論