當前位置:
首頁 > 最新 > 專知-PyTorch手把手深度學習教程07

專知-PyTorch手把手深度學習教程07

Practical PyTorch: 用字符集RNN進行名稱分類

本文翻譯自spro/practical-pytorch

原文:https://github.com/spro/practical-pytorch/blob/master/char-rnn-classification/char-rnn-classification.ipynb

翻譯: Mandy

輔助: huaiwen

初始

我們將建立和訓練一個基本的字元級RNN來分類單詞。字元級RNN將字作為一系列字元讀入 - 在每個步驟輸出預測和「隱藏狀態」,將其先前的隱藏狀態饋送到每個下一步驟。我們將最終預測作為輸出,即該詞屬於哪一類。具體來說,我們將從18種語言的起源開始列出數千個姓氏,並根據拼寫預測該名字來源於哪種語言

舉例

推薦閱讀

假設你至少安裝了PyTorch,知道Python,並了解Tensors:

http://pytorch.org/ ( 有關安裝說明的網址)

Deep Learning with PyTorch: A 60-minute Blitz (這個鏈接讓你大致了解什麼是PyTorch )

jcjohnson s PyTorch examples ( 深入了解PyTorch )

Introduction to PyTorch for former Torchies ( 如果你之前用過 Lua Torch )

知道並了解RNNs 以及它們是如何工作的是很有用的

The Unreasonable Effectiveness of Recurrent Neural Networks ( 展示了一堆現實生活中的例子)

Understanding LSTM Networks(是關於LSTM具體的,但也是關於RNN的一般介紹)

準備數據

包含在data/names目錄中的是18個文本文件,名稱為「[Language] .txt」。每個文件包含一堆名稱,每行一個名稱,主要是羅馬字體化的(但是我們仍然需要從Unicode轉換為ASCII)。

我們最終會得到一個每種語言名稱列表的字典,。通用變數「category」和「line」(在我們的例子中用於語言和名稱)用於後續的可擴展性。

[ ../data/names/Arabic.txt , ../data/names/Chinese.txt , ../data/names/Czech.txt , ../data/names/Dutch.txt , ../data/names/English.txt , ../data/names/French.txt , ../data/names/German.txt , ../data/names/Greek.txt , ../data/names/Irish.txt , ../data/names/Italian.txt , ../data/names/Japanese.txt , ../data/names/Korean.txt , ../data/names/Polish.txt , ../data/names/Portuguese.txt , ../data/names/Russian.txt , ../data/names/Scottish.txt , ../data/names/Spanish.txt , ../data/names/Vietnamese.txt ]

Slusarski

n_categories = 18

現在我們有category_lines,一個將每個類別(語言)映射到行 列表(名稱)的字典。我們還跟蹤所有類別(只是一個語言列表)和n_categories以供以後參考。

[ Abandonato , Abatangelo , Abatantuono , Abate , Abategiovanni ]

把名字變成Tensors

現在我們已經組織了所有的名字,我們需要把它們變成Tensors來使用它們。

為了表示單個字母,我們使用大小為的「one-hot vector」。一個熱向量填充0,除了當前字母的索引1,例如「b」= 。

為了表達我們的意思,我們將一大堆加入到2維矩陣中。

這個額外的1維是因為PyTorch假設一切都是批量的 -我們只是在這裡使用批量大小為1。

Columns 0 to 12

0 0 0 0 0 0 0 0 0 0 0 0 0

Columns 13 to 25

0 0 0 0 0 0 0 0 0 0 0 0 0

Columns 26 to 38

0 0 0 0 0 0 0 0 0 1 0 0 0

Columns 39 to 51

0 0 0 0 0 0 0 0 0 0 0 0 0

Columns 52 to 56

0 0 0 0 0

[torch.FloatTensor of size 1x57]

torch.Size([5, 1, 57])

創建網路

在自動格式化之前,在Torch中創建一個循環神經網路涉及到克隆了多個時間步長的層的參數。這些層保持隱藏的狀態和漸變,現在完全由圖形本身處理。這意味著你可以以非常「純凈」的方式實施RNN,作為正常的前饋層。

這個RNN模塊(大部分來自PyTorch for Torch用戶教程的複製)只是2個線性層,它們在輸入和隱藏狀態下運行,輸出後面有LogSoftmax層。

手動測試網路

定義了我們定製的RNN類,我們可以創建一個新的實例:

為了開始運行這個網路,我們需要傳遞一個輸入(在我們的例子中是當前字母的Tensor)和一個先前的隱藏狀態(我們首先初始化為零)。我們將取回輸出(每種語言的概率)和下一個隱藏狀態(我們為下一步保留)。

請記住,PyTorch模塊在變數上運行,而不是直接在Tensors。

output.size = torch.Size([1, 18])

為了提高效率,我們不希望為每個步驟創建一個新的Tensor,所以我們將使用line_to_tensor而不是letter_to_tensor並使用slice。這可以通過預先計算批量的Tensors進一步優化。

Variable containing:

Columns 0 to 9

-2.8658 -2.8801 -2.7945 -2.9082 -2.8309 -2.9718 -2.9366 -2.9416 -2.7900 -2.8467

Columns 10 to 17

-2.9495 -2.9496 -2.8707 -2.8984 -2.8147 -2.9442 -2.9257 -2.9363

