教程|如何快速訓練免費的文本生成神經網絡

textgenrnn 的一個好處是它可以免費使用「Google Colaboratory」很容易地在 GPU 上快速地訓練神經網絡。我創建了一個 notebook(https://drive.google.com/file/d/1mMKGnVxirJnqDViH7BDJxFqWrsXlPSoK/view),它可以讓你僅僅通過幾次點擊就能夠訓練自己的網絡並且生成文本。

開始編寫你的第一個文本生成神經網絡吧

Colaboratory 是一個類似其它數據科學項目中使用的 Jupyter Notebooks 的筆記本環境。然而,Colaboratory notebook 被免費託管在一個有兩個虛擬 CPU、13GB 內存、一個 K80 GPU 的短期虛擬機上。通常,這種配置的虛擬機需要在谷歌計算引擎上花費 0.57 美元/小時;這個費用聽上去很低,但是當你需要訓練好幾個小時才能取得好的訓練結果時,費用就積少成多了。

首先,我建議將該 notebook 複製到硬盤上(如果你沒有這麼做,那麼請使用 Google Chrome 瀏覽器訪問它)。Colaboratory 虛擬機包含了 Python 3 和像「Tensorflow」這樣用於機器學習的通用 Python 程序包。但是你可以直接在 notebook 中安裝更多的程序包。比如 textgenrnn!只需要點擊進入這個單元並且點擊「play」按鈕(或者使用 Shift + Enter)即可運行這個單元格,其它的部分都將由它控制:

教程|如何快速訓練免費的文本生成神經網絡

當我們訓練新模型時,「textgenrnn」使你能夠通過各種各樣的參數來指定神經網絡的大小和複雜度:

教程|如何快速訓練免費的文本生成神經網絡

現在讓我們保留這些默認的參數,運行該單元將它們加載到內存中。運行下一個單元,它會提示你上傳一個文件。任何文本文件都應該能工作,甚至是很大的文本文件!在這個例子中,本文將使用一個在 char-rnn demo 中也使用過的 1.1MB 莎士比亞戲劇的文本文件。

教程|如何快速訓練免費的文本生成神經網絡

下一個單元將初始化一個 textgenrnn 實例,並開始訓練一個新的自定義文本生成神經網絡!

教程|如何快速訓練免費的文本生成神經網絡

textgenrnn 自動地將輸入文本處理成用於訓練神經網絡的字符序列。並且每兩個 epoch(對數據進行完整的遍歷)後,神經網絡就會使用不同的溫度(temperature)參數來生成文本,這代表了文本的「創造能力」(也就是說,它允許模型做出越來越差的預測,這可能會創造出令人啼笑皆非的文本。)我通常喜歡將溫度設置為 0.5 來生成文本,但是對於訓練的很好的模型,你可以將它調高為 1。

該模型快速的訓練速度要歸功於虛擬機的 GPU,它可以比 CPU 更快地執行必要的數學運算。然而,針對循環神經網絡,Keras 最近添加了一個 RNN 的 CuDNN 實現,如 CuDNNLSTM,它可以更容易地利用直接在 GPU 上編程的代碼,並且較之於之前的實現方法能獲得巨大的速度提升(大約是之前的 7 倍)!總的來說,對於這個示例數據集和模型架構,在 GPU 上每訓練一個 epoch 需要花費 5 到 6 分鐘,而在一個 CPU 上,相同的訓練則需要 1 小時 24 分鐘。可見,在 GPU 上獲得了 14 倍的速度提升!

訓練完成後,運行下一個單元將下載以下 3 個文件:一個權重文件(weights)、一個詞彙表文件(vocabulary),以及一個配置文件(config),如果你想在其他地方重新生成該模型,這些文件都是必要的。

教程|如何快速訓練免費的文本生成神經網絡

例如:在你自己的個人電腦上。只用在終端輸入 pip3 install textgenrnn tensorflow,即可安裝 textgenrnn 和 Tensorflow。切換到下載文件所在的目錄,運行 python3,並使用以下代碼加載模型:

from textgenrnn import textgenrnntextgen = textgenrnn(weights_path='colaboratory_weights.hdf5',vocab_path='colaboratory_vocab.json',config_path='colaboratory_config.json') 

就是這樣了!如果你僅僅想生成文本,並不一定需要 GPU。你可以使用 textgen.generate_samples() 來生成樣本(比如在訓練時),使用 textgen.generate_to_file() 在任意你選定的溫度下生成大量的樣本。或者使用 textgen.generate(1, return_as_list=True)[0] 將生成的文本引入到 Python 腳本中(例如 Twitter 機器人),從而將文本存儲為變量。你可以在這個 demo Jupyter Notebook 中查看 textgenrnn 的更多函數和功能:https://github.com/minimaxir/textgenrnn/blob/master/docs/textgenrnn-demo.ipynb。

以下是在溫度參數為 0.5 時,訓練了 50 分鐘的模型生成的莎士比亞戲劇文本:

LUCENTIO:

And then shall good grave to my wife thee;

Thou would the cause the brieved to me,

And let the place and then receives:

The rest you the foren to my ways him child,

And marry that will be a parties and so set me that be deeds

And then the heart and be so shall make the most as he and stand of seat.

GLOUCESTER:

Your father and madam, or shall for the people

And dead to make the truth, or a business

As we brother to the place her great the truth;

And that which to the smaster and her father,

I am I was see the sun have to the royal true.

還不錯,甚至有點五步抑揚格的意思!

對模型進行調整

上面提到最重要的模型配置選項是 rnn_size 和 rnn_layers:它們決定網絡的複雜度。通常來說,你在教程中看到的網絡是由 128 個神經元或 256 個神經元組成的網絡。然而,textgenrnn 的架構略有不同,因為它有一個包含了前面所有模型層的注意力層。因此,除非你擁有特別大量的文本(>10MB),讓模型更深比讓模型更寬要好一些(例如,4x128 比 1x512 的模型要好)。rnn_bidirectional 控制循環神經網絡是否是雙向的,也就是說,它同時向前和向後處理一個字符(如果文本遵循特定的規則,如莎士比亞的字符標題,這種方法會十分有效)。max_length 決定用於預測下一個字符的網絡的最大字符數,當網絡需要學習更長的序列時應該增大它,而當網絡需要學習更短的序列時則應該減小它。

在訓練過程中也有很多有用的配置選項。num_epochs 決定了完整遍歷數據的次數,如果你想對模型進行更多次的訓練,你可以調整這個參數。batch_size 決定了在一個計算步中訓練的模型序列的數量,深度學習模型的批處理大小一般是 32 或 128,但是當你擁有一個 GPU 的時候,你可以通過使用給定的 1024 作為缺省批處理大小來獲得訓練速度的提升。train_size 決定待訓練字符樣本的比例,將它設置為< 1.0 可以同時加快每個 epoch 的訓練速度,同時防止模型通過一字不差地學習並複製原文來「作弊」(你可以將「validation」設置為 True,在每一個 epoch 後利用未使用的數據運行模型,來看看模型是否過擬合)。

下面我們嘗試在一個新的文本數據集上對參數進行更多的調整。

用 Reddit 網站的數據進行單詞級別的文本生成

然而,Reddit 上有數以百萬計的文章標題,這非常有益於訓練模型。我寫了一個能夠在給定的時間內從給定的「subreddit」板塊上自動下載自上而下的 n 條 Reddit 文章的 helper 腳本(https://github.com/minimaxir/subreddit-generator)。如果你選擇了有相似語言風格的 subreddit,這些 subreddit 甚至會合並在一起!這裡,我們獲取了 2017 年/r/politics 和/r/technology 板塊的前 20000 條文章,最終形成了一個 3.3MB 的文件,其數據大小大約是莎士比亞戲劇數據的 3 倍。

教程|如何快速訓練免費的文本生成神經網絡

此外,該模型的權重比字符級別的模型大得多,因為單詞級別的模型需要存儲每個單詞的嵌入(取決於 max_word 參數,該參數在單詞級模型中的缺省值為 10,000,而字符級模型中的詞彙表大小為 200-300)。

Colaboratory notebook 的另一個優點是,你可以快速地調整模型參數、上傳新文件,並且立刻開始訓練它。由於沒有特殊的規則,我們將 line_delimited 設定為 True,將 rnn_bidirectional 設定為 False。對於單詞級別的訓練,我們將 word_level 設定為 True,將 max_length 設定為 8 來反映新的訓練架構。由於訓練長度被減少到了五分之一,我們可以將 num_epochs 設定為 50,將 gen_epoch 設定為 10 來平衡它。接下來,我們重新運行配置單元以更新參數,上傳 Reddit 數據文件,並且重新訓練模型。

最終的模型比莎士比亞戲劇模型訓練得更好,以下是在溫度為 1.0 的條件下生成的一些 Reddit 文章標題:

report : 49 % of americans now believe all of the country 』 s effective

people like facebook like it ' s 650 of 1 %

uber accused of secretly - security popular service ( likely oklahoma )

equifax breach fallout : your salary is dead

sanders uses texas shooter ' s iphone sales

adobe videos will be used to sell the web

apple to hold cash for $ 500 service

fitbit just targeting solar energy

george bush ' s concept car 『 goes for all the biggest controversy .

後續工作

這些例子只是在短時間內訓練模型,作為 textfenrnn 快速學習的演示樣例,你可以通過不斷地增加 num_epochs 來進一步完善模型。然而,根據我的經驗,訓練單元在訓練進行 4 小時後會出現超時問題:你需要根據具體情況設定 num_epochs 參數,儘管在我的經驗裡,這是在網絡訓練收斂之前所需要做的工作。

事實上,我使用了這個 Colaboratory notebool 為/r/SubredditNN 訓練了許多模型,這個 Reddit 子板塊中只有文本生成神經網絡機器人是基於其他 subreddit 板塊數據訓練的。生成的結果非常有趣:

教程|如何快速訓練免費的文本生成神經網絡

儘管文本生成神經網絡目前還不能自行編寫完整的文章,但是仍然有很多機會可以使用它做一些有趣的事!得益於 textgenrnn,這種探索對於每個人來說都是很容易、快速並且划算的!


分享到:


相關文章: