10分鐘快速入門PyTorch (8)

前面一篇文章中鸽捻,我們簡單的介紹了自然語言處理中最簡單的詞向量 word embedding,這一篇文章我們將介紹如何使用word embedding做自然語言處理的詞語預(yù)測统锤。

N-Gram language Modeling

首先我們介紹一下 N-Gram 模型猎莲。在一篇文章中奔则,每一句話有很多單詞組成,而對于一句話,這些單詞的組成順序也是很重要的驮吱,我們想要知道在一篇文章中我們是否可以給出幾個(gè)詞然后預(yù)測這些詞后面的一個(gè)單詞茧妒,比如'I lived in France for 10 years, I can speak _ .'那么我們想要做的就是預(yù)測最后這個(gè)詞是French。

知道了我們想要做的事情之后左冬,我們就可以引出 N-Gram 模型了嘶伟。先給出其公式


1

這就是一個(gè)條件概率,也就是我們給定想要預(yù)測的單詞的前面幾個(gè)單詞又碌,然后最大化我們想要預(yù)測的這個(gè)單詞的概率九昧。

Code

數(shù)據(jù)預(yù)處理

首先我們給出了一段文章作為我們的訓(xùn)練集

CONTEXT_SIZE = 2
EMBEDDING_DIM = 10
# We will use Shakespeare Sonnet 2
test_sentence = """When forty winters shall besiege thy brow,
And dig deep trenches in thy beauty's field,
Thy youth's proud livery so gazed on now,
Will be a totter'd weed of small worth held:
Then being asked, where all thy beauty lies,
Where all the treasure of thy lusty days;
To say, within thine own deep sunken eyes,
Were an all-eating shame, and thriftless praise.
How much more praise deserv'd thy beauty's use,
If thou couldst answer 'This fair child of mine
Shall sum my count, and make my old excuse,'
Proving his beauty by succession thine!
This were to be new made when thou art old,
And see thy blood warm when thou feel'st it cold.""".split()

CONTEXT_SIZE表示我們想由前面的幾個(gè)單詞來預(yù)測這個(gè)單詞,這里設(shè)置為2毕匀,就是說我們希望通過這個(gè)單詞的前兩個(gè)單詞來預(yù)測這一個(gè)單詞铸鹰。 EMBEDDING_DIM表示word embedding的維數(shù),上一篇已經(jīng)介紹過了皂岔。

trigram = [((test_sentence[i], test_sentence[i+1]), test_sentence[i+2])
           for i in range(len(test_sentence)-2)]

接下來我們需要將數(shù)據(jù)整理好蹋笼,也就是我們需要將單詞三個(gè)分組,每個(gè)組前兩個(gè)作為傳入的數(shù)據(jù)躁垛,而最后一個(gè)作為預(yù)測的結(jié)果剖毯。

vocb = set(test_sentence) # 通過set將重復(fù)的單詞去掉
word_to_idx = {word: i for i, word in enumerate(vocb)}
idx_to_word = {word_to_idx[word]: word for word in word_to_idx}

接下來需要給每個(gè)單詞編碼,也就是用數(shù)字來表示每個(gè)單詞教馆,這樣才能夠傳入word embeding得到詞向量逊谋。

定義模型

class NgramModel(nn.Module):
    def __init__(self, vocb_size, context_size, n_dim):
        super(NgramModel, self).__init__()
        self.n_word = vocb_size
        self.embedding = nn.Embedding(self.n_word, n_dim)
        self.linear1 = nn.Linear(context_size*n_dim, 128)
        self.linear2 = nn.Linear(128, self.n_word)

    def forward(self, x):
        emb = self.embedding(x)
        emb = emb.view(1, -1)
        out = self.linear1(emb)
        out = F.relu(out)
        out = self.linear2(out)
        log_prob = F.log_softmax(out)
        return log_prob


ngrammodel = NgramModel(len(word_to_idx), CONTEXT_SIZE, 100)
criterion = nn.NLLLoss()
optimizer = optim.SGD(ngrammodel.parameters(), lr=1e-3)

這個(gè)模型需要傳入的參數(shù)是所有的單詞數(shù)胶滋,預(yù)測單詞需要的前面單詞數(shù),即CONTEXT_SIZE悲敷,詞向量的維度。

然后在向前傳播中后德,首先傳入單詞得到詞向量,比如在該模型中傳入兩個(gè)詞瓢湃,得到的詞向量是(2, 100),然后將詞向量展開成(1, 200)箱季,然后傳入一個(gè)線性模型,經(jīng)過relu激活函數(shù)再傳入一個(gè)線性模型藏雏,輸出的維數(shù)是單詞總數(shù)拷况,可以看成一個(gè)分類問題,要最大化預(yù)測單詞的概率赚瘦,最后經(jīng)過一個(gè)log softmax激活函數(shù)粟誓。