[torch.FloatTensor of size 1x18]

可以看到輸出是 Tensor,其中每個項目都是該類別的可能性(更高的可能性)。

準備訓練

在進行訓練之前,我們應該製造一些功能函數。第一個是解釋網路的輸出,我們知道這是每個類別的可能性。我們可以使用Tensor.topk得到最大值的索引:

( Irish , 8)

我們還需要一個快速的方式來獲得訓練示例(名稱及其語言):

category = Italian / line = Campana

category = Korean / line = Koo

category = Irish / line = Mochan

category = Japanese / line = Kitabatake

category = Vietnamese / line = an

category = Korean / line = Kwak

category = Portuguese / line = Campos

category = Vietnamese / line = Chung

category = Japanese / line = Ise

category = Dutch / line = Romijn

訓練網路

現在,訓練這個網路所需要的就是展示一大堆例子,讓它做出猜測,並告訴它是否錯誤。

對於損耗函數nn.NLLLoss是適當的,因為RNN的最後一層是nn.LogSoftmax。

我們還將創建一個「優化器」,根據其梯度更新我們的模型的參數。我們將使用具有低學習率的SGD演算法。

每個訓練循環將會:

創建輸入和目標 tensors

創建一個歸零的初始隱藏狀態

閱讀每個字母和保持下一個字母的隱藏狀態

將最終輸出與目標進行比較

反向傳播

返回輸出值和丟失值

現在我們只需要運行一些例子。由於train函數返回輸出和損失,我們可以列印其猜測,並跟蹤繪製的損失。由於有1000個例子,我們只需列印每一個print_every時間步長,並且得到平均損失。

5000 5% (0m 7s) 2.7940 Neil / Chinese (Irish)

10000 10% (0m 14s) 2.7166 O Kelly / English (Irish)

15000 15% (0m 23s) 1.1694 Vescovi / Italian

20000 20% (0m 31s) 2.1433 Mikhailjants / Greek (Russian)

25000 25% (0m 40s) 2.0299 Planick / Russian (Czech)

30000 30% (0m 48s) 1.9862 Cabral / French (Portuguese)

35000 35% (0m 55s) 1.5634 Espina / Spanish

40000 40% (1m 5s) 3.8602 MaxaB / Arabic (Czech)

45000 45% (1m 13s) 3.5599 Sandoval / Dutch (Spanish)

50000 50% (1m 20s) 1.3855 Brown / Scottish

55000 55% (1m 27s) 1.6269 Reid / French (Scottish)

60000 60% (1m 35s) 0.4495 Kijek / Polish

65000 65% (1m 43s) 1.0269 Young / Scottish

70000 70% (1m 50s) 1.9761 Fischer / English (German)

75000 75% (1m 57s) 0.7915 Rudaski / Polish

80000 80% (2m 5s) 1.7026 Farina / Portuguese (Italian)

85000 85% (2m 12s) 0.1878 Bakkarevich / Russian

90000 90% (2m 19s) 0.1211 Pasternack / Polish

95000 95% (2m 25s) 0.6084 Otani / Japanese

100000 100% (2m 33s) 0.2713 Alesini / Italian

繪製結果

從 all_losses變數繪製的歷史數據圖展示網路學習:

[]

評估結果

要了解網路在不同類別上的運行情況,我們將創建一個混淆矩陣,表示對於每種實際語言(行),網路預測為哪種語言(列)的信息。(每一行表示這一類的數據在不同類別上的預測結果)

你可以從主軸上選出亮點,顯示哪些語言預測錯誤,例如很多漢語被預測為韓語這一類了,西班牙語被預測為義大利語。由這個圖可知,希臘語預測的結果非常好,顏色最亮,英語預測的很差(可能的原因是和其他很多歐洲語言有很多重合的詞)

在用戶輸入端運行

Dovesky

(-0.87) Czech

(-0.88) Russian

(-2.44) Polish

Jackson

(-0.74) Scottish

(-2.03) English

(-2.21) Polish

Satoshi

(-0.77) Arabic

(-1.35) Japanese

(-1.81) Polish

Practical PyTorch repo中腳本的最終版本將上述代碼分成幾個文件:

data.py (loads files)

model.py (defines the RNN)

train.py (runs training)

predict.py (runs predict() with command line arguments)

server.py (serve prediction as a JSON API with bottle.py)

運行train.py來訓練並保存網路。

運行具有名稱的predict.py來查看預測:

運行server.py並訪問http://localhost:5533 /Yourname 以獲得JSON輸出的預測。

明天繼續推出:專知PyTorch深度學習教程系列< NLP系列(三) 基於字元級RNN的姓名生成 >,敬請關注。

完整系列搜索查看,請PC登錄

對PyTorch教程感興趣的同學,歡迎進入我們的專知PyTorch主題群一起交流、學習、討論,掃一掃如下群二維碼即可進入:

了解使用專知-獲取更多AI知識!

-END-

專 · 知

關注我們的公眾號,獲取最新關於專知以及人工智慧的資訊、技術、演算法、深度乾貨等內容。掃一掃下方關注我們的微信公眾號。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 專知 的精彩文章:

專知中秋呈獻-PyTorch手把手深度學習教程03

TAG:專知 |