無監督循環神經網路文法 (URNNG) | NAACL19
雷鋒網 AI 科技評論按,本文作者[韋陽](https://www.zhihu.com/people/godweiyang/posts "韋陽"),本文首發於知乎專欄[自然語言處理與深度學習](https://zhuanlan.zhihu.com/godweiyang "自然語言處理與深度學習"),雷鋒網 AI 科技評論獲其授權轉載。 **論文地址:**[Unsupervised Recurrent Neural Network Grammars](http://arxiv.org/abs/1904.03746) **代碼地址:**[github](https://github.com/harvardnlp/urnng) # 介紹 --- 這篇是新鮮出爐的 NAACL19 的關於無監督循環神經網路文法(URNNG)的論文,在語言模型和無監督成分句法分析上都取得了非常不錯的結果,主要採用了變分推理和 RNNG。本文公式量較大,因此我也推了好久,演算法也挺多的,首先上一張我推導的公式筆記: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5ccfe8d71f197.jpg) 我這篇博客就不按照論文的順序來講了,就按照我上面這張筆記講一講我的理解吧,很多細節可能會忽略,請參見原文吧。 首先對於無監督成分句法分析,常規做法就是學習一個生成模型!(https://static.leiphone.com/uploads/new/article/740_740/201905/5ccff4c4e9ea9.png),就比如 RNNG 就是一個生成模型,但是缺少句法樹 z 的監督信號怎麼辦呢?現在給你的輸入只有句子 x,那麼只能用語言模型!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0018247697.png)來做監督了。習慣上我們喜歡取對數,也就是: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0019a1a3ae.png) 這裡就存在幾個問題,比如 z 的狀態空間太大了,不可能窮舉所有的,所以接下來按步驟講解如何求解。 # URNNG模型 --- 先上一張模型圖,讓大家對整體模型有個大概的認知: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd001d48aec7.png) 左邊是一個推理網路(Inference Network),用來根據輸入 x 推理出隱變數也就是句法樹 z 的概率分布!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0022261540.png)。右邊是一個生成模型(Generative Model),用來計算從推理網路中採樣出來的句法樹 z 的聯合概率!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0023ebd1a7.png),最後根據上面語言模型算出句子的概率,最大化這個概率即可。 接下來分別講解這兩個部分和具體的優化方法。 !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd002c44eea8.png) 首先將詞向量!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0031285a42.png)和位置向量!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00322db624.png)拼接,作為推理網路 LSTM 的輸入: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0034a094fe.png) 然後算出!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0036de95e8.png)的得分,計算方式和以往一樣,用 BiLSTM 前後向輸出做差,然後通過一個前饋神經網路得到分數: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0056fdb506.png) 接下來就需要計算句法樹的概率分布了,這裡不直接計算句法樹 z,而是計算它的鄰接矩陣 B 的概率分布,這個鄰接矩陣意思就是如果!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0059732fb2.png)存在,那麼!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd005b539800.png),否則的話!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd005ca68054.png)。然後就可以用 CRF 計算出鄰接矩陣 B 對應的概率: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd005f4dd93b.png) 其中!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0060b1878b.png)是配分函數,也就是用來將概率歸約到 0 到 1 之間的: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00620c7d27.png) 注意這裡的!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0064462a9e.png)並不是所有的 01 矩陣集合,而是必須滿足能產生合法句法樹的矩陣,情況也很多,不能窮舉求解,在這裡採用經典的 inside 演算法來求解這個配分函數: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00669436e2.jpg) 不過我覺得這裡是錯的!就是這裡的兩處!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd006c10dc7e.png)應該改成!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd006d1b4efd.png)。不過具體代碼實現的時候並沒有這麼做,初始值一樣都是!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd006e5cf5f9.png),但是遞推的時候採用了如下式子: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00703cf397.png) 其實就是用!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd007198598f.png)來取代!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00744ca553.png)了,化簡後就是代碼實現這個式子,應該是為了防止數值溢出。 然後就是採樣了,推理網路的目的就是計算出句法樹的概率分布,然後根據這個分布採樣出若干個句法樹,那麼現在給定一棵句法樹可以根據上面的演算法計算出它的概率了,那怎麼採樣呢?其實還是可以通過剛剛計算得出的!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0076183c1a.png)數組來採樣,採樣演算法如下: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd008cad79c7.jpg) 其實就是自頂向下的根據概率分布來採樣每個 span 的 split,用一個隊列來保存所有還沒有採樣出 split 的 span,然後把所有採樣出的 span 在鄰接矩陣中的對應值標為1。 最後推理網路採樣出了若干個句法樹 z,然後根據 CRF 計算出每個句法樹的概率!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00937a3d16.png),後面的事情就交給生成網路了。 !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0094a504bb.png) 上面的推理網路採樣出了若干個句法樹 z,生成網路的目的就是計算它的聯合概率!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd009d0b7269.png)。這個其實不難,在之前的 RNNG 論文筆記中,我已經大致講過了,可以去複習一下:[Recurrent Neural Network Grammars](https://godweiyang.com/2018/09/02/RNNG/),這裡稍稍做了一些改進。 首先需要定義一個棧用來存放轉移的歷史狀態,這裡定義棧里放的元素為二元組(h, g),一個是 stack-LSTM 編碼的輸出,一個是子樹的結構表示。首先需要預測下一步的 action 是什麼,所以取出棧頂的元素!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00a0993c7a.png),預測 action 的時候只要用到隱含層輸出: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00a2527fe7.png) 然後根據這個概率預測 action 是 SHIFT 還是 REDUCE,下面分兩種情況討論。 如果是 SHIFT,那麼因為是生成模型,所以需要預測下一個移進的單詞是什麼: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00a9b68a11.png) 然後將單詞 x 的詞向量輸入到 stack-LSTM 中得到下一個時刻的隱含層輸出: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00acb80148.png) 最後將!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00adcd092c.png)推進棧里。 如果是 REDUCE,那麼首先需要取出棧頂的兩個元素!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00b3f16ad7.png)和!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00b4d004fb.png),然後用 TreeLSTM 計算出兩個子結點合併後的子樹的表示: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00be43318f.png) 接著還是計算 stack-LSTM 下一個時刻的隱含層輸出: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00bfb2133e.png) 最後將!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00c0f3cf6c.png)推進棧里。 為了防止數值溢出,常規上我們計算聯合概率的對數: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00c27f19cf.png) 從這個式子可以看出,聯合概率定義為所有給定某段單詞和 action 預測下一個單詞和給定某段單詞和 action 預測下一個 action 的概率之積。 如果是監督任務比如 RNNG,那麼只需要最大化這個聯合概率就足夠了,但是現在要做無監督,沒有 z,注意別搞混了,推理網路採樣出的 z 可不能用來監督哦,因為那本來就不是正確的,所以接下來要採用語言模型來作為最終的目標函數。 ## Variational Inference 句子 x 的對數概率定義為: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd00c637b136.png) 其中!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0192ac578b.png)是所有合法句法樹的集合,但是這裡不可能窮舉所有的句法樹,所以就要用到變分推理,具體的理論知識不仔細介紹了,可以去查閱變分推理相關知識,下面直接推導。 !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0194ced2d8.png) 其中最後一行叫做先驗!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd019b000b7e.png)的證據下界(ELBO),要想最大化先驗,可以最大化這個 ELBO,如果我們對這個 ELBO 變化一下形式可以得到: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd019dd14ef4.png) 所以這個 ELBO 和先驗就相差了一個 KL 散度,最大化 ELBO 的話等價於最小化 KL 散度,也就是使推理網路產生句法樹的概率分布和生成模型盡量接近。 但是這個 ELBO 還是不好算,儘管它把!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01a6b14e49.png)移到了求和符號也就是期望裡面,所以轉換一下形式: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01a586f2ef.png) 因為模型一共有兩組參數,一個是推理網路的參數!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01a8852ffc.png),一個是生成網路的參數!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01a96dfd87.png),所以下面分別對兩個參數求導。 首先對!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01aac8c546.png)求偏導,因為只有第一項有這個參數,所以偏導為: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01abef116c.png) 這個偏導可以按照概率!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01ad0d3953.png)採樣得到: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01afc11128.png) 然後對!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01b1a34d63.png)求偏導,因為有兩項含有這個參數,分別求偏導。第二項是熵,它的值其實可以用之前的!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01b2fa2a6b.png)數組算出來,演算法如下: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01b4d4da00.jpg) 然後偏導可以交給深度學習庫的自動微分,就不用你自己求啦。 至於第一項的偏導可以用類似於策略梯度的方法解決: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01bac0deb4.png) 這裡最後也是轉化為了採樣,和策略梯度做法類似,這裡加入 baseline 來提升性能: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01bc65131a.png) 其中!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01bd90b591.png)定義為所有其他的對數聯合概率的均值: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01bec80a30.png) 至此所有偏導都已求出來了,兩個通過採樣得到,一個通過 inside 演算法結果自動微分得到,所以去掉導數符號並相加就得到了最終的損失函數: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01c03b63c7.png) 一定要注意,這裡的!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd0290b4e43e.png)在代碼實現的時候不能傳入梯度,不然的話對!(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01c2b70fc5.png)的偏導就會多出這一項的偏導了! # 實驗 --- 實驗結果這裡就不多說了,細節具體看論文吧,就貼兩個結果,一個是語言模型: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01c41e1884.jpg) 可以看出在標準的 PTB 數據集上,URNNG 效果只比監督學習的 RNNG 和用 URNNG 損失函數微調後的 RNNG 效果略差一點,但是在大數據集上,URNNG 的優勢就體現出來了。 另一個是無監督成分句法分析,這裡是用的全部長度的測試集: !(https://static.leiphone.com/uploads/new/article/740_740/201905/5cd01c6670faa.jpg) 這個任務上 URNNG 效果是最好的。 # 結論 --- 和之前兩篇語言模型做無監督成分句法分析類似,這篇論文用推理網路學習句法樹的概率分布並採樣句法樹,再用生成網路計算這些句法樹和句子的聯合概率,最後用變分推理最大化句子的概率,也就是學習出一個好的語言模型。 雷鋒網
※蘋果稅要亡?
※蘋果信用卡Apple Card實物首曝光;雷軍曬小米首款5G手機;扎克伯格拒絕拆分Facebook
TAG:雷鋒網 |