Este repositorio contiene el código utilizado para dos artículos de investigación de Salesforce:
El modelo viene con instrucciones para entrenar:
Modelos de lenguaje a nivel de palabra sobre los conjuntos de datos de Penn Treebank (PTB), WikiText-2 (WT2) y WikiText-103 (WT103).
Modelos de lenguaje a nivel de carácter sobre el conjunto de datos de Penn Treebank (PTBC) y Hutter Prize (enwik8).
El modelo puede estar compuesto por un LSTM o una red neuronal cuasi recurrente (QRNN) que es dos o más veces más rápida que el cuDNN LSTM en esta configuración y al mismo tiempo logra una precisión equivalente o mejor.
getdata.sh
para adquirir los conjuntos de datos de Penn Treebank y WikiText-2main.py
finetune.py
pointer.py
Si utiliza este código o nuestros resultados en su investigación, cite según corresponda:
@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}
}
El código base ahora es compatible con PyTorch 0.4 para la mayoría de los casos de uso (un gran agradecimiento a https://github.com/shawntan por un PR #43 bastante completo). Es posible que sean necesarios ligeros reajustes de los hiperparámetros para obtener el rendimiento cotizado. Si desea una reproducibilidad exacta (o desea ejecutar PyTorch 0.3 o inferior), le sugerimos utilizar una confirmación anterior de este repositorio. Todavía estamos trabajando en pointer
, finetune
y generate
funcionalidades.
Se requieren Python 3 y PyTorch 0.4 para el código base actual.
A continuación se incluyen hiperparámetros para obtener resultados equivalentes o mejores a los incluidos en el artículo original.
Si necesita utilizar una versión anterior del código base, se requieren el código original y los hiperparámetros accesibles en la versión PyTorch==0.1.12, con Python 3 y PyTorch 0.1.12. Si está utilizando Anaconda, la instalación de PyTorch 0.1.12 se puede lograr mediante: conda install pytorch=0.1.12 -c soumith
.
El código base se modificó durante la redacción del artículo, lo que impidió la reproducción exacta debido a diferencias menores en semillas aleatorias o similares. También hemos visto cambios en los números de reproducción exactos al cambiar la GPU subyacente. La siguiente guía produce resultados muy similares a los números informados.
Para la configuración de datos, ejecute ./getdata.sh
. Este script recopila los conjuntos de datos Penn Treebank y WikiText-2 preprocesados de Mikolov y los coloca en el directorio data
.
A continuación, decida si utilizar QRNN o LSTM como modelo de red neuronal recurrente subyacente. El QRNN es muchas veces más rápido que incluso el LSTM optimizado para cuDNN de Nvidia (y docenas de veces más rápido que una implementación ingenua de LSTM), pero logra resultados similares o mejores que el LSTM para muchos conjuntos de datos a nivel de palabra. Al momento de escribir este artículo, los modelos QRNN usan la misma cantidad de parámetros y son redes ligeramente más profundas, pero son de dos a cuatro veces más rápidas por época y requieren menos épocas para converger.
El modelo QRNN utiliza un QRNN con tamaño convolucional 2 para la primera capa, lo que permite que el modelo vea entradas de lenguaje natural discretas (es decir, "Nueva York"), mientras que todas las demás capas utilizan un tamaño convolucional de 1.
Nota de ajuste fino: El ajuste fino modifica el archivo model.pt
del modelo original guardado; si desea conservar los pesos originales, debe copiar el archivo.
Nota informativa: BPTT simplemente cambia la duración de la secuencia enviada a la GPU, pero no afectará el resultado 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
La siguiente instrucción entrena un modelo PTB que sin ajuste logra perplejidades de aproximadamente 61.2
/ 58.8
(validación/prueba), con ajuste logra perplejidades de aproximadamente 58.8
/ 56.5
y con el aumento continuo del puntero de caché logra perplejidades de aproximadamente 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
La siguiente instrucción entrena un modelo QRNN que sin ajuste logra perplejidades de aproximadamente 60.6
/ 58.3
(validación/prueba), con ajuste logra perplejidades de aproximadamente 59.1
/ 56.7
y con el aumento continuo del puntero de caché logra perplejidades de aproximadamente 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
Las instrucciones siguientes entrenan un modelo PTB que sin ajuste logra perplejidades de aproximadamente 68.7
/ 65.6
(validación/prueba), con ajuste logra perplejidades de aproximadamente 67.4
/ 64.7
y con el aumento continuo del puntero de caché logra perplejidades de aproximadamente 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
Las instrucciones a continuación mostrarán un modelo QRNN que, sin ajuste fino, logra perplejidades de aproximadamente 69.3
/ 66.8
(validación/prueba), con ajuste fino logra perplejidades de aproximadamente 68.5
/ 65.9
y con el aumento continuo del puntero de caché logra perplejidades de aproximadamente 53.6
/ 52.1
. Es probable que se puedan lograr mejores cifras, pero los hiperparámetros no se han buscado exhaustivamente. Sin embargo, estos hiperparámetros deberían servir como un buen punto de partida.
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
Para conocer la velocidad con respecto a PTB a nivel de caracteres y enwik8 o WikiText-103 a nivel de palabra, consulte el documento correspondiente.
Las velocidades predeterminadas para los modelos durante el entrenamiento en una NVIDIA Quadro GP100:
Los modelos QRNN predeterminados pueden ser mucho más rápidos que el modelo cuDNN LSTM, y las aceleraciones dependen de qué tan cuello de botella sea el RNN. La mayor parte del tiempo del modelo anterior ahora se dedica a softmax o a la sobrecarga de optimización (consulte la discusión sobre PyTorch QRNN sobre velocidad).
Las velocidades son aproximadamente tres veces más lentas en un K80. En una K80 u otras tarjetas de memoria con menos memoria, es posible que desee habilitar el límite en la longitud máxima de la secuencia muestreada para evitar errores de falta de memoria (OOM), especialmente para WikiText-2.
Si la velocidad es un problema importante, SGD converge más rápidamente que nuestra variante de ASGD no activada monótonamente, aunque logra una perplejidad general peor.
Para obtener detalles completos, consulte el repositorio QRNN de PyTorch.
Todos los aumentos del LSTM, incluida nuestra variante de DropConnect (Wan et al. 2013), denominada caída de peso que agrega abandono recurrente, permiten el uso de la implementación cuDNN LSTM de NVIDIA. PyTorch utilizará automáticamente el backend de cuDNN si se ejecuta en CUDA con cuDNN instalado. Esto garantiza que el modelo se entrene rápidamente incluso cuando la convergencia puede tardar muchos cientos de épocas.