人工智能Text Generation文本生成原理示例詳解
承上啟下
上一篇文章我們介紹了 RNN 相關(guān)的基礎(chǔ)知識(shí),現(xiàn)在我們介紹文本生成的基本原理,主要是為了能夠靈活運(yùn)用 RNN 的相關(guān)知識(shí),真實(shí)的文本生成項(xiàng)目在實(shí)操方面比這個(gè)要復(fù)雜,但是基本的原理是不變的,這里就是拋磚引玉了。
RNN 基礎(chǔ)知識(shí)回顧鏈接:http://www.dbjr.com.cn/article/228994.htm
原理
我們這里用到了 RNN 來進(jìn)行文本生成,其他的可以對(duì)時(shí)序數(shù)據(jù)進(jìn)行建模的模型都可以拿來使用,如 LSTM 等。這里假如已經(jīng)訓(xùn)練好一個(gè) RNN 模型來預(yù)測(cè)下一個(gè)字符,假如我們限定了輸入的長(zhǎng)度為為 21 ,這里舉例說明:
input:“the cat sat on the ma”
把 21 個(gè)字符的文本分割成字符級(jí)別的輸入,輸進(jìn)到模型中,RNN 來積累輸入的信息,最終輸出的狀態(tài)向量 h ,然后經(jīng)過全連接層轉(zhuǎn)換和 Softmax 分類器的分類,最終輸出是一個(gè)候選字符的概率分布。
在上面的例子中,輸入“the cat sat on the ma”,最后會(huì)輸出 26 個(gè)英文字母和其他若干用到的字符(如可能還有標(biāo)點(diǎn),空格等)的概率分布。
"a" --> 0.05 "b" --> 0.03 "c" --> 0.054 ... "t" --> 0.06 ... "," --> 0.01 "。" --> 0.04
此時(shí)預(yù)測(cè)的下一個(gè)字符“t”概率值最大,所以選擇“t”作為下一個(gè)字符,我們之后將“t”拼接到“the cat sat on the ma”之后得到“the cat sat on the mat”,然后我們?nèi)『?21 個(gè)字符“he cat sat on the mat”,輸入到模型中
input:“he cat sat on the mat”
此時(shí)加入預(yù)測(cè)下一個(gè)字符的概率分布中“。”的概率最大,我們就取“。”拼接到“the cat sat on the mat”之后,得到“the cat sat on the mat。”,如果還需要繼續(xù)進(jìn)行下去,則不斷重復(fù)上面的過程。如果我們的文本生成要求到此結(jié)束,則最終得到了文本
the cat sat on the mat。
通常我們要用和目標(biāo)相同的數(shù)據(jù)進(jìn)行訓(xùn)練。如想生成詩詞,就用唐詩宋詞去訓(xùn)練模型,像生成歌詞,就用周杰倫的歌詞去訓(xùn)練。
選取預(yù)測(cè)的下一個(gè)字符的三種方式
一般在得到概率分布,然后去預(yù)測(cè)下一個(gè)字符的時(shí)候,會(huì)有三種方法。
第一種方法就是像上面提到的,選擇概率分布中概率最大的字符即可。這種方法雖然最簡(jiǎn)單,但是效果并不是最好的,因?yàn)閹缀躅A(yù)測(cè)字符都是確定的,但是不能達(dá)到多元化的有意思的字符結(jié)果。公式如下:
next_index = np.argmax(pred)
第二種方法會(huì)從多項(xiàng)分布中隨機(jī)抽樣,預(yù)測(cè)成某個(gè)字符的概率為多少,則它被選取當(dāng)作下一個(gè)字符的概率就是多少。在實(shí)際情況中往往概率分布中的值都很小,而且很多候選項(xiàng)的概率相差不大,這樣大家被選擇的概率都差不多,下一個(gè)字符的預(yù)測(cè)隨機(jī)性就很強(qiáng)。假如我們得到預(yù)測(cè)成某個(gè)正確字符的概率為 0.1 ,而預(yù)測(cè)成其他幾個(gè)字符的概率也就只是稍微低于 0.1 ,那么這幾個(gè)字符被選取當(dāng)作下一個(gè)字符的概率都很相近。這種方式過于隨機(jī),生成的文本的語法和拼寫錯(cuò)誤往往很多。公式如下:
next_onehot = np.random.multimomial(1, pred, 1) next_index = np.argmax(next_onehot)
第三種方法是介于前兩種方法之間的一種,生成的下一個(gè)字符具有一定的隨機(jī)性,但是隨機(jī)性并不大,這要靠 temperature 參數(shù)進(jìn)行調(diào)節(jié), temperature 是在 0 到 1 之間的小數(shù),如果為 1 則和第一種方法相同,如果為其他值則可以將概率進(jìn)行不同程度的放大,這表示概率大的字符越大概率被選取到,概率小的字符越小概率被選擇到,這樣就可以有明顯的概率區(qū)分度,這樣就不會(huì)出現(xiàn)第二種方法中的情況。公式如下所示:
pred = pred ** (1/temperature) pred = pred / np.sum(pred)
訓(xùn)練
假如我們有一句話作為訓(xùn)練數(shù)據(jù),如下:
Machine learning is a subset of artificial intelligence.
我們?cè)O(shè)置兩個(gè)參數(shù) len = 5 和 stride = 3 ,len 是輸入長(zhǎng)度,stride 是步長(zhǎng),我們將輸入 5 個(gè)字符作為輸入,然后輸入下一個(gè)字符作為標(biāo)簽,如下
input:“Machi” target:“n”
然后因?yàn)槲覀冊(cè)O(shè)置了 stride 為 3 ,所以我們?cè)谖谋局邢蛴移揭?3 位,然后又選擇 5 個(gè)字符作為輸入,之后的一個(gè)字符作為標(biāo)簽,如下:
input:“hine ” target:“l(fā)”
如此往復(fù),不斷向右平移 3 個(gè)字符,將新得到的 5 個(gè)字符和接下來的 1 個(gè)字符作為標(biāo)簽作為訓(xùn)練數(shù)據(jù)輸入到模型中,讓模型學(xué)習(xí)文本內(nèi)部的特征。其實(shí)訓(xùn)練數(shù)據(jù)就是(字符串,下一個(gè)字符)的鍵值對(duì)。此時(shí)得到的所有訓(xùn)練數(shù)據(jù)為:
input:'Machi' target:'n' input:'hine ' target:'l' input:'e lea' target:'r' ... input:'ligen' target:'c'
然后用這些訓(xùn)練數(shù)據(jù)進(jìn)行大量的訓(xùn)練得到的模型,就可以用來生成新的文本啦!。
總結(jié)
訓(xùn)練模型的流程大致需要三個(gè)過程:
1.將訓(xùn)練數(shù)據(jù)整理成(segment,next_char)的組合
2.用 one-hot 將字符編碼,segment 編碼成 l*v 的向量,next_char 編碼成 v*1 的向量,l 是輸入長(zhǎng)度,v 是字符總個(gè)數(shù)
3.構(gòu)建一個(gè)網(wǎng)絡(luò),輸入是 l*v 的矩陣,然后通過 RNN 或者 LSTM 捕捉文本特征,然后將最后的特征進(jìn)行全連接層進(jìn)行轉(zhuǎn)換,全連接層用 Softmax 作為激活函數(shù),最后輸出一個(gè) v*1 的概率分布,下一個(gè)字符的選擇方式可以看上面的內(nèi)容。
生成文本的流程大致需要三個(gè)過程:
一般在已經(jīng)訓(xùn)練好模型的情況下,我們要輸入字符串當(dāng)作種子輸入,讓其作為我們接下來要生成文本的開頭,然后不斷重復(fù)下面的過程:
- a)把輸入使用 one-hot 向量表示,然后輸入到模型中
- b)在神經(jīng)網(wǎng)絡(luò)輸出的概率分布中選取一個(gè)字符,作為預(yù)測(cè)的下一個(gè)字符
- c)將預(yù)測(cè)的字符拼接到之前的文本后,選取新的輸入文本
案例
這里有我之前實(shí)現(xiàn)的兩個(gè)小案例,可以用來復(fù)習(xí) RNN 和 LSTM 的相關(guān)知識(shí),覺好留贊。
深度學(xué)習(xí)TextRNN的tensorflow1.14實(shí)現(xiàn)示例
深度學(xué)習(xí)TextLSTM的tensorflow1.14實(shí)現(xiàn)示例
另外 github 上也有很多開源的文本生成項(xiàng)目,項(xiàng)目實(shí)現(xiàn)要稍微復(fù)雜一點(diǎn),但是原理和我介紹的一樣,我這里介紹兩個(gè)。
https://github.com/stardut/Text-Generate-RNN
https://github.com/wandouduoduo/SunRnn
以上就是Text Generation文本生成原理示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Text Generation文本生成的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
簡(jiǎn)單了解python PEP的一些知識(shí)
這篇文章主要介紹了簡(jiǎn)單了解python PEP的一些知識(shí),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07教你使用Python的pygame模塊實(shí)現(xiàn)拼圖游戲
pygame模塊是一個(gè)可以跨平臺(tái)的模塊,其設(shè)計(jì)目的就是為電子游戲而設(shè)計(jì),能夠支持圖片和聲音,下面這篇文章主要給給大家介紹了關(guān)于使用Python的pygame模塊實(shí)現(xiàn)拼圖游戲的相關(guān)資料,需要的朋友可以參考下2022-07-07PyQt5實(shí)現(xiàn)下載進(jìn)度條效果
這篇文章主要為大家詳細(xì)介紹了PyQt5實(shí)現(xiàn)下載進(jìn)度條效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Python數(shù)據(jù)處理之savetxt()和loadtxt()使用詳解
這篇文章主要介紹了Python數(shù)據(jù)處理之savetxt()和loadtxt()使用詳解,NumPy提供了多種存取數(shù)組內(nèi)容的文件操作函數(shù),保存數(shù)組數(shù)據(jù)的文件可以是二進(jìn)制格式或者文本格式,今天我們來看看savetxt()和loadtxt()的用法,需要的朋友可以參考下2023-08-08Python趣味挑戰(zhàn)之pygame實(shí)現(xiàn)無敵好看的百葉窗動(dòng)態(tài)效果
最近寫了很多期關(guān)于pygame的案例和知識(shí)點(diǎn),自己也收獲了很多知識(shí),也在這個(gè)過程中成長(zhǎng)了不少, 這次還是圍繞surface對(duì)象進(jìn)行詳細(xì)介紹,并形成完整的案例過程,文中有非常詳細(xì)實(shí)現(xiàn)百葉窗動(dòng)態(tài)效果的代碼示例,需要的朋友可以參考下2021-05-05python獲取文件版本信息、公司名和產(chǎn)品名的方法
這篇文章主要介紹了python獲取文件版本信息、公司名和產(chǎn)品名的方法,是Python程序設(shè)計(jì)中非常實(shí)用的技巧,需要的朋友可以參考下2014-10-10Python實(shí)現(xiàn)設(shè)置顯示屏分辨率
這篇文章主要為大家詳細(xì)介紹了Python如何調(diào)用win32庫實(shí)現(xiàn)分辨率獲取和讀寫,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考下2023-01-01Pytorch如何打印與Keras的model.summary()類似的輸出(最新推薦)
這篇文章主要介紹了Pytorch如何打印與Keras的model.summary()類似的輸出,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07