在過去的幾年中,自然語(yǔ)言處理(NLP)有了顯著的增長(zhǎng),這要?dú)w功于深度學(xué)習(xí)算法的進(jìn)步和足夠的計(jì)算能力。但是,前饋神經(jīng)網(wǎng)絡(luò)不被認(rèn)為是對(duì)語(yǔ)言或文本建模的最佳選擇。這是因?yàn)榍梆伨W(wǎng)絡(luò)未考慮文本中的單詞順序。
因此,為了捕獲文本中存在的順序信息,在NLP中使用了遞歸神經(jīng)網(wǎng)絡(luò)。在本文中,我們將了解如何使用PyTorch生成自然語(yǔ)言,使用遞歸神經(jīng)網(wǎng)絡(luò)(LSTM)。
自然語(yǔ)言生成(NLG)是自然語(yǔ)言處理(NLP)的子字段,它與計(jì)算機(jī)自動(dòng)生成人類可讀文本有關(guān)。NLG可用于各種NLP任務(wù),例如機(jī)器翻譯,語(yǔ)音轉(zhuǎn)文本,聊天機(jī)器人,文本自動(dòng)更正或文本自動(dòng)完成。
我們可以借助語(yǔ)言建模為NLG建模。讓我解釋一下語(yǔ)言模型的概念–語(yǔ)言模型學(xué)會(huì)預(yù)測(cè)單詞序列的概率。例如,考慮以下句子:
我們可以看到,第一句話比第二句話更有可能,因?yàn)槲覀冎赖诙湓捴械膯卧~順序是不正確的。這是語(yǔ)言建模背后的基本概念。語(yǔ)言模型應(yīng)該能夠區(qū)分較高可能性的單詞(或標(biāo)記)序列。
以下是兩種類型的語(yǔ)言模型:
統(tǒng)計(jì)語(yǔ)言模型: 這些模型使用傳統(tǒng)的統(tǒng)計(jì)技術(shù),例如N-gram,隱馬爾可夫模型(HMM)和某些語(yǔ)言規(guī)則來(lái)學(xué)習(xí)單詞的概率分布。神經(jīng)語(yǔ)言模型: 這些模型的有效性已經(jīng)超過統(tǒng)計(jì)語(yǔ)言模型。他們使用不同種類的神經(jīng)網(wǎng)絡(luò)對(duì)語(yǔ)言進(jìn)行建模。
首先,讓我們看看如何在統(tǒng)計(jì)模型(如N-Gram模型)的幫助下生成文本。
假設(shè)我們必須為下面的句子生成下一個(gè)單詞:
假設(shè)我們的N-Gram模型考慮3個(gè)前一個(gè)詞的上下文只是為了預(yù)測(cè)下一個(gè)詞。因此,模型將嘗試使概率P(w |“它建立了a”)最大化,其中“ w”代表文本數(shù)據(jù)集中的每個(gè)單詞。將使該概率最大化的單詞將作為句子“她在那里建…”的下一個(gè)單詞生成。
然而,使用這樣的統(tǒng)計(jì)模型存在某些缺點(diǎn),該統(tǒng)計(jì)模型使用直接的前一個(gè)單詞作為上下文來(lái)預(yù)測(cè)下一個(gè)單詞。讓我給您一些額外的背景信息。
現(xiàn)在,我們獲得了有關(guān)正在發(fā)生的事情的更多信息。“沙堡”一詞很可能是下一個(gè)詞,因?yàn)樗鼘?duì)“海灘”一詞有很強(qiáng)的依賴性,因?yàn)槿藗冊(cè)诖蠖鄶?shù)正確的海灘上建造沙堡。因此,重點(diǎn)是,“沙堡”并不取決于當(dāng)前環(huán)境(“她建造了”),而是取決于“海灘”。
為了捕獲序列標(biāo)記之間的這種無(wú)限制的依賴性,我們可以使用基于RNN / LSTM的語(yǔ)言模型。以下是我們將用于NLG的語(yǔ)言模型的簡(jiǎn)約表示:
x1,x2和x3分別是時(shí)間步1,時(shí)間步2和時(shí)間步3的輸入單詞嵌入?1,?2和?3是訓(xùn)練數(shù)據(jù)集中所有不同標(biāo)記的概率分布y1,y2和y3是基本真值U,V和W是權(quán)重矩陣H0,H1,H2和H3是隱藏狀態(tài)
我們將嘗試從三個(gè)階段來(lái)了解神經(jīng)語(yǔ)言模型的功能:
資料準(zhǔn)備模型訓(xùn)練文字產(chǎn)生
假設(shè)我們將下面的句子用作訓(xùn)練數(shù)據(jù)。
[“好吧,完美”,
“聽起來(lái)不錯(cuò)”,
“差價(jià)是多少”]
第一句話有4個(gè)記號(hào),第二句話有3個(gè)記號(hào),第三個(gè)句子有5個(gè)記號(hào)。因此,所有這些句子在記號(hào)方面都有不同的長(zhǎng)度。LSTM模型只接受長(zhǎng)度相同的序列作為輸入。因此,我們必須使訓(xùn)練數(shù)據(jù)中的序列具有相同的長(zhǎng)度。
有多種技術(shù)可以使序列長(zhǎng)度相等。
一種技術(shù)是填充。我們可以在需要時(shí)使用填充令牌填充序列。但是,如果使用此技術(shù),則在損失計(jì)算和文本生成期間將不得不處理填充令牌。
因此,我們將使用另一種技術(shù),該技術(shù)涉及在不使用任何填充令牌的情況下將一個(gè)序列分成多個(gè)等長(zhǎng)的序列。該技術(shù)還增加了訓(xùn)練數(shù)據(jù)的大小。讓我將其應(yīng)用于我們的訓(xùn)練數(shù)據(jù)。
假設(shè)我們希望序列具有三個(gè)標(biāo)記。然后,第一個(gè)序列將分為以下序列:
['好吧,就是'
完美']
第二個(gè)序列的長(zhǎng)度僅為三,因此不會(huì)被拆分。但是,訓(xùn)練數(shù)據(jù)的第三個(gè)序列具有五個(gè)令牌,它將被分解為多個(gè)令牌序列:
['什么是',
'價(jià)格是',
'價(jià)格差']
現(xiàn)在,新數(shù)據(jù)集將如下所示:
['好吧就是',
'就是完美',
'聽起來(lái)很棒',
'什么是',
'就是價(jià)格',
'價(jià)格差']
由于我們要解決下一個(gè)單詞生成問題,因此目標(biāo)應(yīng)該是輸入單詞的下一個(gè)單詞。例如,考慮第一個(gè)文本序列“正確”。
對(duì)于我們訓(xùn)練數(shù)據(jù)的第一個(gè)序列,模型的輸入為“正確”和“那個(gè)”,相應(yīng)的目標(biāo)標(biāo)記為“那個(gè)”和“是”。因此,在開始訓(xùn)練過程之前,我們將必須將數(shù)據(jù)集中的所有序列拆分為輸入和目標(biāo),如下所示:
因此,“輸入”和“目標(biāo)”下的這些序列對(duì)是將傳遞給模型的訓(xùn)練示例,訓(xùn)練示例的損失將是每個(gè)時(shí)間步的損失平均值。
讓我們看看如何將此模型用于文本生成。
一旦我們的語(yǔ)言模型得到訓(xùn)練,我們便可以將其用于NLG。想法是傳遞一個(gè)文本字符串作為輸入,以及模型要在輸入文本字符串之后生成的許多標(biāo)記。例如,如果用戶傳遞“ what is”作為輸入文本,并指定該模型應(yīng)生成2個(gè)令牌,則該模型可能會(huì)生成“ what’s going”或“ what is your name”或任何其他序列。
讓我借助一些插圖展示它是如何發(fā)生的:
輸入文字=“什么是”
n=2
步驟1 –輸入文本的第一個(gè)標(biāo)記(“ what”)傳遞給訓(xùn)練后的LSTM模型。它產(chǎn)生一個(gè)輸出?1,我們將忽略它,因?yàn)槲覀円呀?jīng)知道第二個(gè)標(biāo)記(“ is”)。該模型還生成隱藏狀態(tài)H1,該狀態(tài)將傳遞到下一個(gè)時(shí)間步。
步驟2 –然后將第二個(gè)令牌(“ is”)與H1一起在時(shí)間步驟2傳遞到模型。在此時(shí)間步長(zhǎng)處的輸出是概率分布,其中令牌“ going”具有最大值。因此,我們將其視為模型首次生成或預(yù)測(cè)的令牌?,F(xiàn)在我們還有一個(gè)令牌可以生成。
步驟3 –為了生成下一個(gè)令牌,我們需要在時(shí)間步驟3將輸入令牌傳遞給模型。但是,我們用完了輸入令牌,“ is”是生成“ going”的最后一個(gè)令牌。那么,接下來(lái)我們要傳遞什么作為輸入呢?在這種情況下,我們將傳遞先前生成的令牌作為輸入令牌。
該模型的最終輸出將是“正在發(fā)生什么”。這就是我們將用于執(zhí)行NLG的文本生成策略。接下來(lái),我們將在電影情節(jié)摘要的數(shù)據(jù)集中訓(xùn)練自己的語(yǔ)言模型。
現(xiàn)在我們知道了神經(jīng)語(yǔ)言模型是如何工作的以及需要什么樣的數(shù)據(jù)預(yù)處理,讓我們訓(xùn)練一個(gè)LSTM語(yǔ)言模型以使用PyTorch執(zhí)行自然語(yǔ)言生成。
讓我們快速導(dǎo)入必要的庫(kù)。
我們將使用CMU電影摘要語(yǔ)料庫(kù)的樣本。
你可以使用下面的代碼打印五份摘要,這些摘要是隨機(jī)抽樣的。
#個(gè)樣本隨機(jī)摘要
random.sample(movie_plots,5)
首先,我們將稍微清除文本。我們將僅保留字母和撇號(hào)標(biāo)點(diǎn)符號(hào),并從文本中刪除其余的其他元素。
?。8蓛舻奈淖?/p>
movie_plots=[re.sub(“ [^ az']”,“”,i)for movie_plots中的i]
不必執(zhí)行此步驟。只是我希望我的模型僅關(guān)注字母,而不必?fù)?dān)心標(biāo)點(diǎn)符號(hào)或數(shù)字或其他符號(hào)。
接下來(lái),我們將定義一個(gè)函數(shù)以從數(shù)據(jù)集中準(zhǔn)備定長(zhǎng)序列。我已指定序列的長(zhǎng)度為五。它是一個(gè)超參數(shù),您可以根據(jù)需要更改它。
因此,我們會(huì)將電影情節(jié)摘要傳遞給此函數(shù),并且它將為每個(gè)輸入返回固定長(zhǎng)度序列的列表。
輸出: 152644
一旦準(zhǔn)備好相同長(zhǎng)度的序列,就可以將它們進(jìn)一步分為輸入序列和目標(biāo)序列。
現(xiàn)在我們必須將這些序列(x和y)轉(zhuǎn)換為整數(shù)序列,但是在此之前,我們將必須將數(shù)據(jù)集中的每個(gè)不同的單詞映射為一個(gè)整數(shù)值。因此,我們將為令牌字典創(chuàng)建一個(gè)令牌,并為令牌字典創(chuàng)建一個(gè)整數(shù)。
輸出:(14271,'the')
?。TO(shè)置詞匯量
vocab_size=len(int2token)
vocab_size
輸出: 16592
詞匯量為16,592,即我們的游戲下載數(shù)據(jù)集中有超過16,000個(gè)不同的標(biāo)記。
一旦我們有了令牌到整數(shù)的映射,就可以將文本序列轉(zhuǎn)換為整數(shù)序列。
我們將批次的輸入序列和目標(biāo)序列傳遞給模型,因?yàn)樽詈檬前磁芜M(jìn)行訓(xùn)練,而不是一次將整個(gè)數(shù)據(jù)傳遞給模型。以下功能將從輸入數(shù)據(jù)創(chuàng)建批次。
現(xiàn)在,我們將定義語(yǔ)言模型的體系結(jié)構(gòu)。
輸入序列將首先通過嵌入層,然后通過LSTM層。LSTM層將提供一組與序列長(zhǎng)度相等的輸出,并且這些輸出中的每一個(gè)都將傳遞到線性(密集)層,在該層上將應(yīng)用softmax。
輸出:
WordLSTM(
(emb_layer):嵌入(16592,200)
?。╨stm):LSTM(200,256,num_layers=4,batch_first=True,dropout=0.3)
?。╠ropout ):Dropout(p=0.3,inplace=False)
?。╢c ):線性(in_features=256,out_features=16592,bias=True)
?。?/p>
現(xiàn)在讓我們定義一個(gè)用于訓(xùn)練模型的函數(shù)。
?。S?xùn)練模型
火車(凈額,batch_size = 32,歷元= 20,print_every = 256)
我已將批次大小指定為32,并將訓(xùn)練模型20個(gè)時(shí)間段。訓(xùn)練可能需要一段時(shí)間。
訓(xùn)練模型后,我們可以將其用于文本生成。請(qǐng)注意,此模型可以一次生成一個(gè)單詞,并帶有隱藏狀態(tài)。因此,要生成下一個(gè)單詞,我們將必須使用此生成的單詞和隱藏狀態(tài)。
函數(shù)sample()從用戶處輸入一個(gè)輸入文本字符串(“ prime”),并指定一個(gè)數(shù)字(“ size”),該數(shù)字指定要生成的令牌數(shù)量。在給定輸入單詞和隱藏狀態(tài)的情況下,sample()使用predict()函數(shù)預(yù)測(cè)下一個(gè)單詞。下面給出了由模型生成的一些文本序列。
樣本(凈值,15)
輸出:
“現(xiàn)在由他們擁有新福音的圣殿負(fù)責(zé),并關(guān)押他”
樣本(凈值15,素?cái)?shù)=“其中之一”)
輸出:
``其中一個(gè)團(tuán)隊(duì)正在等待他的拒絕,并把他扔進(jìn)對(duì)sannokai的拒絕中''
樣本(凈值15,素?cái)?shù)=“盡快”)
輸出:
“一旦他被派去做不是他嘴上造成的普通戰(zhàn)士”
樣本(凈值15,素?cái)?shù)=“他們”)
輸出:
“他們發(fā)現(xiàn)自己以被扔進(jìn)船的方式被扔進(jìn)了船上”
自然語(yǔ)言生成是一個(gè)快速成熟的領(lǐng)域,并且是越來(lái)越活躍的研究領(lǐng)域。從N-Gram模型到RNN / LSTM模型,用于NLG的方法也已走了很長(zhǎng)一段路,現(xiàn)在基于變壓器的模型已成為該領(lǐng)域的最新技術(shù)。
總而言之,在本文中,涵蓋了許多與NLG相關(guān)的內(nèi)容,例如數(shù)據(jù)集準(zhǔn)備,如何訓(xùn)練神經(jīng)語(yǔ)言模型以及最終在PyTorch中進(jìn)行自然語(yǔ)言生成過程。我建議大家嘗試在更大的數(shù)據(jù)集上構(gòu)建語(yǔ)言模型,并查看它生成什么樣的文本。
聯(lián)系客服