10分鐘快速入門PyTorch (9)

在上一節(jié)中凑懂,我們介紹了一下自然語言處理里面最基本的單邊和雙邊的 n gram 模型嗽元,用 word embedding和n gram 模型對一句話中的某個詞做預(yù)測,下面我們將使用LSTM來做判別每個詞的詞性环础,因為同一個單詞有著不同的詞性宾巍,比如book可以表示名詞,也可以表示動詞丈甸,所以我們需要訓(xùn)練一下網(wǎng)絡(luò)來得到詞性的判斷糯俗。

LSTM 詞性判斷

LSTM的網(wǎng)絡(luò)結(jié)構(gòu)在之前已經(jīng)介紹過了,如果忘了的同學(xué)可以去前面看看睦擂。我們首先介紹一下如何做每個詞詞性的判斷得湘。

首先,我們定義好一個LSTM網(wǎng)絡(luò)顿仇,然后給出一個句子淘正,每個句子都有很多個詞構(gòu)成摆马,每個詞可以用一個詞向量表示,這樣一句話就可以形成一個序列鸿吆,我們將這個序列依次傳入LSTM囤采,然后就可以得到與序列等長的輸出,每個輸出都表示的是一種詞性伞剑,比如名詞斑唬,動詞之類的,還是一種分類問題黎泣,每個單詞都屬于幾種詞性中的一種恕刘。

我們可以思考一下為什么LSTM在這個問題里面起著重要的作用。如果我們完全孤立的對一個詞做詞性的判斷這樣我們需要特別高維的詞向量抒倚,但是對于LSTM褐着,它有著一個記憶的特性,這樣我們就能夠通過這個單詞前面記憶的一些詞語來對其做一個判斷托呕,比如前面如果是my含蓉,那么他緊跟的詞有很大可能就是一個名詞,這樣就能夠充分的利用上文來做這個問題项郊。

同時我們還可以通過引入字符來增強表達(dá)馅扣,什么意思呢?也就是說一個單詞有一些前綴和后綴着降,比如-ly這種后綴很大可能是一個副詞差油,這樣我們就能夠在字符水平得到一個詞性判斷的更好結(jié)果。

具體怎么做呢任洞?還是用LSTM蓄喇。每個單詞有不同的字母組成,比如 apple 由a p p l e構(gòu)成交掏,我們同樣給這些字符詞向量妆偏,這樣形成了一個長度為5的序列,然后傳入另外一個LSTM網(wǎng)絡(luò)盅弛,只取最后輸出的狀態(tài)層作為它的一種字符表達(dá)钱骂,我們并不需要關(guān)心到底提取出來的字符表達(dá)是什么樣的,在learning的過程中這些都是會被更新的參數(shù)熊尉,使得最終我們能夠正確預(yù)測罐柳。

原理看著挺讓人煩的,這個時候看代碼反而更快狰住,所以如果前面的原理你沒有理解清楚张吉,那么看看代碼,說不行你就恍然大悟了催植。

Code

準(zhǔn)備數(shù)據(jù)

training_data = [
    ("The dog ate the apple".split(), ["DET", "NN", "V", "DET", "NN"]),
    ("Everybody read that book".split(), ["NN", "V", "DET", "NN"])
]

這是一個簡單的訓(xùn)練數(shù)據(jù)肮蛹,兩句話勺择,每句話的每個單詞的詞性由后面給出。

接著我們需要給這些單詞和詞性一個編碼

word_to_idx = {}
tag_to_idx = {}
for context, tag in training_data:
    for word in context:
        if word not in word_to_idx:
            word_to_idx[word] = len(word_to_idx)
    for label in tag:
        if label not in tag_to_idx:
            tag_to_idx[label] = len(tag_to_idx)

這樣每個單詞就用一個數(shù)字表示伦忠,每種詞性也用一個數(shù)字表示省核,這些之前都接觸過。

alphabet = 'abcdefghijklmnopqrstuvwxyz'
character_to_idx = {}
for i in range(len(alphabet)):
    character_to_idx[alphabet[i]] = i

同時我們需要將從a到z的字符也編碼昆码。

字符LSTM

接著我們定義字符水平的LSTM

class CharLSTM(nn.Module):
    def __init__(self, n_char, char_dim, char_hidden):
        super(CharLSTM, self).__init__()
        self.char_embedding = nn.Embedding(n_char, char_dim)
        self.char_lstm = nn.LSTM(char_dim, char_hidden, batch_first=True)

    def forward(self, x):
        x = self.char_embedding(x)
        _, h = self.char_lstm(x)
        return h[1]

看看上面的代碼气忠,首先定義好embedding和lstm,接著傳入n個字符赋咽,然后通過nn.Embedding得到詞向量旧噪,接著傳入LSTM網(wǎng)絡(luò),得到狀態(tài)輸出h脓匿,然后通過h[1]得到我們想要的hidden state淘钟。

這樣我們對于每個單詞,通過CharLSTM就能夠得到相應(yīng)的字符表示陪毡。

詞性LSTM

接著我們來完成我們的目標(biāo)米母,分析每個單詞的詞性,首先定義好LSTM網(wǎng)絡(luò)

