維基百科對自動摘要生成的定義是, “使用計算機程序對一段文本進行處理, 生成一段長度被壓縮的摘要, 并且這個摘要能保留原始文本的大部分重要信息”. 摘要生成算法主要分為抽取型(Extraction-based)和概括型(Abstraction-based)兩類. 傳統(tǒng)的摘要生成系統(tǒng)大部分都是抽取型的, 這類方法從給定的文章中, 抽取關鍵的句子或者短語, 并重新拼接成一小段摘要, 而不對原本的內容做創(chuàng)造性的修改. 這類抽取型算法工程上已經有很多開源的解決辦法了, 例如Github上的項目sumy, pytextrank, textteaser等. 本文重點講概括型摘要生成系統(tǒng)的算法思想和tensorflow實戰(zhàn), 算法思想源于A Neural Attention Model for Abstractive Sentence Summarization這篇論文. 本文希望幫助讀者詳細的解析算法的原理, 再結合github上相關的開源項目textsum講解工程上的實際應用.本文由PPmoney大數(shù)據(jù)算法團隊撰寫,PPmoney是國內領先的互聯(lián)網(wǎng)金融公司,旗下PPmoney理財總交易額超過700億元。此外,若對TensorFlow的使用技巧和方法感興趣,歡迎閱讀本團隊負責人黃文堅所著的《TensorFlow實戰(zhàn)》。
下面對A Neural Attention Model for Abstractive Sentence Summarization這篇文章, 的算法原理進行講解. 我們將這個模型簡稱為NAM. 主要分為模型訓練(train)和生成摘要(decode)兩部分講解.
NAM這個模型是純數(shù)據(jù)驅動, 我們喂給它的訓練集數(shù)據(jù)是由一系列{正文: 摘要}對組成. 假設正文是
對于給定的數(shù)據(jù), 我們希望給定
下面我們舉一個例子來說明訓練的過程:
我們希望根據(jù), 當前局部摘要序列<s>來補全.
我們感興趣的分布
通過包含編碼器并且聯(lián)合訓練這兩個組塊, 我們根據(jù)當前
模型整體的網(wǎng)絡結構圖(具有一個額外的編碼器單元):
右側分支: 僅根據(jù)當前的序列
左側分支: 使用
聯(lián)合輸出: 終結合右側的神經語言模型和左側attention-based編碼器的輸出, 求下一個詞是
基于注意力模型的編碼器enc31的網(wǎng)絡結構圖:
左側分支:
右側分支:
聯(lián)合輸出: 此時
下面兩幅圖分別是對整體結構和編碼器結構的展開:
感興趣的同學可以結合原文中的公式理解:
上圖(a)中對應的公式:
我們現(xiàn)在回到生成摘要的問題. 回顧前面, 我們的目標是找到:
下面舉一個簡單的例子來說明beam search算法的運行過程. 在這個例子里, 摘要長度
Step1: 預測前
Step2: 預測第2個詞的時候, 我們選出新的K個詞符, 對應K條備選路徑. 前一階段概率低的路徑和詞符, 被拋棄掉.
Step3: 重復前面的過程.
Step4: 每次beam search不一定能選出不同的K個詞, 但是每次beam search都找到優(yōu)的前K個路徑, 路徑可以有重疊.
Step5: 迭代N次, 終選出可能性大的一條詞序列路徑
下面是對Beam Search算法的詳細分析, 對原文的Algorithm 1逐條進行解釋.
<s>來初始化. 在訓練和生成摘要時, 窗口<s>做padding.
<e>, 摘要就是從<s>到<e>, 如果沒有<e>出現(xiàn), 摘要的大長度就是
Beam Search的運算復雜度從
NAM模型的程序早是由開源的torch版本的程序. 近谷歌開源了TensorFlow版本的摘要生成程序textsum, Github上的項目. textsum的核心模型就是基于注意力的seq2seq(sequence-to-sequence)模型, textsum使用了LSTM和深度雙向RNN.
Github上的textsum首頁給出了此項目在Bazel環(huán)境下的運行方式. 如果你不想通過Bazel運行, 你可以直接在seq2seq_attention.py中設定運行參數(shù). 設定完參數(shù)后, 直接運行Python seq2seq_attention.py即可. 參數(shù)設定如下圖所示:
除了上述項目運行時所需的必要參數(shù), 模型參數(shù)也在seq2seq_attention.py中設定, 如下圖所示, 包括學習率, 小學習率(學習率會衰減但不會低于小學習率), batch size, train模式encoder的RNN層數(shù), 輸入正文詞匯數(shù)上限, 輸出摘要詞匯數(shù)上限, 小長度限制, 隱層節(jié)點數(shù), word embedding維度, 梯度截取比例, 每一個batch隨機分類采樣的數(shù)量.
Git項目textsum給的toy數(shù)據(jù)集太小, vocab也幾乎不可用(一些常見的單詞都沒有覆蓋到). 如果希望獲得好的效果, 需要自己整理可用的數(shù)據(jù)集.
主要文件說明:
- seq2seq_attention.py: 主程序, 選擇程序的運行模式, 設定參數(shù), 建立模型, 啟動tensorflow
- seq2seq_attention_model.py: 建立attention-based seq2seq model, 包括算法的encoder, decoder和attention模塊, 都在Seq2SeqAttentionModel中完成.
- seq2seq_attention_decode.py: 讀取數(shù)據(jù), 調用beam_search解碼
beam_search.py: beam search算法的核心程序
Google開源的textsum項目的具體算法是基于Hinton 2014年的Grammar as a Foreign Language這篇論文, 下面給出textsum工程中attention-based seq2seq模型的整體結構圖, 圖中所使用的名字與程序中的變量名一致, Seq2SeqAttentionModel是一個類, 定義在seq2seq_attention_model.py中; attention_decoder是一個函數(shù), 定義在/tensorflow/contrib/legacy_seq2seq/python/ops/seq2seq.py中.
為了方便理解, 簡單解釋一下圖中出現(xiàn)的符號,
個符號表示從x1,x2到y(tǒng)的線性變換, 紅色變量是訓練過程要學習出來的.
attention機制比較復雜也比較重要, 我們對這部分細化一下來看. attention decoder結構圖如下:
下圖是對attention模塊的細化:
符號說明:
為什么attention這個模塊會起到效果呢? 因為attention模塊會根據(jù)decoder當前時刻的LSTM單元的狀態(tài), 來調整對attention_states(encoder輸出)的注意力. Attention_states不同位置獲得的關注不一樣. 這樣我們就更大程度地, 關注了原文中, 對當前輸出更為有用的信息, 輸出結果也就更準確了. Attention模塊輸出結果和decoder模塊原本的輸出聯(lián)合起來, 得到終的輸出結果.
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網(wǎng)站上部分文章為轉載,并不用于任何商業(yè)目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯(lián)系我們,我們將根據(jù)著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。