Ce référentiel contient le code utilisé pour deux articles de Salesforce Research :
Le modèle est livré avec des instructions pour s'entraîner :
modèles de langage au niveau des mots sur les ensembles de données Penn Treebank (PTB), WikiText-2 (WT2) et WikiText-103 (WT103)
modèles de langage au niveau des caractères sur l'ensemble de données Penn Treebank (PTBC) et Hutter Prize (enwik8)
Le modèle peut être composé d'un LSTM ou d'un réseau neuronal quasi-récurrent (QRNN) qui est deux fois ou plus plus rapide que le cuDNN LSTM dans cette configuration tout en obtenant une précision équivalente ou meilleure.
getdata.sh
pour acquérir les ensembles de données Penn Treebank et WikiText-2main.py
finetune.py
pointer.py
Si vous utilisez ce code ou nos résultats dans votre recherche, veuillez citer le cas échéant :
@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}
}
La base de code est désormais compatible avec PyTorch 0.4 pour la plupart des cas d'utilisation (un grand merci à https://github.com/shawntan pour un PR #43 assez complet). De légers réajustements des hyperparamètres peuvent être nécessaires pour obtenir les performances indiquées. Si vous désirez une reproductibilité exacte (ou si vous souhaitez exécuter sur PyTorch 0.3 ou une version antérieure), nous vous suggérons d'utiliser une ancienne validation de ce référentiel. Nous travaillons toujours sur les fonctionnalités pointer
, finetune
et generate
.
Python 3 et PyTorch 0.4 sont requis pour la base de code actuelle.
Vous trouverez ci-dessous des hyperparamètres permettant d'obtenir des résultats équivalents ou meilleurs à ceux inclus dans l'article original.
Si vous devez utiliser une version antérieure de la base de code, le code d'origine et les hyper paramètres accessibles dans la version PyTorch==0.1.12, avec Python 3 et PyTorch 0.1.12 sont requis. Si vous utilisez Anaconda, l'installation de PyTorch 0.1.12 peut être réalisée via : conda install pytorch=0.1.12 -c soumith
.
La base de code a été modifiée lors de la rédaction de l'article, empêchant une reproduction exacte en raison de différences mineures dans les graines aléatoires ou similaires. Nous avons également constaté que les chiffres de reproduction exacts changent lors du changement de GPU sous-jacent. Le guide ci-dessous produit des résultats largement similaires aux chiffres rapportés.
Pour la configuration des données, exécutez ./getdata.sh
. Ce script collecte les ensembles de données Penn Treebank et WikiText-2 prétraités par Mikolov et les place dans le répertoire data
.
Ensuite, décidez si vous souhaitez utiliser le QRNN ou le LSTM comme modèle de réseau neuronal récurrent sous-jacent. Le QRNN est plusieurs fois plus rapide que le LSTM optimisé cuDNN de Nvidia (et des dizaines de fois plus rapide qu'une implémentation naïve du LSTM), tout en obtenant des résultats similaires ou meilleurs que le LSTM pour de nombreux ensembles de données au niveau des mots. Au moment de la rédaction, les modèles QRNN utilisent le même nombre de paramètres et constituent des réseaux légèrement plus profonds, mais sont deux à quatre fois plus rapides par époque et nécessitent moins d'époques pour converger.
Le modèle QRNN utilise un QRNN avec une taille convolutive de 2 pour la première couche, permettant au modèle d'afficher des entrées discrètes en langage naturel (c'est-à-dire « New York »), tandis que toutes les autres couches utilisent une taille convolutive de 1.
Remarque sur le réglage fin : Le réglage fin modifie le fichier model.pt
du modèle enregistré d'origine. Si vous souhaitez conserver les poids d'origine, vous devez copier le fichier.
Remarque : BPTT modifie simplement la longueur de la séquence transmise au GPU, mais n'aura pas d'impact sur le résultat final.
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
L'instruction ci-dessous entraîne un modèle PTB qui, sans réglage fin, atteint des perplexités d'environ 61.2
/ 58.8
(validation/test), avec un réglage fin, atteint des perplexités d'environ 58.8
/ 56.5
, et avec l'augmentation continue du pointeur de cache, atteint des perplexités d'environ 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
L'instruction ci-dessous entraîne un modèle QRNN qui, sans réglage fin, atteint des perplexités d'environ 60.6
/ 58.3
(validation/test), avec un réglage fin, atteint des perplexités d'environ 59.1
/ 56.7
, et avec l'augmentation continue du pointeur de cache, atteint des perplexités d'environ 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
L'instruction ci-dessous entraîne un modèle PTB qui, sans réglage fin, atteint des perplexités d'environ 68.7
/ 65.6
(validation/test), avec un réglage fin, atteint des perplexités d'environ 67.4
/ 64.7
et avec l'augmentation continue du pointeur de cache, atteint des perplexités d'environ 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
Les instructions ci-dessous seront un modèle QRNN qui, sans réglage fin, atteint des perplexités d'environ 69.3
/ 66.8
(validation/test), avec un réglage fin, atteint des perplexités d'environ 68.5
/ 65.9
, et avec l'augmentation continue du pointeur de cache, atteint des perplexités d'environ 53.6
/ 52.1
. De meilleurs chiffres sont probablement réalisables, mais les hyperparamètres n'ont pas fait l'objet de recherches approfondies. Ces hyper paramètres devraient cependant servir de bon point de départ.
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
Pour plus de rapidité concernant le PTB au niveau des caractères et enwik8 ou le WikiText-103 au niveau des mots, reportez-vous à l'article correspondant.
Les vitesses par défaut des modèles lors d'un entraînement sur une NVIDIA Quadro GP100 :
Les modèles QRNN par défaut peuvent être beaucoup plus rapides que le modèle cuDNN LSTM, les accélérations dépendant du degré de goulot d'étranglement du RNN. La majorité du temps du modèle ci-dessus est désormais consacrée au softmax ou à la surcharge d'optimisation (voir la discussion PyTorch QRNN sur la vitesse).
Les vitesses sont environ trois fois plus lentes sur un K80. Sur un K80 ou d'autres cartes mémoire avec moins de mémoire, vous souhaiterez peut-être activer le plafond de la longueur maximale de la séquence échantillonnée pour éviter les erreurs de mémoire insuffisante (MOO), en particulier pour WikiText-2.
Si la vitesse est un problème majeur, SGD converge plus rapidement que notre variante déclenchée de manière non monotone d'ASGD, tout en générant une perplexité globale pire.
Pour plus de détails, reportez-vous au référentiel PyTorch QRNN.
Toutes les augmentations du LSTM, y compris notre variante de DropConnect (Wan et al. 2013) appelée perte de poids qui ajoute des abandons récurrents, permettent l'utilisation de l'implémentation cuDNN LSTM de NVIDIA. PyTorch utilisera automatiquement le backend cuDNN s'il est exécuté sur CUDA avec cuDNN installé. Cela garantit que le modèle est rapide à former, même lorsque la convergence peut prendre plusieurs centaines d'époques.