class LSTMTagger(nn.Module):
    def __init__(self, n_word, n_char, char_dim, n_dim, char_hidden,
                 n_hidden, n_tag):
        super(LSTMTagger, self).__init__()
        self.word_embedding = nn.Embedding(n_word, n_dim)
        self.char_lstm = CharLSTM(n_char, char_dim, char_hidden)
        self.lstm = nn.LSTM(n_dim+char_hidden, n_hidden, batch_first=True)
        self.linear1 = nn.Linear(n_hidden, n_tag)

    def forward(self, x, word_data):
        word = [i for i in word_data]
        char = torch.FloatTensor()
        for each in word:
            word_list = []
            for letter in each:
                word_list.append(character_to_idx[letter.lower()])
            word_list = torch.LongTensor(word_list)
            word_list = word_list.unsqueeze(0)
            tempchar = self.char_lstm(Variable(word_list).cuda())
            tempchar = tempchar.squeeze(0)
            char = torch.cat((char, tempchar.cpu().data), 0)
        char = char.squeeze(1)
        char = Variable(char).cuda()
        x = self.word_embedding(x)
        x = torch.cat((x, char), 1)
        x = x.unsqueeze(0)
        x, _ = self.lstm(x)
        x = x.squeeze(0)
        x = self.linear1(x)
        y = F.log_softmax(x)
        return y

看著有點復(fù)雜毡琉,我們慢慢來解釋铁瞒。首先n_word 和 n_dim來定義單詞的詞向量維度,n_char和char_dim來定義字符的詞向量維度桅滋,char_hidden表示CharLSTM輸出的維度精拟,n_hidden表示每個單詞作為序列輸入的LSTM輸出維度,最后n_tag表示輸出的詞性的種類虱歪。

接著開始前向傳播,不僅要傳入一個編碼之后的句子栅表,同時還需要傳入原本的單詞笋鄙,因為需要對字符做一個LSTM,所以傳入的參數(shù)多了一個word_data表示一個句子的所有單詞怪瓶。

然后就是將每個單詞傳入CharLSTM萧落,得到的結(jié)果和單詞的詞向量拼在一起形成一個新的輸入,將輸入傳入LSTM里面洗贰,得到輸出找岖,最后接一個全連接層,將輸出維數(shù)定義為label的數(shù)目敛滋。

這就是基本的思路许布,我就不具體解釋每句話的含義了,留給大家自己看看绎晃,特別要注意里面有一些unsqueeze和squeeze是因為LSTM的輸入要求要帶上batch_size蜜唾,torch.cat里面0和1分別表示沿著行和列來拼接杂曲。

結(jié)果

經(jīng)過300個epoch,loss降到了0.2左右

1

最后我們來預(yù)測一下 Everybody ate the apple 這句話每個詞的詞性袁余,一共有3種詞性擎勘,DET,NN颖榜,V棚饵。最后得到的結(jié)果為

2

一共有4行,每行里面取最大的掩完,那么第一個詞的詞性就是NN噪漾,第二個詞是V,第三個詞是DET藤为,第四個詞是NN怪与。這個是相符的。

以上我們介紹了RNN在圖像處理以及自然語言處理上的應(yīng)用缅疟,RNN還有更多的應(yīng)用分别,比如做image captioning,機器翻譯等等存淫,感興趣的同學(xué)可以自己在github上找一找耘斩。

下一章將是本次教程的倒數(shù)第二個部分,Generative Adversarial Networks桅咆,生成對抗網(wǎng)絡(luò)括授。


本文代碼已經(jīng)上傳到了github

歡迎查看我的知乎專欄,深度煉丹

歡迎訪問我的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岩饼,一起剝皮案震驚了整個濱河市荚虚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌籍茧,老刑警劉巖版述,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異寞冯,居然都是意外死亡渴析,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門吮龄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俭茧,“玉大人,你說我怎么就攤上這事漓帚∧刚” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵胰默,是天一觀的道長场斑。 經(jīng)常有香客問我漓踢,道長,這世上最難降的妖魔是什么漏隐? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任喧半,我火速辦了婚禮,結(jié)果婚禮上青责,老公的妹妹穿的比我還像新娘挺据。我一直安慰自己,他們只是感情好脖隶,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布扁耐。 她就那樣靜靜地躺著,像睡著了一般产阱。 火紅的嫁衣襯著肌膚如雪婉称。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天构蹬,我揣著相機與錄音王暗,去河邊找鬼。 笑死庄敛,一個胖子當(dāng)著我的面吹牛俗壹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播藻烤,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼绷雏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了怖亭?” 一聲冷哼從身側(cè)響起涎显,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎兴猩,沒想到半個月后棺禾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡峭跳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缺前。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛀醉。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖衅码,靈堂內(nèi)的尸體忽然破棺而出拯刁,到底是詐尸還是另有隱情,我是刑警寧澤逝段,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布垛玻,位于F島的核電站割捅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏帚桩。R本人自食惡果不足惜亿驾,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望账嚎。 院中可真熱鬧莫瞬,春花似錦、人聲如沸郭蕉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽召锈。三九已至旁振,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涨岁,已是汗流浹背拐袜。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留卵惦,地道東北人阻肿。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像沮尿,于是被迫代替她去往敵國和親丛塌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容