本文轉載至知乎ID:Charles(白露未晞)知乎個人專欄
本文轉載至知乎ID:Charles(白露未晞)知乎個人專欄
導語
本文將在此基礎上介紹LSTM網絡。最后舉一個類似“Python學寫作”的例子來實現文本生成,如生成詩歌、小說等等。
讓我們愉快地開始吧~~~
參考文獻
Understanding LSTM Networks:
http://colah.github.io/posts/2015-08-Understanding-LSTMs/
相關文件
百度網盤下載鏈接: https://pan.baidu.com/s/16hjmw1NtU9Oa4iwyj4qJuQ
密碼: gmpi
開發(fā)工具
Python版本:3.6.4
相關模塊:
tensorflow-gpu模塊;
numpy模塊;
以及一些Python自帶的模塊。
其中TensorFlow-GPU版本為:
1.7.0
環(huán)境搭建
安裝Python并添加到環(huán)境變量,pip安裝需要的相關模塊即可。
另外,TensorFlow-GPU的環(huán)境搭建請自行參考相關的網絡教程,注意版本和驅動嚴格對應即可。
原理介紹
一. RNNs
人們的思維總是具有延續(xù)性的,比如當你閱讀這篇文章時,你對每個詞的理解都會依賴于你前面看到的一些詞,而不是把你前面看的內容全部拋棄,再去理解每個詞。而傳統(tǒng)的神經網絡(CNN)無法做到這一點,因此有了循環(huán)神經網絡(RNNs)。
在RNNs中,存在循環(huán)操作,使得它們能夠保留之前學習到的內容:
在上圖網絡結構中,對于矩形塊A的那部分,通過輸入Xt(t時刻的特征向量),它會輸出一個結果ht(t時刻的狀態(tài)或者輸出),網絡中的循環(huán)結構使得當前狀態(tài)作為下一時刻輸入的一部分。
將RNNs在時間步上進行展開,就可以得到下圖:
也就是“Python實現簡單的機器翻譯模型”一文中所使用的RNNs鏈狀的結構。顯然,這樣的結構是有利于處理序列相關問題的。近年來,其在語音識別、語言翻譯等等領域都取得了巨大的成功。
而RNNs的成功,主要歸功于LSTMs這種特殊RNNs結構的使用,而非普通的RNNs結構。
二. LSTMs
全稱為Long Short Term Memory networks.
即長短期記憶網絡。
普通RNNs的局限性在于當我們所要預測的內容和相關信息之間的間隔很大時,普通RNNs很難去把它們關聯起來:
盡管從理論上來講,只要參數合適,還是可以解決長時期依賴關系無法很好聯系這一問題的,但具體實現起來似乎并不容易,至少目前為止是不容易的。
幸運的是,LSTMs能夠很好地解決這一問題。它被設計的初衷就是為了能夠記住長時期內的信息。
循環(huán)神經網絡是由相同結構的神經網絡模塊進行復制而形成的。在標準的RNNs中,神經網絡模塊的結構非常簡單,比如可以由單一的tanh層構成:
LSTMs也有類似的結構,不過神經網絡模塊的結構變得相對復雜了一些:
接下來,我們來詳細介紹一下這個結構。首先,我們來定義一下用到的符號:
粉紅色的圈:
代表向量加之類的逐點操作;
黃色矩形框:
代表神經網絡層;
普通的線:
用于攜帶并傳遞向量;
合并的線:
代表對兩條線上所攜帶的向量進行合并;
分開的線:
代表將線上所攜帶的向量復制后傳給兩個地方。
2.1 LSTMs的核心思想
假設一個綠色的框就是一個cell。
向量通過結構圖最上面的那條貫穿cell的水平線穿過整個cell,而cell僅對其做了少量的線性操作:
顯然,這樣的結構能夠很輕松地讓信息從整個cell中穿過而不發(fā)生變化。
當然,只有一條水平線是無法實現添加或者刪除信息的,也就是實現讓信息有選擇地通過cell,這需要通過一種叫做門(gates)的結構來實現。
門結構主要由一個sigmoid神經網絡層和一個逐點相乘的操作來實現:
sigmoid層輸出的向量每個元素都是介于0和1之間的實數,表示此時通過的信息的權重,當其為0時表示“此時不讓任何信息通過”,為1時表示“此時讓所有信息通過”。每個LSTM都有三個這樣的門結構,來實現保護和控制信息。
2.2 逐步理解LSTM
遺忘門(forget gate layer):
首先,LSTM需要決定哪些信息需要丟棄,哪些信息需要保留。這是通過一個叫做遺忘門的sigmoid層來實現的。它的輸入是ht-1和xt,輸出是一個數值都在0到1之間的向量,表示Ct-1中各部分信息的權重,0表示不讓該部分信息通過,1表示讓該部分信息全部通過。
具體而言,比如在語言模型中,我們要根據所有的上下文信息來預測下一個詞。在這種情況下,每個cell的狀態(tài)中都應該包含了當前主語的性別信息。這樣,接下來我們才能夠正確地使用代詞。但是,當我們開始描述一個新的主語時,就應該把之前的主語性別給丟棄了才對。
傳入門(input gate layer):
其次,LSTM將決定讓哪些新的信息加入到cell的狀態(tài)中來。該實現分兩個步驟進行:
① 用一個tanh層生成一個備選向量,用于表示獲得的所有可添加信息;
② 用一個叫做傳入門的sigmoid層來決定步驟①中獲得的可添加信息各自的權重。
具體而言,比如在語言模型中,我們需要把新主語的性別信息添加到cell狀態(tài)中,來替換掉之前的主語性別信息。
有了遺忘門和傳入門,我們就能夠更新cell的狀態(tài)了,即把Ct-1更新為Ct。
還是以語言模型為例,假設我們的模型剛輸出了一個代詞,接下來可能要輸出一個動詞,那么這個動詞應該采用單數形式還是復數形式呢?顯然,我們需要把代詞相關的信息和當前的預測信息都加入到cell的狀態(tài)中來,才能夠進行正確的預測。
具體計算方式如下圖所示:
輸出門(Output):
最后,我們需要決定輸出值。輸出值的計算方式為:
① 使用sigmoid層來決定/計算出Ct中的哪部分信息會被輸出;
② 利用tanh層將Ct的取值壓縮到-1到1之間;
③ 將tanh層的輸出和sigmoid層的輸出相乘即為最終的輸出結果。
三. LSTMs的變種
① 將cell的狀態(tài)作為門結構輸入的一部分。
② 將遺忘門與傳入門耦合,即不再分開決定要遺忘和添加的信息。
③ GRU
GRU模型“簡化”了LSTM模型的設計,其中rt由LSTM中的遺忘門和傳入門合并而得,稱為重置門;zt為更新門,作用相當于LSTM中的輸出門。
實際應用
為了貫徹理論與實踐相結合的理念,本文將舉一個簡單的小例子,該例子使用的模型與“Python學寫作”類似,本文不再作多余的介紹。
具體實現過程詳見相關文件中的源代碼。
使用演示
模型訓練:
在cmd窗口運行'train.py'文件即可:
如有需要,可自行修改相關參數:
模型使用:
在cmd窗口運行“generate.py”文件即可。
注意模型參數需和train.py文件中的模型參數一致:
結果展示
生成英文文本:
以莎士比亞的作品為訓練素材獲得的結果:
生成中文文本:
以周杰倫的作品為訓練素材獲得的結果:
更多
代碼截止2018-06-24測試無誤。
模型比較簡單,有興趣的朋友可以在此基礎上進行優(yōu)化,當然RNN的作用可不僅僅是文本生成哦~
以后有機會再舉其他例子吧~~~