第一天搭建文字生成器網頁就上手

Watson Wang
Jul 16, 2021

--

之前在剛接觸機器學習時,有次點擊了一個網站:讓 AI 寫點金庸:如何用 TensorFlow 2.0 及 TensorFlow.js 寫天龍八部,懵懂無知的我看到網頁裡面那個金庸文章生成器是直接被震懾住的,過了一陣子稍微理解一些些NLP (natural language process)小基礎後,今天就來跟著這篇文章做做看吧~

網頁demo效果截圖

素材發想

第一部肯定是這個的,我第一個想法是我希望能寫出一個散文生成器,之後如果拿這東西丟散文比賽投稿然後不小心得獎一定超好笑的。

那我就在網路上開始找一些線上閱讀網頁啊之類的,然後開始亂丟一些關鍵字,很幸運的,在我把腦中已知不多的作家名字耗盡之前,我找到了這個酷東東:簡媜散文集,就決定是這個了!

文字前處理

大概抓了40篇散文下來作為我們的文字資料集,這邊很簡單的做一些小小的前處理:純粹的換行跟一些奇怪的符號去掉,只留下純文字跟逗號句號。可以看一下我最後附上的github程式碼裡面。喔對了,這邊的素材是簡體字,如果讀者可以在找其他素材做訓練的時候注意一下。

# 簡單建立一個tokenizertokenizer = tf.keras.preprocessing.text.Tokenizer( num_words=num_words, char_level=True, filters='')

這個tokenizer裡面會有一個diction方便我們將文字跟數字轉換,轉換成數字的目的是方便我們做機器學習訓練,有興趣可以去 Haren Lin 那邊更深入瞭解一些NLP的概念。

文字轉換

那再來是切分文字集,藉由將文字切成長度各為11的字串們,然後每段再取其前十個字跟後10個字來當作x,y值訓練,這樣講可能有點抽象,我們舉個例子來看,如果今天有一個長度11的字串其轉成數字表示為:[1,2,3,4,5,6,7,8,9,10,11],那我們定義其中的x為[1,2,3,4,5,6,7,8,9,10],而y則為[2,3,4,5,6,7,8,9,10,11],這樣我們模型就會學到說在輸入前十個字後,最應該輸出哪一個字(也就是例子裡的11)。

模型訓練

然後就到我們最喜愛的部分拉,訓練模型,這邊我們使用colab訓練以避免自己電腦燒壞XD,請務必記得開GPU,我們簡單建立Embedding + LSTM + FCN(3111是文章裡面出現過的不同文字數量)各一層的模型來簡單看一下訓練效果。

model architecture

因為訓練一遍還蠻快的,應該是因為我抓下來的文字量本身不多,所以這邊就給他訓練個400epoch。

記得將模型存檔,這會是以後我們網頁上呈現模型demo的重要元件。

那現在有一個技術問題來了,我們剛剛訓練的是輸入長度10,輸出10的模型對吧,但如果我們想讓使用者能夠自己選定輸入長度的話,我們就會希望模型能夠輸入一個字元,吐出另一個字元,然後再拿這字元繼續丟回去,直到達到使用者想要的長度為止~

這件事其實也不算難,我們就重新建立一個一模一樣的模型但這次把batchsize改為1(一次只會輸入一句話),然後讀入我們剛剛存好的權重,模型的部分就搞定拉!

測試效果

我們的模型不是單純像一般分類器一樣選擇softmax後最高的那個字最輸出,而是每個字最後都有一個機率,讓程式隨機挑選,當然數值高的就比較可能會選到,但也有可能後面會接一個讓你想不到的字,在開頭你會注意到說有一個溫度的選項,那就是用來讓文字機率差距提高的數字,溫度越高,生成的文字就越不可掌握。

那我們先手動測試看看,假設要生成500字,然後起始字是「他拿起刀說」,給予隨機度0.23。

生成文章

看看這個神奇的小東西,好像有點邏輯,仔細一看還真不通順,但已經有那個寫作風格出現了,著實令人欣慰。

架設網頁

那緊接著讓我們來處理網頁吧~這邊我剛好之前有做過一個小型的Flask網頁(真巧),但之前是做圖片輸入,然後輸出確診機率的,我們拿之前作品(有興趣可以參考:🔗文章跟🔗程式碼)來小改一下。

我們會在網頁初始化時做兩件事情,第一步,把文章掃過一遍,建立文字轉數字word2num (丟進模型)跟數字轉文字num2word(網頁呈現)兩個diction,第二件事就是重建模型並把訓練權重load好。

有這兩個class,我們就能在網頁初始化時把這兩件事做好,有了背後的計算支持,讓我們來看看前端,一定要有3個input對吧~分別是初始文字,欲生成文章長度,跟溫度(隨機度)。

讓我們看看效果,不錯不錯,在沒有css下差強人意。

後端我們用flask接起來~並做一些防呆處理避免被使用者玩到網頁crash,像是數字型別的確認跟長度限制之類的。

最後的最後,當然是在測試一下效果,看一下有沒有什麼錯誤跳出來。

字串:到了山腰/ 文字長度:100/ 隨機度:0.3

看來沒什麼問題,那今天就先到這邊拉~有興趣可以follow我跟底下🖐,偶爾實作偶爾看看論文的紀錄過程。

題外話,本來想讓這網頁上線的,但模型要100M,tensorflow環境要450M,直接超過Heroku免費帳號的大小限制(500M),只好之後再看看。

source

Github(詳讀README)

更詳細的實作內容

--

--