此儲存庫包含兩篇 Salesforce 研究論文所使用的程式碼:
此模型附帶訓練說明:
Penn Treebank (PTB)、WikiText-2 (WT2) 和 WikiText-103 (WT103) 資料集上的詞級語言模型
Penn Treebank (PTBC) 和 Hutter 獎資料集 (enwik8) 上的字元級語言模型
該模型可以由 LSTM 或準循環神經網路 (QRNN) 組成,其速度比此設定中的 cuDNN LSTM 快兩倍或更多倍,同時實現相同或更好的精確度。
getdata.sh
以取得 Penn Treebank 和 WikiText-2 資料集main.py
訓練基本模型finetune.py
微調模型pointer.py
將連續緩存指標應用到微調模型如果您在研究中使用此代碼或我們的結果,請視情況引用:
@article{merityRegOpt,
title={{Regularizing and Optimizing LSTM Language Models}},
author={Merity, Stephen and Keskar, Nitish Shirish and Socher, Richard},
journal={arXiv preprint arXiv:1708.02182},
year={2017}
}
@article{merityAnalysis,
title={{An Analysis of Neural Language Modeling at Multiple Scales}},
author={Merity, Stephen and Keskar, Nitish Shirish and Socher, Richard},
journal={arXiv preprint arXiv:1803.08240},
year={2018}
}
程式碼庫現在與 PyTorch 0.4 相容,適用於大多數用例(強烈推薦 https://github.com/shawntan 以獲得相當全面的 PR #43)。為了獲得所引用的效能,可能需要對超參數進行輕微的重新調整。如果您需要精確的重現性(或希望在 PyTorch 0.3 或更低版本上運行),我們建議使用此儲存庫的較舊提交。我們仍在研究pointer
、 finetune
和generate
功能。
目前程式碼庫需要 Python 3 和 PyTorch 0.4。
下麵包含的超參數可以獲得與原始論文中包含的結果相同或更好的結果。
如果您需要使用早期版本的程式碼庫,則需要使用 PyTorch==0.1.12 版本以及 Python 3 和 PyTorch 0.1.12 來存取原始程式碼和超參數。如果您使用 Anaconda,可以透過以下方式安裝 PyTorch 0.1.12: conda install pytorch=0.1.12 -c soumith
。
在撰寫論文期間修改了程式碼庫,由於隨機種子或類似內容的微小差異而無法準確複製。我們也發現,當變更底層 GPU 時,精確的再現數會改變。以下的指南產生的結果與報告的數字基本上相似。
對於資料設置,請執行./getdata.sh
。該腳本收集 Mikolov 預處理的 Penn Treebank 和 WikiText-2 資料集並將它們放置在data
目錄中。
接下來,決定使用 QRNN 還是 LSTM 作為底層循環神經網路模型。 QRNN 甚至比 Nvidia 的 cuDNN 優化 LSTM 快很多倍(比簡單的 LSTM 實現快幾十倍),但在許多字級資料集上取得了與 LSTM 相似或更好的結果。在撰寫本文時,QRNN 模型使用相同數量的參數,並且是稍微更深的網絡,但每個 epoch 的速度快兩到四倍,並且需要更少的 epoch 來收斂。
QRNN 模型第一層使用卷積大小為 2 的 QRNN,允許模型查看離散的自然語言輸入(即「紐約」),而所有其他層使用卷積大小為 1。
微調注意:微調會修改原始儲存的模型model.pt
檔案 - 如果您希望保留原始權重,則必須複製該檔案。
指針注意: BPTT 只是改變推送到 GPU 上的序列的長度,但不會影響最終結果。
python -u main.py --epochs 50 --nlayers 3 --emsize 400 --nhid 1840 --alpha 0 --beta 0 --dropoute 0 --dropouth 0.1 --dropouti 0.1 --dropout 0.4 --wdrop 0.2 --wdecay 1.2e-6 --bptt 200 --batch_size 128 --optimizer adam --lr 1e-3 --data data/enwik8 --save ENWIK8.pt --when 25 35
python -u main.py --epochs 500 --nlayers 3 --emsize 200 --nhid 1000 --alpha 0 --beta 0 --dropoute 0 --dropouth 0.25 --dropouti 0.1 --dropout 0.1 --wdrop 0.5 --wdecay 1.2e-6 --bptt 150 --batch_size 128 --optimizer adam --lr 2e-3 --data data/pennchar --save PTBC.pt --when 300 400
python -u main.py --epochs 14 --nlayers 4 --emsize 400 --nhid 2500 --alpha 0 --beta 0 --dropoute 0 --dropouth 0.1 --dropouti 0.1 --dropout 0.1 --wdrop 0 --wdecay 0 --bptt 140 --batch_size 60 --optimizer adam --lr 1e-3 --data data/wikitext-103 --save WT103.12hr.QRNN.pt --when 12 --model QRNN
下面的指令訓練了一個 PTB 模型,在沒有微調的情況下實現了大約61.2
/ 58.8
的困惑度(驗證/測試),透過微調實現了大約58.8
/ 56.5
的困惑度,並且透過連續快取指標增強實現了大約53.2
/ 52.5
的困惑度。
python main.py --batch_size 20 --data data/penn --dropouti 0.4 --dropouth 0.25 --seed 141 --epoch 500 --save PTB.pt
python finetune.py --batch_size 20 --data data/penn --dropouti 0.4 --dropouth 0.25 --seed 141 --epoch 500 --save PTB.pt
python pointer.py --data data/penn --save PTB.pt --lambdasm 0.1 --theta 1.0 --window 500 --bptt 5000
下面的指令訓練了一個 QRNN 模型,在沒有微調的情況下,可以實現大約60.6
/ 58.3
的困惑度(驗證/測試),透過微調,可以實現大約59.1
/ 56.7
的困惑度,並且透過連續快取指標增強,可以實現大約53.4
/ 52.6
的困惑度。
python -u main.py --model QRNN --batch_size 20 --clip 0.2 --wdrop 0.1 --nhid 1550 --nlayers 4 --emsize 400 --dropouth 0.3 --seed 9001 --dropouti 0.4 --epochs 550 --save PTB.pt
python -u finetune.py --model QRNN --batch_size 20 --clip 0.2 --wdrop 0.1 --nhid 1550 --nlayers 4 --emsize 400 --dropouth 0.3 --seed 404 --dropouti 0.4 --epochs 300 --save PTB.pt
python pointer.py --model QRNN --lambdasm 0.1 --theta 1.0 --window 500 --bptt 5000 --save PTB.pt
下面的指令訓練了一個 PTB 模型,在沒有微調的情況下實現了大約68.7
/ 65.6
的困惑度(驗證/測試),透過微調實現了大約67.4
/ 64.7
的困惑度,並且透過連續快取指標增強實現了大約52.2
/ 50.6
的困惑度。
python main.py --epochs 750 --data data/wikitext-2 --save WT2.pt --dropouth 0.2 --seed 1882
python finetune.py --epochs 750 --data data/wikitext-2 --save WT2.pt --dropouth 0.2 --seed 1882
python pointer.py --save WT2.pt --lambdasm 0.1279 --theta 0.662 --window 3785 --bptt 2000 --data data/wikitext-2
下面的指令將是一個 QRNN 模型,在沒有微調的情況下,可以實現大約69.3
/ 66.8
的困惑度(驗證/測試),透過微調,可以實現大約68.5
/ 65.9
的困惑度,並且透過連續快取指標增強,可以實現大約53.6
/ 52.1
的困惑度。可能可以獲得更好的數字,但超參數尚未廣泛搜尋。然而,這些超參數應該作為一個很好的起點。
python -u main.py --epochs 500 --data data/wikitext-2 --clip 0.25 --dropouti 0.4 --dropouth 0.2 --nhid 1550 --nlayers 4 --seed 4002 --model QRNN --wdrop 0.1 --batch_size 40 --save WT2.pt
python finetune.py --epochs 500 --data data/wikitext-2 --clip 0.25 --dropouti 0.4 --dropouth 0.2 --nhid 1550 --nlayers 4 --seed 4002 --model QRNN --wdrop 0.1 --batch_size 40 --save WT2.pt
python -u pointer.py --save WT2.pt --model QRNN --lambdasm 0.1279 --theta 0.662 --window 3785 --bptt 2000 --data data/wikitext-2
有關字元級 PTB 和 enwik8 或單字級 WikiText-103 的速度,請參閱相關論文。
在 NVIDIA Quadro GP100 上訓練期間模型的預設速度:
預設的 QRNN 模型可能比 cuDNN LSTM 模型快得多,加速取決於 RNN 的瓶頸程度。上面的大部分模型時間現在都花在了 softmax 或最佳化開銷上(請參閱 PyTorch QRNN 關於速度的討論)。
K80 的速度大約慢三倍。在 K80 或其他記憶體較少的記憶卡上,您可能想要啟用最大採樣序列長度的上限,以防止記憶體不足 (OOM) 錯誤,尤其是對於 WikiText-2。
如果速度是一個主要問題,SGD 比我們的非單調觸發的 ASGD 變體收斂得更快,儘管整體困惑度更差。
有關完整詳細信息,請參閱 PyTorch QRNN 存儲庫。
LSTM 的所有增強功能,包括我們稱為權重下降的 DropConnect 變體(Wan 等人,2013 年),它增加了經常性 dropout,允許使用 NVIDIA 的 cuDNN LSTM 實現。如果在安裝了 cuDNN 的 CUDA 上運行,PyTorch 將自動使用 cuDNN 後端。這確保了模型能夠快速訓練,即使收斂可能需要數百個時期。