【自然語言處理】SeqGAN的探索(踩坑)記錄

前言

SeqGAN是2017年《SeqGAN: Sequence Generative Adversarial Nets with Policy Gradient》這篇論文提出的模型,使用了強化學習的策略梯度解決了之前GAN只能應用在生成器輸出爲連續值的問題(文本中詞與詞之間的表示是離散的)。
屬於比較開創的工作,之後的許多工作都是在這篇文章的基礎進行的。今天主要是想研究SeqGAN這麼久以來的一個踩坑記錄的總結,主要是要討論關於蒙特卡洛搜索樹在這篇文章是怎麼工作的。

內容

在這個模型中,分爲生成器和判別器。

判別器

判別器是一個二分類器,接收的是一個生成器生成的序列(句子),預訓練和對抗訓練都是由交叉熵作爲目標函數進行訓練。

生成器

生成器是一個基於循環遞歸神經網絡的語言模型(RNNLM)。預訓練是使用極大似然估計法(交叉熵作爲目標函數)。
在對抗訓練中,該篇論文作者將其視爲一個序列決策過程,每個序列狀態是已生成的序列,使用策略梯度進行訓練。這部分細節別的博客講了很多,本文不再贅述,接下來主要描述下蒙特卡洛搜索樹的過程。
在策略梯度的訓練過程中,需要對每個狀態序列給於一個獎勵(reward)。
蒙特卡洛搜索樹就是基於當前的序列狀態(未生成完整的句子)進行補全。
這裏舉個例子。
我們將"< GO> 今天 的 天氣 真的 非常好"視爲一個句子。
在這裏我們需要得到每個單詞的獎勵。
在"< GO>“狀態序列時,進行補全,得到”< GO> 我 愛 吃 蘋果 < PAD>"(舉例的),扔到判別器進行判別得到的概率作爲"< GO>“的獎勵。
在”< GO> 今天 “狀態序列時,進行補全,得到”< GO> 今天 適合 野炊 < PAD> < PAD>"(舉例的),扔到判別器進行判別得到的概率作"今天"的獎勵。
在"< GO> 今天 的"狀態序列時,進行補全,得到"< GO> 今天 的 美女 很多 < PAD>"(舉例的),扔到判別器進行判別得到的概率作爲"的"獎勵。
在"< GO> 今天 的 天氣"狀態序列時,進行補全,得到"< GO> 今天 的 天氣 不是 非常差"(舉例的),扔到判別器進行判別得到的概率作爲"天氣"獎勵。

在"< GO> 今天 的 天氣 真的 非常好"狀態序列時,直接扔到判別器進行判別得到的概率作爲"非常好"獎勵。
那麼,如何這個用代碼實現,請看下面的片段。
在"< GO> 今天 的"狀態序列時,我們像訓練(dynamic_rnn)一樣將""< GO> 今天"輸入(注意,沒有輸入"的"),得到最後一個隱含狀態。然後將隱含層狀態和"的"作爲推理的輸入,得到輸出詞,再把輸出的詞和當前的隱含狀態想做下一步的輸入。
那這裏有需要注意的地方是,經過蒙特卡洛搜索樹的句子扔到判別器得到概率,記得要和用判別器訓練時的句子一樣。
比如"< GO> 這個 飯菜 真的 很好吃 < PAD> < EOS>“這樣的句子去訓練判別器,經過蒙特卡洛搜索樹的句子”< GO> 這個 飯菜 真的 很好吃 < PAD> "(沒有< EOS>)會立即被判別器判別爲假的句子(判別器非常記仇,一旦訓練時句子有< EOS>,然後沒有< EOS>的句子會判別爲假)。

不足

SeqGAN的模型提出確實提高了文本生成的質量,但是目前也存在着兩個問題。
1.在訓練過程中可以發現,判別器太好,以至於生成器生成的句子常常得到的都是被判別爲假的(概率非常小),而這個是用來作爲獎勵進行訓練的。這樣會造成訓練低下,有些論文稱這個現象爲梯度消失(vanishing gradient)。
2.模式崩潰,這是原生GAN就存在的問題,即在讓生成器學習真實樣本的數據分佈時只能學到一部分,以至於句子常常是重複的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章