遞迴神經網路教程請簽收!

人工智慧頻道發表於2018-11-20

使用遞迴神經網路撰寫專利摘要

當我第一次嘗試研究遞迴神經網路時,我犯了一個錯誤,我試圖先學習LSTM和GRU之類的理論。在研究線性代數方程的幾天之後,我在Python的深度學習中偶然發現了下面這段話():

總之,你不需要了解LSTM單元的所有具體架構;作為一個人,理解它不應該是你的工作。請記住LSTM單元的作用:允許過去的資訊在以後重新注入。

遞迴神經網路教程請簽收!


這是深度學習專家Keras(Francois Chollet的作者),他告訴我,我不需要了解基礎層面的所有內容!我意識到我的錯誤是從理論開始的底層開始的,而不僅僅是試圖構建一個遞迴的神經網路。

此後不久,我改變了策略,決定嘗試最有效的學習資料科學技術的方法:找到問題並解決它!

透過這種方式,我能夠弄清楚在此過程中我需要知道什麼,當我重新研究概念時,我就有了一個框架,我可以適應每個想法。在這種心態中,我決定不再擔心細節,完成一個遞迴的神經網路專案。

本文將介紹如何在Keras中構建和使用遞迴神經網路來編寫專利摘要。這篇文章很清楚這個理論,但是當你完成這個專案時,你會發現你在過程中會學到你需要知道的東西。最終結果是,你可以構建一個有用的應用程式,並弄清楚自然語言處理的深度學習方法是如何工作的。

