Chapter7-6_Text Style Transfer

zjuPeco發表於2020-10-07

本文為李弘毅老師【Text Style Transfer】的課程筆記,課程視訊youtube地址,點這裡?(需翻牆)。

下文中用到的圖片均來自於李宏毅老師的PPT,若有侵權,必定刪除。

文章索引:

上篇 - 7-5 Multilingual BERT

下篇 - 待更新

總目錄

1 什麼是Text Style Transfer

style transfer這個概念對我們而言並不陌生,就算不是做技術的,也在日常生活中會看到過一些影像風格轉換的東西,比如把正常的照片變成梵高風格的畫等等。語音上的風格轉換我們在之前講voice conversion的時候也由講到過,比如把男聲變成女聲就是一種風格轉換。
7-6-1

而文字的風格轉換一個典型的例子就是正面情緒的語言和負面情緒語言的相互轉換。不過,文字風格轉換的實際應用場景要比我們想象的多得多。
7-6-2

2 Cycle GAN

文字風格轉換用到的技術也是cycle gan,我們會需要一個generator(G),G會吃一個負面的句子,然後吐出一個正面的句子;我們也會需要一個discriminator(D),D已經用一堆句子訓練過了,知道什麼是正面的句子,什麼是負面的句子,把G生成的句子丟給D,D判斷G生成的句子是正面的還是負面的;同時我們還需要一個generator,這裡我們可以將其稱之為reconstructor®,他就是要把G生成的句子再變回換來的句子,沒有R的話,G只要一直生成同一句話就可以騙過D了。
7-6-3

我們的G是一個seq2seq的模型,這個大家應該已經很熟悉了,它就是輸入文字的第一個token的feature和前一個token,然後RNN會輸出這個time step預測出來的token distribution,在distribution中進行sample,最後得到預測的一串tokens,把這些tokens輸入D,D就會吐出一個scalar,就表示現在輸出的句子,是不是有某種風格,比如是不是正面情緒的句子。我們一般會把G和D串起來end2end這樣train,但在這裡,由於sample這個過程是不可微的,所以不能串起來train。
7-6-4

那怎麼辦呢?沒有了D這個下游任務,loss怎麼算?這其實是一個比較大的話題,這裡我們只略講一下。解決方法目前大致可以分為三大類:Gumbel-softmax,Continuous Input for Discriminator和Reinforcement Learning。Gumbel-softmax不常用,Continuous Input for Discriminator和Reinforcement Learning孰強孰弱不好說。

2.1 Gumbel-softmax

Gumbel-softmax這一招沒有後面那兩招那麼流行,它用了VAE中叫做reparameterization的trick,使得不可微分的sample變成可微分的了。具體怎麼回事,李老師也沒說,想了解的小夥伴可以參考GANS for Sequences of Discrete Elements with the Gumbel-softmax DistributionRelGAN:
Relational Generative Adversarial Networks for Text Generation

7-6-5

2.2 Continuous Input for Discriminator

第二招非常直接,既然sample這個步驟不可微,那麼我們就乾脆跳過這個步驟,把token distribution直接塞給D,這不就可以微分了嗎?
7-6-6

那這樣做的問題是什麼呢?問題就是,D在預訓練是看到的資料都是one-hot的,而G生成的distribution不是one-hot的,D只需要學到說one-hot的是real的,不是one-hot的是generated的就可以了。這樣就會發現模型什麼都沒學到。所以一般還會用WGAN中類似的技術,給D加一些約束條件,讓它不那麼重要,那模型也許就可以學到些東西。還有一種做法是,把distribution經過embedding之後變成特徵向量,這樣模型就沒法一下子從表面認出來了。
7-6-7

2.3 Reinforcement Learning

最後一招就是用RL,怎麼用RL呢?我們只要把不能微分的地方用RL去做就可以了,這裡的話,就是把sample出來的token當作action,把D當作environment,然後scalar當作reward就可以了。
7-6-8

但是這裡的D是在更新的,也就是environment一直在變,這會讓RL非常難train,同時GAN也是非常難train的,難上加難會讓這個訓練非常困難。所以我們需要一些tips,這個可以參考ScratchGAN,上面羅列了一些可用的技巧。其中有一個必用的技巧叫做SeqGAN-step,這裡稍微說一下。

RL之所以難train是因為當D輸出一個低分數,從G的角度來說,它並不知道為什麼分數這麼低,它不知道句子的哪個部分導致了分數低。所以我們希望每生成一個token都可以有一個評分,這樣G就知道哪裡錯了。
7-6-9

讓D在每個generation step都做出評價的方法這裡不細講,有興趣的小夥伴可自行查資料學習一下,主要有三種:

2.4 效果

Cycle GAN產生的句子是長什麼樣子呢?李老師的學生做了實驗之後的結果如下所示。出來的結果還是有點奇怪的,不過也有幾分道理。
7-6-10

3 Star GAN

當我們需要在多種風格之間轉換時,用Cycle GAN就需要train很多的G和D,這樣太麻煩了。影像和語音中一般會考慮使用Star GANSytle Transformer就是文字版的Star GAN。這裡只是提一下多個風格之間轉換該怎麼辦,想了解詳情的小夥伴可以自行看論文。
7-6-11

4 Feature Disentangle

