Maintenant, la pré-formation du modèle de langue pour la compréhension du langage est une étape importante dans le contexte de la PNL.
Un modèle de langue serait formé sur un corpus massif, puis nous pourrons l'utiliser comme composant dans d'autres modèles qui doivent gérer le langage (par exemple, l'utiliser pour les tâches en aval).
Un modèle de lanugage (LM) capture la distribution sur toutes les phrases possibles .
Bien que la modélisation du langage soit un apprentissage non supervisé typique sur un corpus massif, nous transformons cela en une séquence d'apprentissage supervisé dans ce repo.
Le modèle de langage autorégressif capture la distribution sur le jeton suivant est basé sur tous les jetons précédents. En d'autres termes, il examine le jeton précédent et prédit le jeton suivant.
L'objectif du modèle de langue autorégressif est exprimé dans une formule comme suit:
Parce que le modèle de langue autorégressif doit être en avant ou en arrière, seules les informations de contexte unidirectionnel unidirectionnel peuvent être utilisées. Par conséquent, il est difficile de comprendre le contexte dans les deux sens simultanément.
RNNLM, Elmo est un exemple typique du modèle de langage autorégressif, et les modèles de langage LSTM unidirectionnels / bidirectionnels sont couverts dans ce repo.
Wikipedia distribue régulièrement l'ensemble du document. Vous pouvez télécharger le vidage coréen Wikipedia ici (et le vidage Wikipedia anglais ici). Wikipedia recommande d'utiliser pages-articles.xml.bz2 , qui ne comprend que la dernière version de l'ensemble du document, et est compressée à environ 600 Mo (pour l'anglais, pages-articles-multistream.xml.bz2 ).
Vous pouvez utiliser le script wikipedia_ko.sh pour télécharger le vidage sur le dernier document coréen Wikipedia. Pour l'anglais, utilisez wikipedia_en.sh
exemple:
$ cd build_corpus
$ chmod 777 wikipedia_ko.sh
$ ./wikipedia_ko.sh
Le vidage téléchargé en utilisant le script shell ci-dessus est au format XML, et nous devons analyser XML dans le fichier texte. Le script Python WikiExtractor.py dans attardi / wikiextractor repo, extrait et nettoie le texte du vidage.
exemple:
$ git clone https://github.com/attardi/wikiextractor
$ python wikiextractor/WikiExtractor.py kowiki-latest-pages-articles.xml
$ head -n 4 text/AA/wiki_02
<doc id="577" url="https://ko.wikipedia.org/wiki?curid=577" title="천문학">
천문학
천문학(天文學, )은 별이나 행성, 혜성, 은하와 같은 천체와, 지구 대기의 ..
</doc>
Le texte extrait est enregistré sous forme de fichier texte d'une certaine taille. Pour les combiner, utilisez build_corpus.py . La sortie corpus.txt contient 4 277 241 phrases, 55 568 030 mots .
exemple:
$ python build_corpus.py > corpus.txt
$ wc corpus.txt
4277241 55568030 596460787 corpus.txt
Maintenant, vous devez diviser le corpus pour set et set et set.
$ cat corpus.txt | shuf > corpus.shuf.txt
$ head -n 855448 corpus.shuf.txt > corpus.test.txt
$ tail -n 3421793 corpus.shuf.txt > corpus.train.txt
$ wc -l corpus.train.txt corpus.test.txt
3421793 corpus.train.txt
855448 corpus.test.txt
4277241 합계
Notre Corpus corpus.txt compte 55 568 030 mots et 608 221 mots uniques. Si la fréquence minimale nécessaire pour inclure un jeton dans le vocabulaire est définie sur 3, le vocabulaire contient 297 773 mots uniques.
Ici, nous utilisons le train corpus corpus.train.txt pour construire un vocabulaire. Le vocabulaire construit par Train Corpus contient 557 627 mots uniques et 271 503 mots uniques qui apparaissent au moins trois fois.
exemple:
$ python build_vocab.py --corpus build_corpus/corpus.train.txt --vocab vocab.train.pkl --min_freq 3 --lower
Namespace(bos_token='<bos>', corpus='build_corpus/corpus.train.txt', eos_token='<eos>', is_tokenized=False, lower=True, min_freq=3, pad_token='<pad>', tokenizer='mecab', unk_token='<unk>', vocab='vocab.train.pkl')
Vocabulary size: 271503
Vocabulary saved to vocab.train.pkl
Étant donné que le fichier de vocabulaire est trop grand (~ 1,3 Go) à télécharger sur ce dépôt, je l'ai téléchargé sur Google Drive.
vocab.train.pkl : [téléchargement] $ python lm_trainer.py -h
usage: lm_trainer.py [-h] --train_corpus TRAIN_CORPUS --vocab VOCAB
--model_type MODEL_TYPE [--test_corpus TEST_CORPUS]
[--is_tokenized] [--tokenizer TOKENIZER]
[--max_seq_len MAX_SEQ_LEN] [--multi_gpu] [--cuda CUDA]
[--epochs EPOCHS] [--batch_size BATCH_SIZE]
[--clip_value CLIP_VALUE] [--shuffle SHUFFLE]
[--embedding_size EMBEDDING_SIZE]
[--hidden_size HIDDEN_SIZE] [--n_layers N_LAYERS]
[--dropout_p DROPOUT_P]
optional arguments:
-h, --help show this help message and exit
--train_corpus TRAIN_CORPUS
--vocab VOCAB
--model_type MODEL_TYPE
Model type selected in the list: LSTM, BiLSTM
--test_corpus TEST_CORPUS
--is_tokenized Whether the corpus is already tokenized
--tokenizer TOKENIZER
Tokenizer used for input corpus tokenization
--max_seq_len MAX_SEQ_LEN
The maximum total input sequence length after
tokenization
--multi_gpu Whether to training with multiple GPU
--cuda CUDA Whether CUDA is currently available
--epochs EPOCHS Total number of training epochs to perform
--batch_size BATCH_SIZE
Batch size for training
--clip_value CLIP_VALUE
Maximum allowed value of the gradients. The gradients
are clipped in the range
--shuffle SHUFFLE Whether to reshuffle at every epoch
--embedding_size EMBEDDING_SIZE
Word embedding vector dimension
--hidden_size HIDDEN_SIZE
Hidden size of LSTM
--n_layers N_LAYERS Number of layers in LSTM
--dropout_p DROPOUT_P
Dropout rate used for dropout layer in LSTM
exemple:
$ python lm_trainer.py --train_corpus build_corpus/corpus.train.txt --vocab vocab.train.pkl --model_type LSTM --batch_size 16
Vous pouvez sélectionner vos propres valeurs de paramètre via des entrées d'argument.
La formation d'un modèle avec un seul GPU est non seulement très lente, mais il limite également l'ajustement de la taille du lot, de la taille du modèle, etc. Pour accélérer la formation du modèle avec plusieurs GPU et utiliser un grand modèle, ce que vous devez faire est d'inclure --multi_gpu Flag Like Belows. Pour plus de détails, veuillez vérifier ici.
Cet exemple de code forme un modèle Unidirectional-LSTM sur le corpus Wikipedia en utilisant une formation parallèle sur les GPU 8 * V100.
$ python lm_trainer.py --train_corpus build_corpus/corpus.train.txt --vocab vocab.train.pkl --model_type LSTM --multi_gpu
Namespace(batch_size=512, clip_value=10, cuda=True, dropout_p=0.2, embedding_size=256, epochs=10, hidden_size=1024, is_tokenized=False, max_seq_len=32, model_type='LSTM', multi_gpu=True, n_layers=3, shuffle=True, test_corpus=None, tokenizer='mecab', train_corpus='build_corpus/corpus.train.txt', vocab='vocab.train.pkl')
=========MODEL=========
DataParallelModel(
(module): LSTMLM(
(embedding): Embedding(271503, 256)
(lstm): LSTM(256, 1024, num_layers=3, batch_first=True, dropout=0.2)
(fc): Linear(in_features=1024, out_features=512, bias=True)
(fc2): Linear(in_features=512, out_features=271503, bias=True)
(softmax): LogSoftmax()
)
)
Cet exemple de code forme le modèle Bidirectional-LSTM sur le corpus Wikipedia en utilisant une formation parallèle sur les GPU 8 * V100.
$ python lm_trainer.py --train_corpus build_corpus/corpus.train.txt --vocab vocab.train.pkl --model_type BiLSTM --n_layers 1 --multi_gpu
Namespace(batch_size=512, clip_value=10, cuda=True, dropout_p=0.2, embedding_size=256, epochs=10, hidden_size=1024, is_tokenized=False, max_seq_len=32, model_type='BiLSTM', multi_gpu=True, n_layers=1, shuffle=True, test_corpus=None, tokenizer='mecab', train_corpus='build_corpus/corpus.train.txt', vocab='vocab.train.pkl')
=========MODEL=========
DataParallelModel(
(module): BiLSTMLM(
(embedding): Embedding(271503, 256)
(lstm): LSTM(256, 1024, batch_first=True, dropout=0.2, bidirectional=True)
(fc): Linear(in_features=2048, out_features=1024, bias=True)
(fc2): Linear(in_features=1024, out_features=512, bias=True)
(fc3): Linear(in_features=512, out_features=271503, bias=True)
(softmax): LogSoftmax()
)
)
Un modèle de langue capture la distribution sur toutes les phrases possibles. Et, le meilleur modèle de langue est celui qui prédit le meilleur une phrase invisible. La perplexité est une mesure très courante de la façon dont une distribution de probabilité prédit des phrases invisibles.
Perplexité : probabilité inverse de la phrase donnée, normalisée par le nombre de mots (en prenant la moyenne géométrique)
Comme vous pouvez le voir à partir de l'équation ci-dessus, la perplexité est définie comme le journal logarithmique moyen négatif exposant. En d'autres termes, la maximisation de la probabilité est la même que la minimisation de la perplexité.
Et maintenant, la perplexité est la métrique que nous allons utiliser. Une faible perplexité indique que la distribution de probabilité est bonne pour prédire la phrase.
| Modèle | Perte | Perplexité |
|---|---|---|
| Unidirectional-LSTM | 3.496 | 33.037 |
| Bidirectional-LSTM | 1.896 | 6.669 |
| Bidirectional-Lstm-Large ( Hidden_Size = 1024) | 1.771 | 5.887 |