Jetzt ist die Vorausbildung des Sprachmodells für das Sprachverständnis ein wesentlicher Schritt im Kontext von NLP.
Ein Sprachmodell würde auf einem massiven Korpus trainiert, und dann können wir es als Komponente in anderen Modellen verwenden, die die Sprache verarbeiten müssen (z. B. für nachgeschaltete Aufgaben).
Ein Lanugage -Modell (LM) erfasst die Verteilung über alle möglichen Sätze .
Während die Sprachmodellierung ein typisches unbeaufsichtigtes Lernen auf dem massiven Korpus ist, verwandeln wir dies in eine Folge des überwachten Lernens in diesem Repo.
Das autoregressive Sprachmodell erfasst die Verteilung über das nächste Token basiert auf allen vorherigen Token. Mit anderen Worten, es befasst sich mit dem vorherigen Token und prognostiziert den nächsten Token.
Das Ziel des autoregressiven Sprachmodells wird wie folgt in einer Formel ausgedrückt:
Da das autoregressive Sprachmodell vorwärts oder rückwärts sein sollte, können nur Einweg-Einweg-Informationen verwendet werden. Daher ist es schwierig, den Kontext gleichzeitig in beide Richtungen zu verstehen.
RNNLM, ELMO sind ein typisches Beispiel für autoregressives Sprachmodell, und in diesem Repo werden unidirektionale/bidirektionale LSTM -Sprachmodelle behandelt.
Wikipedia verteilt regelmäßig das gesamte Dokument. Sie können hier den koreanischen Wikipedia -Dump (und englische Wikipedia -Dump hier) herunterladen. Wikipedia empfiehlt die Verwendung von pages-articles.xml.bz2 , die nur die neueste Version des gesamten Dokuments enthält und ungefähr 600 MB komprimiert ist (für englische pages-articles-multistream.xml.bz2 ).
Sie können mit wikipedia_ko.sh Skript den Dump im neuesten koreanischen Wikipedia -Dokument herunterladen. Verwenden Sie für Englisch wikipedia_en.sh
Beispiel:
$ cd build_corpus
$ chmod 777 wikipedia_ko.sh
$ ./wikipedia_ko.sh
Der heruntergeladene Dump verwendet mit dem obigen Shell -Skript befindet sich im XML -Format und wir müssen XML in Textdatei analysieren. The Python Script WikiExtractor.py in Attardi/Wikiextractor Repo, extrahiert und reinigt Text aus der Müllkippe.
Beispiel:
$ 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>
Der extrahierte Text wird als Textdatei einer bestimmten Größe gespeichert. Um diese zu kombinieren, verwenden Sie build_corpus.py . Der Output corpus.txt enthält 4.277.241 Sätze, 55.568.030 Wörter .
Beispiel:
$ python build_corpus.py > corpus.txt
$ wc corpus.txt
4277241 55568030 596460787 corpus.txt
Jetzt müssen Sie den Korpus zum Training und Testset teilen.
$ 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 합계
Unser Corpus corpus.txt hat 55.568.030 Wörter und 608.221 einzigartige Wörter. Wenn die Mindestfrequenz, die für ein Token in den Wortschatz benötigt wird, auf 3 eingestellt ist, enthält das Wortschatz 297.773 eindeutige Wörter.
Hier verwenden wir den Train Corpus corpus.train.txt , um Vokabular zu bauen. Der vom Train Corpus gebaute Wortschatz enthält 557.627 einzigartige Wörter und 271.503 einzigartige Wörter, die mindestens dreimal erscheinen.
Beispiel:
$ 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
Da die Wortschatzdatei zu groß ist (~ 1,3 GB), um dieses Repo hochzuladen, habe ich sie auf Google Drive hochgeladen.
vocab.train.pkl : [Download] $ 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
Beispiel:
$ python lm_trainer.py --train_corpus build_corpus/corpus.train.txt --vocab vocab.train.pkl --model_type LSTM --batch_size 16
Sie können Ihre eigenen Parameterwerte über Argumenteingaben auswählen.
Das Training eines Modells mit einer einzelnen GPU ist nicht nur sehr langsam, sondern begrenzt auch die Anpassung der Stapelgröße, der Modellgröße und so weiter. Um das Modelltraining mit mehreren GPU zu beschleunigen und ein großes Modell zu verwenden, müssen Sie --multi_gpu Flag wie Belows, einbeziehen. Weitere Informationen finden Sie hier.
Dieser Beispielcode trainiert ein unidirektionales LSTM-Modell auf dem Wikipedia-Korpus unter Verwendung eines parallelen Trainings am 8 * V100 GPUs.
$ 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()
)
)
Dieser Beispielcode trainiert das bidirektionale LSTM-Modell auf dem Wikipedia Corpus unter Verwendung eines parallelen Trainings am 8 * V100 GPU.
$ 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()
)
)
Ein Sprachmodell erfasst die Verteilung über alle möglichen Sätze. Und das beste Sprachmodell ist eines, das das Beste einen unsichtbaren Satz vorhersagt. Verwirrt ist eine sehr häufige Messung, wie gut eine Wahrscheinlichkeitsverteilung unsichtbare Sätze vorhersagt.
Verwirrung : Inverse Wahrscheinlichkeit des gegebenen Satzes, normalisiert durch die Anzahl der Wörter (durch Einnahme geometrischer Mittelwert)
Wie Sie aus der obigen Gleichung erkennen können, wird Verwirrung als die exponentierte negative durchschnittliche Log-Likelihood definiert. Mit anderen Worten, die Maximierung der Wahrscheinlichkeit ist das gleiche wie die Minimierung der Verwirrung.
Und jetzt ist Verwirrung die Metrik, die wir verwenden werden. Eine geringe Verwirrung zeigt an, dass die Wahrscheinlichkeitsverteilung den Satz gut vorhersagt.
| Modell | Verlust | Verwirrung |
|---|---|---|
| Unidirektional-lstm | 3.496 | 33.037 |
| Bidirektional-lstm | 1.896 | 6.669 |
| Bidirektional-lstm-large ( hidden_size = 1024) | 1.771 | 5.887 |