我們在做voice conversion的時候除了GAN之外,還有feature disentangle的方法。這個方法也可以同樣用在text上,我們的目標就是train一個content encoder只抽取content的特徵,同時train一個style encoder只抽取style的特徵。然後要換style,只需要把style這部分的特徵換掉就可以了。不過這種方法近幾年並沒有被用的很多,效果不如GAN,因為要做句子的embedding,把句子壓到一個latent space是比較困難的。
7-6-12
既然content encoder把句子做embedding比較困難,那不妨我們就讓content encoder輸出離散的特徵,也就是句子,然後我們希望content encoder可以學會把風格有關的一些詞彙給蓋掉。這樣再結合style的特徵,decoder只需要把蓋掉的部分替換成對應風格的詞彙即可。
7-6-13

不過新的問題又來了,如何找到這個和風格有關的詞彙並蓋掉呢?有興趣的小夥伴可以參考Delete, Retrieve, Generate: A Simple Approach to Sentiment and Style TransferUnpaired Sentiment-to-Sentiment Translation: A Cycled Reinforcement Learning Approach

5 Unsupervised Abstractive Summarization

風格轉換不光可以把正面情緒的句子轉化為負面情緒的句子,如果我們把完整的文章作為一種風格,摘要作為一種風格,那麼我們就可以利用風格轉換的方法來做無監督的摘要生成。有監督的摘要生成需要收集大堆的成對的資料,成本很高,無監督無疑是大家的福音。
7-6-14

做法與之前情緒轉換的做法一樣,我們需要有一個G把文章轉成摘要;然後需要一個D來判別輸入的是不是摘要;最後還需要一個R來吧G生成的摘要重新變回原來的文章。
7-6-15

那麼,這種做法做出來的摘要效果如何呢?下面是某篇文章中的結果,用的評價指標是ROUGE,越大表示和人寫的摘要越接近,越好。第一行是有監督的結果,是效果最好的。第二行是取文章前幾句話的結果,相當於是個基於規則的baseline。第三行是用同一個資料集裡的文章和摘要做訓練得到的結果,第四行是不同資料集的文章和摘要訓練得到的結果。可見無監督的結果,還行。
7-6-16

6 Unsupervised Translation

我們也可以把不同語言當作不同的風格,來實現無監督的翻譯。

無監督的翻譯有一種做法就是利用word embedding取逐個詞地翻譯。假設我們已經有了中文的embedding和英文的embedding,如下圖所示,那麼很有可能兩個語言的embedding之間只需要一個線性變換就可以把一種語言的embedding對應到另一種語言上,比如下圖這樣的就只需要經過一個逆時針的旋轉即可使得對應意思的詞重合。
7-6-17

那麼我們的問題就變成了如何找這個線性變換 W W W。不同語言之間有一些相同token且相同意思的詞彙,比如阿拉伯數字,那我們就可以根據阿拉伯數字的embedding去學習這個 W W W。我們也可以利用GAN的技術,把 W W W當作一個Generator,然後再訓練一個Discriminator來判別經過G之後的embedding和右邊的接近程度。甚至也有人直接用PCA,這兩邊的embedding就對齊了。

下面來說一下用類似GAN的技術來做Unsupervised Translation的方法。假設我們有語言A和語言B。我們分別對語言A和語言B訓練各自的自編碼器,得到encoder A,decoder A,encoder B和decoder B。在訓練的時候,我們會對輸入加一些noise,防止模型變成一個只會”複製貼上“的模型。然後,我們想要在encoder A中輸入語言A的句子之後,再經過decoder B就得到句子在語言B中的翻譯結果。

這說起來輕鬆,但誰也沒法保證encoder A和encoder B是按照同樣的方式去encoder的。所以我們需要一些tricks。

第一個trick,就是加一個discriminator,用來區別encoder的輸出是encoder A的還是encoder B的。這樣一來,就可以迫使encoder A和encoder B儘可能用同樣的方式去encode。我們希望這樣做之後,decoder B不僅可以看懂encoder B的結果,也可以看懂encoder A的結果。
7-6-18

第二個trick是,我們把encoder A的輸出輸入到decoder B,然後把decoder B的輸出輸入到encoder B,最後把encoder B的輸出輸入到decoder A,希望這種情況下encoder A的輸入和decoder A的輸出越接近越好。但是這樣模型並不能具備翻譯的能力,它可能會把“再見”對應成“How are you”。
7-6-19
所以我們需要另一個模型,這個模型是一個爛一點的模型,它可以就是剛才講到的用word embedding做mapping得到的模型,用這個模型來代替encoder A和decoder B,這樣可以在訓練前期把結果引導到相對正確的句子上去訓練encoder B和decoder A,在後期train的差不多了之後,再固定住encoder B和decoder A,來訓練encoder A和decoder B,如此交替迭代。
7-6-20

這樣做出來的結果如下圖所示,有監督的翻譯訓練會隨著訓練樣本的增加而越來越好,但無監督的翻譯訓練再剛開始就會有一個比較好的結果,隨著訓練樣本的增加,效果提升並不明顯。這樣的結果挺奇怪的。
7-6-21

7 Unsupervised Speech Recognition

最後要講的是無監督的語音辨識,也就是把語音認為是一種風格,文字認為是一種風格。用到的方法還是和之前一樣,只不過有語音進來所以會做一些處理,會把phoneme作為中間媒介。然後這部分就不細講了,有興趣的小夥伴去聽一下李老師的課吧,李老師講的比較簡略,我也一知半解。

總之,用這種方法可以得到還不錯的結果,接近有監督的語音識別。
7-6-22

相關文章