(完整程式碼在GitHub上作為一系列Jupyter筆記本提供.com/WillKoehrsen/recurrent-neural-networks。我還提供了所有預先訓練好的模型 .com /WillKoehrsen/recurrent-neural-networks/tree/master/models,因此你不必自己訓練幾個小時!要儘快開始並研究模型,請參閱快速開始遞迴神經網路(.com/WillKoehrsen/recurrent-neural-networks/blob/master/notebooks/Quick%20Start%20to%20Recurrent%20Neural%20Networks.ipynb,有關深入解釋,請參閱深入到遞迴神經網路.com/WillKoehrsen/recurrent-neural-networks/blob/master/notebooks/Deep%20Dive%20into%20Recurrent%20Neural%20Networks.ipynb)

遞迴神經網路

在開始實施之前,至少理解一些基礎知識是有幫助的。在高層次上,遞迴神經網路(RNN)處理序列——無論是每日股票價格、句子還是感測器測量——一次只處理一個元素,同時保留之前在序列中所存在的記憶(稱為狀態)。

遞迴意味著當前時間步的輸出成為下一個時間步的輸入。在序列的每個元素上,模型不僅考慮當前輸入,還考慮它對前面元素的記憶。

遞迴神經網路教程請簽收!


RNN概述(來源:)

該記憶網路允許網路學習序列中的長期依賴性,這意味著它可以在進行預測時考慮整個上下文,無論是句子中的下一個單詞,情感分類還是下一個溫度測量。RNN旨在模仿人類處理序列的方式:我們在形成響應是應該考慮整個句子,而不是單詞本身。例如,請考慮以下句子:

"演唱會在樂隊熱身前的15分鐘裡很無聊,但隨後就非常令人興奮。"

如果機器學習模型只考慮單獨的單詞,可能會得出結論,這句話是否定的。相比之下,RNN應該能夠看到單詞"但"和"非常令人興奮"並且意識到句子從否定變為了肯定,因為它檢視了整個序列。讀取整個序列為我們提供了處理其含義的背景,這是一種在遞迴神經網路中編碼的概念。

RNN的核心是由記憶網路單元構成的層。目前最流行的單元是長短期記憶網路(LSTM:),它可以保持單元狀態以及進位,以確保在處理序列時訊號(梯度形式的資訊:)不會丟失。在每個時間步中,LSTM都會考慮當前單詞、進位和單元狀態。

遞迴神經網路教程請簽收!

LSTM(長短期記憶網路)

LSTM有3個不同的門和權重向量:有一個"遺忘"門用於丟棄無關資訊;一個"輸入"門用於處理當前輸入,以及用於在每個時間步產生預測的"輸出"門。然而,正如Chollet指出的那樣,嘗試為單元中的每個元素指定特定含義是徒勞的。

每個單元元素的特性最終由訓練期間學習的引數(權重)決定。隨意標記每個單元部分,但這並不是有效使用的必要條件!回想一下,遞迴神經網路對序列學習的好處是它維持整個序列的記憶,防止先前資訊丟失。(https://machinelearningmastery.com/sequence-prediction-problems-learning-lstm-recurrent-neural-networks/)

問題制定

我們可以透過多種方式制定訓練RNN編寫文字的任務,在本文示例中是專利摘要。但是,我們會選擇將其作為多對一序列對映器進行訓練。也就是說,我們輸入一系列單詞並訓練模型以預測下一個單詞。在傳遞到LSTM層之前,將使用嵌入矩陣(預先訓練的或可訓練的)將單詞對映到整數然後對映到向量。

當我們去寫一個新的專利時,我們傳入一個單詞的起始序列,對下一個單詞進行預測,更新輸入序列,進行另一個預測,將單詞新增到序列中,然後繼續生成任意數量的單詞。

該方法的步驟概述如下:

  1. 將字串列表中的摘要轉換為整數列表(序列)

  2. 從序列中建立特性和標籤

  3. 使用嵌入層,LSTM和密集層構建LSTM模型

  4. 載入預先訓練好的嵌入

  5. 訓練模型以按順序預測下一步工作

  6. 透過傳遞起始序列進行預測

請記住,這只是問題的一個表述:我們還可以使用字元級模型或對序列中的每個單詞進行預測。與機器學習中的許多概念一樣,沒有一個正確的答案,但這種方法在實踐中很有效。

資料準備

即使具有神經網路強大的表示能力,獲得高質量、乾淨的資料集也是至關重要的。該專案的原始資料來自USPTO PatentsView(http://www.patentsview.org/querydev/),你可以在其中搜尋有關在美國申請的任何專利的資訊。我搜尋了"神經網路"這個術語並下載了最終的專利摘要——總共3500個。我發現最好是在狹窄的領域上進行訓練,但可以嘗試使用不同的專利。

遞迴神經網路教程請簽收!


專利摘要資料

我們將從專利摘要作為字串列表開始。我們模型的主要資料準備步驟是:

  1. 刪除標點符號並將字串拆分為單個單詞列表

  2. 將單個單詞轉換為整數

這兩個步驟都可以使用Keras ()、Tokenizer()類完成。 預設情況下,這將刪除所有標點符號、小寫單詞,然後將單詞轉換為整數序列。Tokenizer首先適合於字串列表,然後將此列表轉換為整數列表列表。如下所示:

遞迴神經網路教程請簽收!


第一個單元格的輸出顯示原始摘要,第二個單元格的輸出顯示標記化序列。每個摘要現在都表示為整數。

我們可以使用經過訓練的tokenizer的idx_word屬性來確定每個整數的含義:

遞迴神經網路教程請簽收!


如果你仔細觀察,你會注意到Tokenizer已經刪除了所有標點並小寫化了所有單詞。如果我們使用這些設定,那麼神經網路將無法學習正確的英語!我們可以透過將過濾器更改為Tokenizer來調整這一點,以避免刪除標點符號。

遞迴神經網路教程請簽收!


請參閱筆記本中的不同實現,但是,當我們使用預先訓練的嵌入時,我們必須刪除大寫,因為嵌入中沒有小寫字母。在訓練我們自己的嵌入時,我們不必擔心這個問題,因為模型將學習不同的大小寫表示形式。

特性和標籤

上一步將所有摘要轉換為整數序列。下一步是建立一個用於訓練網路的監督機器學習問題。你可以透過多種方式為文字生成設定遞迴神經網路任務,但我們將使用以下方法:

為網路提供一系列單詞並訓練它以預測下一個單詞。

單詞數留作引數;我們將使用50表示這裡顯示的示例,這意味著我們為網路提供50個單詞,並對其進行訓練以預測第51個單詞。訓練網路的其他方法是讓它預測序列中每個點的下一個詞——對每個輸入詞進行預測,而不是對整個序列進行一次預測——或者使用單個字元訓練模型。這裡使用的實現不一定是最優的(沒有公認的最佳解決方案)但它運作良好!

建立特性和標籤相對簡單,對於每個摘要(表示為整數),我們建立多組特性和標籤。我們使用前50個單詞作為特性,第51個單詞作為標籤,然後使用2-51個單詞作為特性並預測第52個單詞等等。這為我們提供了更多的訓練資料,這是有益的,因為網路的效能與它在訓練期間看到的資料量成比例()。

建立功能和標籤的實現如下:

遞迴神經網路教程請簽收!


這些特性最終以shape(296866,50)結束,這意味著我們有近300,000個序列,每個序列有50個標籤。在遞迴神經網路的語言中,每個序列具有50個時間步長,每個具有1個特性。

我們可以將標籤保留為整數,但是當標籤是獨熱編碼時,神經網路能夠最有效地訓練。我們可以使用以下內容快速對numpy的標籤進行獨熱編碼:

遞迴神經網路教程請簽收!


要查詢與label_array中的行對應的單詞,我們使用:

遞迴神經網路教程請簽收!


在將所有特性和標籤格式化後,我們希望將它們分成訓練和驗證集(有關詳細資訊,請參閱筆記本)。這裡的一個重點是要同時對特性和標籤進行調整,這樣相同的摘要就不會全部集中在一起。

建立一個遞迴神經網路

Keras是一個令人難以置信的庫:它允許我們用幾行可理解的Python程式碼構建最先進的模型。雖然其他神經網路庫可能更快或允許更大的靈活性(),但在開發時間和易用性方面,沒有什麼能夠超越Keras。

下面是一個簡單LSTM的程式碼,其解釋如下:

遞迴神經網路教程請簽收!


遞迴神經網路教程請簽收!


遞迴神經網路教程請簽收!


我們正在使用Keras序列API,這意味著我們一次構建一個網路層。層次如下:

  • 將每個輸入字對映到100維向量的嵌入。嵌入可以使用我們在權重引數中提供的預訓練權重。如果我們不想更新嵌入,可以將trainable設定為False。

  • 一個遮蔽層,用於遮蔽任何沒有經過預訓練嵌入的單詞,這些單詞將被表示為零。在訓練嵌入時不應使用此層。

  • 網路的核心:一層LSTM單元,具有防止過度擬合的特性()。由於我們只使用一個LSTM層,因此不返回序列,如果使用兩個或更多層,請確保返回序列。

  • 具有relu啟用的完全連線的密集層。這為網路增加了額外的表示能力。

  • Dropout層可防止過度擬合訓練資料。

  • 密集的全連線輸出層。這使用softmax啟用產生詞彙中每個單詞的機率。

該模型使用Adam最佳化器(隨機梯度下降的一種變體)編譯,並使用categorical_crossentropy損失進行訓練。在訓練期間,網路將嘗試透過調整可訓練引數(權重)來最小化損失。與往常一樣,引數的梯度使用反向傳播計算並使用最佳化器進行更新()。由於我們使用的是Keras,因此我們不必擔心在幕後如何發生這種情況(),只需要正確設定網路即可。

遞迴神經網路教程請簽收!

LSTM網路佈局

在不更新嵌入的情況下,在網路中需要訓練的引數更少。LSTM層的輸入是(None,50,100),這意味著對於每個批次(第一個維度),每個序列具有50個時間步長(單詞),每個序列在嵌入後具有100個特性。LSTM圖層的輸入始終具有(batch_size,timesteps,features)形狀。

構建此網路的方法有很多種,筆記本中還包含其他幾種方法(.com/WillKoehrsen/recurrent-neural-networks/blob/master/notebooks/Deep%20Dive%20into%20Recurrent%20Neural%20Networks.ipynb)。例如,我們可以使用兩個堆疊在一起的LSTM層,一個雙向LSTM層,用於處理來自兩個方向的序列,或更多的密集層。

預訓練嵌入

一旦建立了網路,我們仍然必須為其提供預先訓練好的嵌入詞。你可以在不同的語料庫上線上搜尋大量嵌入()。我們將使用的那些可以從史丹佛獲得的,並且有100,200或300維度(我們將堅持100)。這些嵌入來自GloVe()演算法,並在維基百科上進行了訓練。

即使預先訓練好的嵌入包含400,000個單詞,但我們的詞彙中也會包含一些單詞。當我們用嵌入來表示這些單詞時,它們將具有全零的100-d向量。可以透過訓練我們自己的嵌入或透過將嵌入層的可訓練引數設定為True(並移除遮蔽層)來解決此問題。

我們可以快速載入來自磁碟的預訓練嵌入,並使用以下程式碼製作嵌入矩陣:

遞迴神經網路教程請簽收!


遞迴神經網路教程請簽收!


這樣做是為詞彙中的每個單詞分配一個100維向量。如果單詞沒有預先訓練的嵌入,則該向量將全為零。

遞迴神經網路教程請簽收!


為了探索嵌入,我們可以使用餘弦相似性來找到嵌入空間中最接近給定查詢字的單詞:

遞迴神經網路教程請簽收!


嵌入是學習的(),這意味著表示只適用於一個任務。當使用預先訓練的嵌入時,我們希望嵌入式學習的任務足夠接近我們的任務,因此嵌入是有意義的。如果這些嵌入是透過推文進行訓練的,我們可能不會期望它們能夠很好地工作,但由於它們接受過維基百科資料的訓練,因此它們通常適用於一系列語言處理任務。

如果你有大量資料和時間,通常最好為特定任務學習自己的嵌入。在筆記本中我採用了兩種方法,學習嵌入的效能稍好一些。

訓練模型

透過準備訓練和驗證資料,構建網路以及載入嵌入,我們幾乎可以為我們的模型學習如何編寫專利摘要。但是,在訓練神經網路時要採取的最好步驟是以Keras回撥的形式使用ModelCheckpoint和EarlyStopping():

  • 模型檢查點:將最佳模型(透過驗證丟失測量)儲存在磁碟上以使用最佳模型

  • 早期停止:當驗證損失不再減少時停止訓練

使用早期停止意味著我們不會過度使用訓練資料並浪費時間去訓練那些不會提高效能的額外時期。模型檢查點意味著我們可以訪問最佳模型,如果我們的訓練在1000個時期中斷,我們將不會失去所有進展!

遞迴神經網路教程請簽收!


然後可以使用以下程式碼訓練模型:

遞迴神經網路教程請簽收!


在亞馬遜p2.xlarge例項上(),這隻花了1個多小時就完成了。訓練完成後,我們可以載入最佳儲存模型並評估驗證資料的最終時間。

遞迴神經網路教程請簽收!


總體而言,使用預先訓練的單詞嵌入的模型實現了23.9%的驗證準確性。作為一個人,我發現很難預測這些摘要中的下一個詞! 對最常用詞("the")的猜測產生的準確率約為8%。筆記本中所模式的指標如下所示:

遞迴神經網路教程請簽收!


最好的模型使用預先訓練的嵌入和如上所示的相同架構。我鼓勵任何人嘗試使用不同模式的訓練!

專利摘要生成

當然,雖然高指標很好,但重要的是網路是否可以產生合理的專利摘要。使用最佳模型,我們可以探索模型生成能力。如果你想在自己的硬體上執行它,你可以在這裡找到筆記本(.com/WillKoehrsen/recurrent-neural-networks/blob/master/notebooks/Exploring%20Model%20Results.ipynb),預先訓練好的模型在GitHub上(.com/WillKoehrsen/recurrent-neural-networks/tree/master/models)。

為了產生輸出,我們使用從專利摘要中選擇的隨機序列為網路播種,使其預測下一個單詞,將預測新增到序列中,並繼續對我們想要的許多單詞進行預測。一些結果如下所示:

遞迴神經網路教程請簽收!


輸出的一個重要引數是預測的多樣性。我們不是使用具有最高機率的預測詞,而是將多樣性注入到預測中,然後選擇具有與更多樣化預測成比例的機率的下一個詞。多樣性過高,生成的輸出就會顯得隨機,而多樣性太低,網路就會進入遞迴的輸出迴圈。

遞迴神經網路教程請簽收!


輸出也不錯!有些時候很難確定哪個是計算機生成的,哪個來自機器。部分原因在於專利摘要的性質,大多數時候,這聽起來並不像是人類寫的。

網路的另一個用途是用我們自己的起始序列播種它。我們可以使用我們想要的任何文字,並檢視網路所在的位置:

遞迴神經網路教程請簽收!


同樣,結果並不完全可信,但它們確實類似於英語。

人或機器?

作為遞迴神經網路的最終測試,我建立了一個遊戲來猜測是模型還是人類產生了輸出。這是第一個示例,其中兩個選項來自計算機,一個來自人類:

遞迴神經網路教程請簽收!


你怎麼猜?答案是第二個是一個人寫的實際摘要(嗯,這實際上是抽象的。我不確定這些摘要是由人寫的)。這是另一個:

遞迴神經網路教程請簽收!


這一次,第三個是人寫的。

我們可以使用其他步驟來解釋模型,例如找出不同的輸入序列會啟用哪些神經元。我們還可以檢視學習到的嵌入(或使用Projector工具將其視覺化)。

結論

重要的是要認識到遞迴神經網路沒有語言理解的概念。它實際上是一種非常複雜的模式識別機器。儘管如此,與馬爾可夫鏈或頻率分析等方法不同,RNN基於序列中元素的排序進行預測。從哲學角度講,你可以說人類只是極端的模式識別機器,因此遞迴神經網路只是像人類機器一樣運作。

遞迴神經網路的使用遠遠超出了文字生成、機器翻譯、影像字幕和作者身份識別。雖然我們在這裡介紹的這個應用程式不會取代任何人類,但可以想象,透過更多的訓練資料和更大的模型,神經網路將能夠合成新的、合理的專利摘要。

遞迴神經網路教程請簽收!

雙向LSTM單元

人們很容易陷入細節或複雜技術背後的理論,但學習資料科學工具的一種更有效的方法是深入研究並構建應用程式。一旦你知道一種技術的能力以及它在實踐中的運作方式,你就可以回過頭來再研究這個理論。我們大多數人不會設計神經網路,但學習如何有效地使用它們是值得的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31545819/viewspace-2220767/,如需轉載,請註明出處,否則將追究法律責任。

相關文章