? ? ? ? ? ? ? ? ? ? ? ? ? ? ? RNN在自然語(yǔ)言處理中的應(yīng)用及其PyTorch實(shí)現(xiàn)
姓名:余玥 ? ? 學(xué)號(hào):16010188033
轉(zhuǎn)載自http://blog.csdn.net/qq_40027052/article/details/78652311,有刪節(jié)齐蔽。
【嵌牛導(dǎo)讀】:對(duì)于人類而言秩仆,以前見(jiàn)過(guò)的事物會(huì)在腦海里面留下記憶唇牧,雖然隨后記憶會(huì)慢慢消失铅檩,但是每當(dāng)經(jīng)過(guò)提醒仗颈,人們往往能夠重拾記憶刻盐。在神經(jīng)網(wǎng)絡(luò)的研究中,讓模型充滿記憶力的研究很早便開(kāi)始了蠢箩,Saratha Sathasivam 于1982 年提出了霍普菲爾德網(wǎng)絡(luò)链蕊,但是由于它實(shí)現(xiàn)困難,在提出的時(shí)候也沒(méi)有很好的應(yīng)用場(chǎng)景谬泌,所以逐漸被遺忘滔韵。深度學(xué)習(xí)的興起又讓人們重新開(kāi)始研究循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network),并在序列問(wèn)題和自然語(yǔ)言處理等領(lǐng)域取得很大的成功掌实。
【嵌牛鼻子】:循環(huán)神經(jīng)網(wǎng)絡(luò)/Recurrent Neural Network/PyTorch/自然語(yǔ)言處理
【嵌牛提問(wèn)】:RNN在自然語(yǔ)言處理中的應(yīng)用有哪些陪蜻?PyTorch如何實(shí)現(xiàn)RNN的應(yīng)用?
【嵌牛正文】:
本文將從循環(huán)神經(jīng)網(wǎng)絡(luò)的基本結(jié)構(gòu)出發(fā)贱鼻,介紹RNN在自然語(yǔ)言處理中的應(yīng)用及其PyTorch 實(shí)現(xiàn)宴卖。
前一章介紹了卷積神經(jīng)網(wǎng)絡(luò)滋将,卷積神經(jīng)網(wǎng)絡(luò)相當(dāng)于人類的視覺(jué),但是它并沒(méi)有記憶能力症昏,所以它只能處理一種特定的視覺(jué)任務(wù)耕渴,沒(méi)辦法根據(jù)以前的記憶來(lái)處理新的任務(wù)。那么記憶力對(duì)于網(wǎng)絡(luò)而言到底是不是必要的呢齿兔?很顯然在某些問(wèn)題上是必要的,比如础米,在一場(chǎng)電影中推斷下一個(gè)時(shí)間點(diǎn)的場(chǎng)景分苇,這個(gè)時(shí)候僅依賴于現(xiàn)在的情景并不夠,需要依賴于前面發(fā)生的情節(jié)屁桑。對(duì)于這樣一些不僅依賴于當(dāng)前情況医寿,還依賴于過(guò)去情況的問(wèn)題,傳統(tǒng)的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)無(wú)法很好地處理蘑斧,所以基于記憶的網(wǎng)絡(luò)模型是必不可少的靖秩。
循環(huán)神經(jīng)網(wǎng)絡(luò)的提出便是基于記憶模型的想法,期望網(wǎng)絡(luò)能夠記住前面出現(xiàn)的特征竖瘾,并依據(jù)特征推斷后面的結(jié)果沟突,而且整體的網(wǎng)絡(luò)結(jié)構(gòu)不斷循環(huán),因?yàn)榈妹h(huán)神經(jīng)
網(wǎng)絡(luò)捕传。
循環(huán)神經(jīng)網(wǎng)絡(luò)的基本結(jié)構(gòu)
循環(huán)神經(jīng)網(wǎng)絡(luò)的基本結(jié)構(gòu)特別簡(jiǎn)單惠拭,就是將網(wǎng)絡(luò)的輸出保存在一個(gè)記憶單元中,這個(gè)記憶單元和下一次的輸入一起進(jìn)入神經(jīng)網(wǎng)絡(luò)中庸论。使用一個(gè)簡(jiǎn)單的兩層網(wǎng)絡(luò)作為示范职辅,在它的基礎(chǔ)上擴(kuò)充為循環(huán)神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu),我們用圖1簡(jiǎn)單地表示聂示。
可以看到網(wǎng)絡(luò)在輸入的時(shí)候會(huì)聯(lián)合記憶單元一起作為輸入域携,網(wǎng)絡(luò)不僅輸出結(jié)果,還會(huì)將結(jié)果保存到記憶單元中鱼喉,圖1就是一個(gè)最簡(jiǎn)單的循環(huán)神經(jīng)網(wǎng)絡(luò)在一次輸入時(shí)的結(jié)構(gòu)示意圖秀鞭。
輸入序列的順序改變, 會(huì)改變網(wǎng)絡(luò)的輸出結(jié)果,這是因?yàn)橛洃泦卧拇嬖谄研祝沟脙蓚€(gè)序列在順序改變之后記憶單元中的元素也改變了气筋,所以會(huì)影響最終的輸出結(jié)果。
圖1 將一個(gè)數(shù)據(jù)點(diǎn)傳入網(wǎng)絡(luò)
圖1是序列中一個(gè)數(shù)據(jù)點(diǎn)傳入網(wǎng)絡(luò)的示意圖旋圆,那么整個(gè)序列如何傳入網(wǎng)絡(luò)呢宠默?將序列中的每個(gè)數(shù)據(jù)點(diǎn)依次傳入網(wǎng)絡(luò)即可,如圖2所示灵巧。
圖2 將整個(gè)序列傳入網(wǎng)絡(luò)
無(wú)論序列有多長(zhǎng)搀矫,都能不斷輸入網(wǎng)絡(luò)抹沪,最終得到結(jié)果∪壳颍可能看到這里融欧,讀者會(huì)有一些疑問(wèn),圖2中每一個(gè)網(wǎng)絡(luò)是不是都是獨(dú)立的權(quán)重卦羡?對(duì)于這個(gè)問(wèn)題噪馏,先考慮一下如果是不同的序列,那么圖2 中格子的數(shù)目就是不同的绿饵,對(duì)于一個(gè)網(wǎng)絡(luò)結(jié)構(gòu)欠肾,不太可能出現(xiàn)這種參數(shù)數(shù)目變化的情況。
事實(shí)上拟赊,這里再次使用了參數(shù)共享的概念刺桃,也就是說(shuō)雖然上面有三個(gè)格子,其實(shí)它們都是同一個(gè)格子吸祟,而網(wǎng)絡(luò)的輸出依賴于輸入和記憶單元瑟慈,可以用圖5.5表示。
如圖5.5所示屋匕,左邊就是循環(huán)神經(jīng)網(wǎng)絡(luò)實(shí)際的網(wǎng)絡(luò)流葛碧,右邊是將其展開(kāi)的結(jié)果,可以看到網(wǎng)絡(luò)中具有循環(huán)結(jié)構(gòu)过吻,這也是循環(huán)神經(jīng)網(wǎng)絡(luò)名字的由來(lái)吹埠。同時(shí)根據(jù)循環(huán)神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)也可以看出它在處理序列類型的數(shù)據(jù)上具有天然的優(yōu)勢(shì),因?yàn)榫W(wǎng)絡(luò)本身就是一個(gè)序列結(jié)構(gòu)疮装,這也是所有循環(huán)神經(jīng)網(wǎng)絡(luò)最本質(zhì)的結(jié)構(gòu)缘琅。
圖3 網(wǎng)絡(luò)的輸入和記憶單元
循環(huán)神經(jīng)網(wǎng)絡(luò)也可以有很深的網(wǎng)絡(luò)層結(jié)構(gòu),如圖4所示廓推。
圖4 深層網(wǎng)絡(luò)結(jié)構(gòu)
可以看到網(wǎng)絡(luò)是單方向的刷袍,這代表網(wǎng)絡(luò)只能知道單側(cè)的信息,有的時(shí)候序列的信息不只是單邊有用樊展,雙邊的信息對(duì)預(yù)測(cè)結(jié)果也很重要呻纹,比如語(yǔ)音信號(hào),這時(shí)候就需要看到兩側(cè)信息的循環(huán)神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)专缠。這并不需要用兩個(gè)循環(huán)神經(jīng)網(wǎng)絡(luò)分別從左右兩邊開(kāi)始讀取序列輸入雷酪,使用一個(gè)雙向的循環(huán)神經(jīng)網(wǎng)絡(luò)就能完成這個(gè)任務(wù),如圖5所示涝婉。
圖5 雙向循環(huán)神經(jīng)網(wǎng)絡(luò)
使用雙向循環(huán)神經(jīng)網(wǎng)絡(luò)哥力,網(wǎng)絡(luò)會(huì)先從序列的正方向讀取數(shù)據(jù),再?gòu)姆捶较蜃x取數(shù)據(jù),最后將網(wǎng)絡(luò)輸出的兩種結(jié)果合在一起形成網(wǎng)絡(luò)的最終輸出結(jié)果吩跋。
循環(huán)神經(jīng)網(wǎng)絡(luò)目前在自然語(yǔ)言處理中應(yīng)用最為火熱寞射,所以這一小節(jié)將介紹自然語(yǔ)言處理中如何使用循環(huán)神經(jīng)網(wǎng)絡(luò)。
詞嵌入
首先介紹自然語(yǔ)言處理中的第一個(gè)概念——詞嵌入(word embedding)锌钮,也可以稱為詞向量桥温。
圖像分類問(wèn)題會(huì)使用one-hot 編碼,比如一共有五類梁丘,那么屬于第二類的話侵浸,它的編碼就是(0, 1, 0, 0, 0),對(duì)于分類問(wèn)題氛谜,這樣當(dāng)然特別簡(jiǎn)明通惫。但是在自然語(yǔ)言處理中,因?yàn)閱卧~的數(shù)目過(guò)多混蔼,這樣做就行不通了,比如有10000 個(gè)不同的詞珊燎,那么使用one-hot這樣的方式來(lái)定義售滤,效率就特別低敛摘,每個(gè)單詞都是10000 維的向量,其中只有一位是1,其余都是0转捕,特別占用內(nèi)存。除此之外哨啃,也不能體現(xiàn)單詞的詞性号阿,因?yàn)槊恳粋€(gè)單詞都是one-hot,雖然有些單詞在語(yǔ)義上會(huì)更加接近芦瘾,但是one-hot 沒(méi)辦法體現(xiàn)這個(gè)特點(diǎn)捌蚊,所以必須使用另外一種方式定義每一個(gè)單詞,這就引出了詞嵌入近弟。
詞嵌入到底是什么意思呢缅糟?其實(shí)很簡(jiǎn)單,對(duì)于每個(gè)詞祷愉,可以使用一個(gè)高維向量去表示它窗宦,這里的高維向量和one-hot 的區(qū)別在于,這個(gè)向量不再是0 和1 的形式二鳄,向量的每一位都是一些實(shí)數(shù)赴涵,而這些實(shí)數(shù)隱含著這個(gè)單詞的某種屬性。這樣解釋可能不太直觀订讼,先舉四個(gè)例子髓窜,下面有4 段話:
(1)The cat likes playing ball.
(2)The kitty likes playing wool.
(3)The dog likes playing ball.
(4)The boy likes playing ball.
重點(diǎn)分析里面的4 個(gè)詞,cat欺殿、kitty纱烘、dog 和boy杨拐。如果使用one-hot,那么cat 就可以表示成(1, 0, 0, 0)擂啥,kitty 就可以表示成(0, 1, 0, 0)哄陶,但是cat 和kitty 其實(shí)都表示小貓,所以這兩個(gè)詞語(yǔ)義是接近的哺壶,但是one-hot 并不能體現(xiàn)這個(gè)特點(diǎn)屋吨。
下面使用詞嵌入的方式來(lái)表示這4 個(gè)詞,假如使用一個(gè)二維向量(a, b) 來(lái)表示一個(gè)詞山宾,其中a至扰,b 分別代表這個(gè)詞的一種屬性,比如a 代表是否喜歡玩球资锰,b 代表是否喜歡玩毛線敢课,并且這個(gè)數(shù)值越大表示越喜歡,這樣就能夠定義每一個(gè)詞的詞嵌入绷杜,并且通過(guò)這個(gè)來(lái)區(qū)分語(yǔ)義直秆,下面來(lái)解釋一下原因。
對(duì)于cat鞭盟,可以定義它的詞嵌入是(-1, 4)圾结,因?yàn)樗幌矚g玩球,喜歡玩毛線齿诉;而對(duì)于kitty筝野,它的詞嵌入可以定義為(-2, 5);那么對(duì)于dog粤剧,它的詞嵌入就是(3, -2)歇竟,因?yàn)樗矚g玩球,不喜歡玩毛線抵恋;最后對(duì)于boy途蒋,它的詞向量就是(-2, -3),因?yàn)檫@兩樣?xùn)|西他都不喜歡馋记。定義好了這樣的詞嵌入号坡,怎么去定義它們之間的語(yǔ)義相似度呢?可以通過(guò)詞向量之間的夾角來(lái)定義它們的相似度梯醒。下面先將每個(gè)詞向量都在坐標(biāo)系中表示出來(lái)宽堆,如圖6所示。
圖6 不同詞向量的夾角
圖6 就顯示出了不同詞向量之間的夾角茸习,可以發(fā)現(xiàn)kitty 和cat 的夾角更小畜隶,所以它們更加相似的,而dog 和boy 之間夾角很大,所以它們不相似籽慢。
通過(guò)這樣一個(gè)簡(jiǎn)單的例子能夠看出詞嵌入對(duì)于單詞的表示具有很好的優(yōu)勢(shì)浸遗,但是問(wèn)題來(lái)了,對(duì)于一個(gè)詞箱亿,怎么知道如何去定義它的詞嵌入跛锌?如果向量的維數(shù)只有5 維,可能還能定義出來(lái)届惋,如果向量的維數(shù)是100 維髓帽,那么怎么知道每一維體是多少呢?
這個(gè)問(wèn)題可以交給神經(jīng)網(wǎng)絡(luò)去解決脑豹,只需要定義我們想要的維度郑藏,比如100 維,神經(jīng)網(wǎng)絡(luò)就會(huì)自己去更新每個(gè)詞嵌入中的元素瘩欺。而之前介紹過(guò)詞嵌入的每個(gè)元素表示一種屬性必盖,當(dāng)然對(duì)于維數(shù)比較低的時(shí)候,可能我們能夠推斷出每一維具體的屬性含義俱饿,然而維度比較高之后歌粥,我們并不需要關(guān)心每一維到底代表著什么含義,因?yàn)槊恳痪S都是網(wǎng)絡(luò)自己學(xué)習(xí)出來(lái)的屬性稍途,只需要知道詞向量的夾角越小,表示它們之間的語(yǔ)義更加接近就可以了砚婆。這就好比卷積網(wǎng)絡(luò)會(huì)對(duì)一張圖片提取出很厚的特征圖械拍,并不需要關(guān)心網(wǎng)絡(luò)提取出來(lái)的特征到底是什么,只需要知道抽象的特征能夠幫助我們分類圖像就可以了装盯。
詞嵌入的PyTorch 實(shí)現(xiàn)
詞嵌入在PyTorch 中是如何實(shí)現(xiàn)的呢坷虑?下面來(lái)具體實(shí)現(xiàn)一下。
PyTorch 中的詞嵌入是通過(guò)函數(shù)nn.Embedding(m, n) 來(lái)實(shí)現(xiàn)的埂奈,其中m 表示所有的單詞數(shù)目迄损,n 表示詞嵌入的維度,下面舉一個(gè)例子:
上面就是輸出的hello 的詞嵌入账磺,下面來(lái)解釋一下代碼芹敌。首先需要給每個(gè)單詞建立一個(gè)對(duì)應(yīng)下標(biāo),這樣每個(gè)單詞都可以用一個(gè)數(shù)字去表示垮抗,比如需要hello 的時(shí)候氏捞,就可以用0來(lái)表示,用這種方式冒版,訪問(wèn)每個(gè)詞會(huì)特別方便液茎。接著是詞嵌入的定義nn.Embedding(2,5),如上面介紹過(guò)的,表示有兩個(gè)詞捆等,每個(gè)詞向量是5 維滞造,也就是一個(gè)2 * 5 的矩陣,只不過(guò)矩陣中的元素是可以被學(xué)習(xí)更新的栋烤,所以如果有1000 個(gè)詞谒养,每個(gè)詞向量希望是100 維,就可以這樣定義詞嵌入nn.Embedding(1000, 100)班缎。訪問(wèn)每一個(gè)詞的詞向量需要將tensor 轉(zhuǎn)換成Variable蝴光,因?yàn)樵~向量也是網(wǎng)絡(luò)中更新的參數(shù),所以在計(jì)算圖中达址,需要通過(guò)Variable 去訪問(wèn)蔑祟。另外這里的詞向量只是初始的詞向量,并沒(méi)有經(jīng)過(guò)學(xué)習(xí)更新沉唠,需要建立神經(jīng)網(wǎng)絡(luò)優(yōu)化更新疆虚,修改詞向量里面的參數(shù)使得詞向量能夠表示不同的詞,且語(yǔ)義相近的詞能夠有更小的夾角满葛。
以上介紹了詞嵌入在PyTorch 中是如何實(shí)現(xiàn)的径簿,下一節(jié)將介紹詞嵌入是如何更新的,以及它如何結(jié)合N Gram 語(yǔ)言模型進(jìn)行預(yù)測(cè)嘀韧。
N Gram 模型
首先介紹N Gram 模型的原理和它要解決的問(wèn)題篇亭。在一篇文章中,每一句話都是由很多單詞組成的锄贷,而且這些單詞的排列順序也是非常重要的译蒂。在一句話中,是否可以由前面幾個(gè)詞來(lái)預(yù)測(cè)這些詞后面的一個(gè)單詞谊却?比如在“I lived in France for 10 years, I can speak _ .”這句話中柔昼,我們希望能夠預(yù)測(cè)最后這個(gè)詞是French。
知道想要解決的問(wèn)題后炎辨,就可以引出N Gram 語(yǔ)言模型了捕透。對(duì)于一句話T,它由w1;w2;…wn 這n 個(gè)詞構(gòu)成碴萧,可以得到下面的公式:
但是這樣的一個(gè)模型存在著一些缺陷乙嘀,比如參數(shù)空間過(guò)大,預(yù)測(cè)一個(gè)詞需要前面所有的詞作為條件來(lái)計(jì)算條件概率破喻,所以在實(shí)際中沒(méi)辦法使用乒躺。為了解決這個(gè)問(wèn)題,引入了馬爾科夫假設(shè)低缩,也就是說(shuō)這個(gè)單詞只與前面的幾個(gè)詞有關(guān)系嘉冒,并不是和前面所有的詞都有關(guān)系曹货,有了這個(gè)假設(shè),就能夠在實(shí)際中使用N Gram 模型了讳推。
對(duì)于這個(gè)條件概率顶籽,傳統(tǒng)的方法是統(tǒng)計(jì)語(yǔ)料中每個(gè)單詞出現(xiàn)的頻率,據(jù)此來(lái)估計(jì)這個(gè)條件概率银觅,這里使用詞嵌入的辦法礼饱,直接在語(yǔ)料中計(jì)算這個(gè)條件概率,然后最大化條件概率從而優(yōu)化詞向量究驴,據(jù)此進(jìn)行預(yù)測(cè)镊绪。
單詞預(yù)測(cè)的PyTorch 實(shí)現(xiàn)
首先給出一段文章作為訓(xùn)練集:
CONTEXT_SIZE 表示想由前面的幾個(gè)單詞來(lái)預(yù)測(cè)這個(gè)單詞,這里設(shè)置為2洒忧,就是說(shuō)我們希望通過(guò)這個(gè)單詞的前兩個(gè)單詞來(lái)預(yù)測(cè)這一個(gè)單詞蝴韭,EMBEDDING_DIM 表示詞嵌入的維數(shù)。
接著建立訓(xùn)練集熙侍,遍歷所有語(yǔ)料來(lái)創(chuàng)建榄鉴,將數(shù)據(jù)整理好,需要將單詞分三個(gè)組蛉抓,每個(gè)組前兩個(gè)作為傳入的數(shù)據(jù)庆尘,而最后一個(gè)作為預(yù)測(cè)的結(jié)果。
將每個(gè)單詞編碼巷送,即用數(shù)字來(lái)表示每個(gè)單詞驶忌,只有這樣才能夠傳入nn.Embedding得到詞向量。
然后可以定義N Gram 模型如下:
模型需要傳入的參數(shù)有三個(gè)笑跛,分別是所有的單詞數(shù)付魔、預(yù)測(cè)單詞所依賴的單詞數(shù)、即CONTEXT_SIZE 和詞向量的維度堡牡。網(wǎng)絡(luò)在向前傳播中抒抬,首先傳入單詞得到詞向量杨刨,模型是根據(jù)前面兩個(gè)詞預(yù)測(cè)第三個(gè)詞的晤柄,所以需要傳入兩個(gè)詞,得到的詞向量是(2, 100)妖胀,然后將詞向量展開(kāi)成(1, 200)芥颈,接著經(jīng)過(guò)線性變換,經(jīng)過(guò)relu 激活函數(shù)赚抡,再經(jīng)過(guò)一個(gè)線性變換爬坑,輸出的維數(shù)是單詞總數(shù),最后經(jīng)過(guò)一個(gè)log softmax 激活函數(shù)得到概率分布涂臣,最大化條件概率盾计,可以用下面的公式表示:
在網(wǎng)絡(luò)的訓(xùn)練中售担,不僅會(huì)更新線性層的參數(shù),還會(huì)更新詞嵌入中的參數(shù)署辉,訓(xùn)練100次模型族铆,可以發(fā)現(xiàn)loss 已經(jīng)降到了0.37,也可以通過(guò)預(yù)測(cè)來(lái)檢測(cè)模型是否有效:
運(yùn)行上面的代碼哭尝,可以發(fā)現(xiàn)真實(shí)的單詞跟預(yù)測(cè)的單詞都是一樣的哥攘,雖然這是在訓(xùn)練集上,但是在一定程度上也說(shuō)明這個(gè)小模型能夠處理N Gram 模型的問(wèn)題材鹦。
上面介紹了如何通過(guò)最簡(jiǎn)單的單邊N Gram 模型預(yù)測(cè)單詞逝淹,還有一種復(fù)雜一點(diǎn)的N Gram 模型通過(guò)雙邊的單詞來(lái)預(yù)測(cè)中間的單詞,這種模型有個(gè)專門的名字桶唐,叫Continuous Bag-of-Words model(CBOW)栅葡,具體內(nèi)容差別不大,就不再贅述莽红。
詞性判斷
上面只使用了詞嵌入和N Gram 模型進(jìn)行自然語(yǔ)言處理妥畏,還沒(méi)有真正使用循環(huán)神經(jīng)網(wǎng)絡(luò),下面介紹RNN 在自然語(yǔ)言處理中的應(yīng)用安吁。在這個(gè)例子中醉蚁,我們將使用LSTM 做詞性判斷,因?yàn)橥粋€(gè)單詞有著不同的詞性鬼店,比如book 可以表示名詞网棍,也可以表示動(dòng)詞,所以需要結(jié)合前后文給出具體的判斷妇智。先介紹使用LSTM 做詞性判斷的原理滥玷。
基本原理
定義好一個(gè)LSTM 網(wǎng)絡(luò),然后給出一個(gè)由很多個(gè)詞構(gòu)成的句子巍棱,根據(jù)前面的內(nèi)容惑畴,每個(gè)詞可以用一個(gè)詞向量表示,這樣一句話就可以看做是一個(gè)序列航徙,序列中的每個(gè)元素都是一個(gè)高維向量如贷,將這個(gè)序列傳入LSTM,可以得到與序列等長(zhǎng)的輸出到踏,每個(gè)輸出都表示為對(duì)詞性的判斷杠袱,比如名詞、動(dòng)詞等窝稿。從本質(zhì)上看楣富,這是一個(gè)分類問(wèn)題,雖然使用了LSTM伴榔,但實(shí)際上是根據(jù)這個(gè)詞前面的一些詞來(lái)對(duì)它進(jìn)行分類纹蝴,看它是屬于幾種詞性中的哪一種庄萎。
思考一下為什么LSTM 在這個(gè)問(wèn)題里面起著重要的作用。如果完全孤立地對(duì)一個(gè)詞做詞性的判斷塘安,往往無(wú)法得到比較準(zhǔn)確的結(jié)果惨恭,但是通過(guò)LSTM,根據(jù)它記憶的特性耙旦,就能夠通過(guò)這個(gè)單詞前面記憶的一些詞語(yǔ)來(lái)對(duì)它做一個(gè)判斷脱羡,比如前面的單詞如果是my,那么它緊跟的詞很有可能就是一個(gè)名詞免都,這樣就能夠充分地利用上文來(lái)處理這個(gè)問(wèn)題锉罐。
字符增強(qiáng)
還可以通過(guò)引入字符來(lái)增強(qiáng)表達(dá),這是什么意思呢绕娘?就是說(shuō)一些單詞存在著前綴或者后綴脓规,比如-ly 這種后綴很可能是一個(gè)副詞,這樣我們就能夠在字符水平上對(duì)詞性進(jìn)行進(jìn)一步判斷险领,把兩種方法集成起來(lái)侨舆,能夠得到一個(gè)更好的結(jié)果。
在實(shí)現(xiàn)上還是用LSTM绢陌,只是這次不再將句子作為一個(gè)序列挨下,而是將每個(gè)單詞作為一個(gè)序列。每個(gè)單詞由不同的字母組成脐湾,比如apple 由a p p l e 構(gòu)成臭笆,給這些字符建立詞向量,形成了一個(gè)長(zhǎng)度為5 的序列秤掌,將它傳入LSTM 網(wǎng)絡(luò)愁铺,只取最后輸出的狀態(tài)層作為它的一種字符表達(dá),不需要關(guān)心提取出來(lái)的字符表達(dá)到底是什么樣闻鉴,它作為一種抽象的特征茵乱,能夠更好地預(yù)測(cè)結(jié)果。
詞性判斷的PyTorch 實(shí)現(xiàn)
作為演示孟岛,使用一個(gè)簡(jiǎn)單的訓(xùn)練數(shù)據(jù)瓶竭,下面有兩句話,每句話中的每個(gè)詞都給出了詞性:
接著對(duì)單詞和詞性由a 到z 的字符進(jìn)行編碼:
接著先定義字符水準(zhǔn)上的LSTM蚀苛,定義方式和之前類似:
定義兩層結(jié)構(gòu):第一層是詞嵌入在验,第二層是LSTM玷氏。在網(wǎng)絡(luò)的前向傳播中堵未,先將單詞的n 個(gè)字符傳入網(wǎng)絡(luò),再通過(guò)nn.Embedding 得到詞向量盏触,接著傳入LSTM 網(wǎng)絡(luò)渗蟹,得到隱藏狀態(tài)輸出h块饺,然后通過(guò)h[0] 得到想要的輸出狀態(tài)。對(duì)于每個(gè)單詞雌芽,都可以通過(guò)CharLSTM 用相應(yīng)的字符表示授艰。
接著完成目標(biāo),分析每個(gè)單詞的詞性世落,首先定義好詞性的LSTM 網(wǎng)絡(luò):
看著有點(diǎn)復(fù)雜淮腾,慢慢來(lái)介紹。首先使用n_word 和n_dim 定義單詞的詞向量矩陣的維度屉佳,n_char 和char_dim 定義字符的詞向量維度谷朝,char_hidden 表示字符水準(zhǔn)上的LSTM 輸出的維度,n_hidden 表示每個(gè)單詞作為序列輸入LSTM 的輸出維度武花,最后n_tag 表示輸出的詞性分類圆凰。介紹完里面參數(shù)的含義,下面具體介紹其中網(wǎng)絡(luò)的向前傳播体箕。
學(xué)習(xí)過(guò)PyTorch 的動(dòng)態(tài)圖結(jié)構(gòu)专钉,網(wǎng)絡(luò)的向前傳播就非常簡(jiǎn)單了。因?yàn)橐褂米址鰪?qiáng)累铅,所以在傳入一個(gè)句子作為序列的同時(shí)跃须,還需要傳入句子中的單詞,用word_data表示娃兽。動(dòng)態(tài)圖結(jié)構(gòu)使得前向傳播中可以使用for 循環(huán)將每個(gè)單詞都傳入CharLSTM回怜,得到的結(jié)果和單詞的詞向量拼在一起作為新的序列輸入,將它傳入LSTM 中换薄,最后接一個(gè)全連接層玉雾,將輸出維數(shù)定義為詞性的數(shù)目。
這是基本的思路轻要,就不具體解釋每句話的含義了复旬,只是要注意代碼里面有unsqueeze和squeeze 的操作,原因前面介紹過(guò)冲泥,LSTM 的輸入要帶上batch_size驹碍,所以需要將維度擴(kuò)大。
網(wǎng)絡(luò)訓(xùn)練經(jīng)過(guò)了300 次凡恍,loss 降到了0.16 左右志秃。為了驗(yàn)證模型的準(zhǔn)確性,可以預(yù)測(cè)“Everybody ate the apple”這句話中每個(gè)詞的詞性嚼酝,一共有三種詞:DET浮还、NN、V闽巩。最后得到的結(jié)果如圖7所示钧舌。
結(jié)果是一個(gè)4 行3 列的向量担汤,每一行表示一個(gè)單詞,每一列表示一種詞性洼冻,從左到右的詞性分別是DET崭歧、NN、V撞牢。從每行里面取最大值率碾,那么第一個(gè)詞的詞性就是NN,第二個(gè)詞是V屋彪,第三個(gè)詞是DET播掷,第四個(gè)詞是NN,與想要的結(jié)果相符撼班。
圖7 網(wǎng)絡(luò)訓(xùn)練結(jié)果
以上歧匈,通過(guò)幾個(gè)簡(jiǎn)單的例子介紹了循環(huán)神經(jīng)網(wǎng)絡(luò)在自然語(yǔ)言處理中的應(yīng)用,當(dāng)然真正的應(yīng)用會(huì)更多砰嘁,同時(shí)也更加復(fù)雜件炉,這里就不再深入介紹了,對(duì)自然語(yǔ)言處理感興趣的讀者可以進(jìn)行更深入地探究矮湘。