2

然后定義好模型、loss以及優(yōu)化函數(shù)起意。

訓(xùn)練

for epoch in range(100):
    print('epoch: {}'.format(epoch+1))
    print('*'*10)
    running_loss = 0
    for data in trigram:
        word, label = data
        word = Variable(torch.LongTensor([word_to_idx[i] for i in word]))
        label = Variable(torch.LongTensor([word_to_idx[label]]))
        # forward
        out = ngrammodel(word)
        loss = criterion(out, label)
        running_loss += loss.data[0]
        # backward
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print('Loss: {:.6f}'.format(running_loss / len(word_to_idx)))

接著進(jìn)行訓(xùn)練鹰服,一共跑100個(gè)epoch,在每個(gè)epoch中揽咕,word代表著預(yù)測單詞的前面兩個(gè)詞悲酷,label表示要預(yù)測的詞,然后記住需要將他們轉(zhuǎn)換成Variable亲善,接著進(jìn)入網(wǎng)絡(luò)得到結(jié)果设易,然后通過loss函數(shù)得到loss進(jìn)行反向傳播,更新參數(shù)蛹头。

訓(xùn)練完100個(gè)epoch后的結(jié)果如下

3

我們發(fā)現(xiàn)loss已經(jīng)降到了0.37顿肺,也可以通過預(yù)測來檢測我們的模型是否有效

word, label = trigram[3]
word = Variable(torch.LongTensor([word_to_idx[i] for i in word]))
out = ngrammodel(word)
_, predict_label = torch.max(out, 1)
predict_word = idx_to_word[predict_label.data[0][0]]
print('real word is {}, predict word is {}'.format(label, predict_word))

得到的如下結(jié)果

4

可以發(fā)現(xiàn)我們能夠準(zhǔn)確地預(yù)測這個(gè)單詞。

以上我們介紹了如何通過最簡單的單邊 N-Gram 模型預(yù)測單詞渣蜗,還有一種復(fù)雜一點(diǎn)的N-Gram模型通過雙邊的單詞來預(yù)測中間的單詞屠尊,這種模型有個(gè)專門的名字,叫 Continuous Bag-of-Words model (CBOW)耕拷,具體的內(nèi)容差別不大讼昆,就不再細(xì)講了,代碼的實(shí)現(xiàn)放在了github上面斑胜。

下一章我們將講一下如何使用LSTM來做自然語言處理控淡。


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

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

歡迎訪問我的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末止潘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子辫诅,更是在濱河造成了極大的恐慌凭戴,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炕矮,死亡現(xiàn)場離奇詭異么夫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)肤视,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門档痪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人邢滑,你說我怎么就攤上這事腐螟。” “怎么了?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵乐纸,是天一觀的道長衬廷。 經(jīng)常有香客問我,道長汽绢,這世上最難降的妖魔是什么吗跋? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任跌宛,我火速辦了婚禮秩冈,結(jié)果婚禮上斥扛,老公的妹妹穿的比我還像新娘。我一直安慰自己芬失,他們只是感情好匾灶,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布阶女。 她就那樣靜靜地躺著,像睡著了一般衬鱼。 火紅的嫁衣襯著肌膚如雪憔杨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天抛蚤,我揣著相機(jī)與錄音岁经,去河邊找鬼蛇券。 笑死朽们,一個(gè)胖子當(dāng)著我的面吹牛骑脱,可吹牛的內(nèi)容都是我干的苍糠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼拥娄,長吁一口氣:“原來是場噩夢啊……” “哼瞳筏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起摊欠,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤些椒,失蹤者是張志新(化名)和其女友劉穎掸刊,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體石窑,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡松逊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年棺棵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了熄捍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片余耽。...
    茶點(diǎn)故事閱讀 38,643評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡苹熏,死狀恐怖币喧,靈堂內(nèi)的尸體忽然破棺而出杀餐,到底是詐尸還是另有隱情朱巨,我是刑警寧澤,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布琼讽,位于F島的核電站钻蹬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏问欠。R本人自食惡果不足惜粒蜈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一薪伏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧设捐,春花似錦塘淑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至兼吓,卻和暖如春森枪,著一層夾襖步出監(jiān)牢的瞬間审孽,已是汗流浹背浑娜。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工筋遭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘸洛。 一個(gè)月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像反肋,于是被迫代替她去往敵國和親踏施。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評論 2 348

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