Теперь предварительное обучение языковой модели для понимания языка является важным шагом в контексте НЛП.
Языковая модель будет обучена массовому корпусу, а затем мы можем использовать ее в качестве компонента в других моделях, которые должны обрабатывать язык (например, используя его для задач по нижней части).
Модель Lanugage (LM) отражает распределение по всем возможным предложениям .
В то время как языковое моделирование является типичным неконтролируемым обучением по массовому корпусу, мы превращаем это в последовательность контролируемого обучения в этом репо.
Авторегрессивный языковой модель отражает распределение по сравнению с следующим токеном, основанная на всех предыдущих токенах. Другими словами, он смотрит на предыдущий токен и предсказывает следующий токен.
Цель модели авторегрессии языка выражается в формуле следующим образом:
Поскольку модель авторегрессии языка должна быть вперед или назад, может использоваться только односторонняя информация об одностороннем контексте. Поэтому трудно понять контекст в обоих направлениях одновременно.
RNNLM, ELMO являются типичным примером модели авторегрессии языка, и однонаправленные/двунаправленные языковые модели LSTM рассматриваются в этом репо.
Википедия регулярно распространяет весь документ. Вы можете скачать корейский свалку в Википедии здесь (и английская свалку Википедии здесь). Wikipedia рекомендует использовать pages-articles.xml.bz2 , которая включает только последнюю версию всего документа, и составляет приблизительно 600 МБ сжата (для английского языка, pages-articles-multistream.xml.bz2 ).
Вы можете использовать скрипт wikipedia_ko.sh для загрузки дампа на последнем корейском документе Википедии. Для английского, используйте wikipedia_en.sh
пример:
$ cd build_corpus
$ chmod 777 wikipedia_ko.sh
$ ./wikipedia_ko.sh
Скачанный дамп с использованием сценария Shell Shell находится в формате XML, и нам нужно проанализировать XML в текстовый файл. Сценарий Python WikiExtractor.py в репозиции Attardi/Wikiextractor, извлекает и очищает текст с дампа.
пример:
$ 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>
Извлеченный текст сохраняется в виде текстового файла определенного размера. Чтобы объединить их, используйте build_corpus.py . Выходная corpus.txt содержит 4 277 241 предложения, 55 568 030 слов .
пример:
$ python build_corpus.py > corpus.txt
$ wc corpus.txt
4277241 55568030 596460787 corpus.txt
Теперь вам нужно разделить корпус на набор обучения и набора тестов.
$ 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 합계
Наш Corpus corpus.txt имеет 55 568 030 слов и 608 221 уникальных слов. Если минимальная частота, необходимая для включения токена в словарный запас, установлена на 3, словарь содержит 297 773 уникальных слова.
Здесь мы используем Train Corpus corpus.train.txt для создания словаря. Словарь, построенный Train Corpus, содержит 557 627 уникальных слов и 271 503 уникальных слов, которые появляются не менее трех раз.
пример:
$ 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
Поскольку файл словаря слишком велик (~ 1,3 ГБ) для загрузки в этом репо, я загрузил его на Google Drive.
vocab.train.pkl : [Скачать] $ 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
пример:
$ python lm_trainer.py --train_corpus build_corpus/corpus.train.txt --vocab vocab.train.pkl --model_type LSTM --batch_size 16
Вы можете выбрать свои собственные значения параметров с помощью вводов аргументов.
Обучение модели с одним графическим процессором не только очень медленное, но и ограничивает регулировку размера партии, размера модели и так далее. Чтобы ускорить обучение моделя с несколькими графическими процессорами и использовать большую модель, вы должны включить флаг --multi_gpu как Cellows. Для получения более подробной информации, пожалуйста, проверьте здесь.
Этот пример кода обучает однонаправленную модель LSTM на корпусе Википедии, используя параллельное обучение на 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()
)
)
Этот пример кода обучает модель двунаправленной LSTM на корпусе Википедии, используя параллельное обучение на графических процессорах 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()
)
)
Языковая модель отражает распределение по всем возможным предложениям. И лучшая языковая модель - это то, что лучше всего предсказывает невидимое предложение. Озадаченная озадачника - это очень распространенное измерение того, насколько хорошо распределение вероятностей предсказывает невидимые предложения.
Смущение : обратная вероятность данного предложения, нормализованная по количеству слов (путем получения геометрического среднего)
Как вы можете видеть из вышеуказанного уравнения, недоумение определяется как экспонент с отрицательным средним логарифмическим положением. Другими словами, максимизация вероятности - это то же самое, что минимизация недоумения.
И теперь, недоумение - это показатель, который мы будем использовать. Низкое недоумение указывает на то, что распределение вероятностей хорошо предсказывает предложение.
| Модель | Потеря | Недоумение |
|---|---|---|
| Однонаправленный-LSTM | 3.496 | 33,037 |
| ДИСТИНАЛЬНЫЙ ЛИСТ | 1.896 | 6.669 |
| Двунаправленный-LSTM-Large ( hidden_size = 1024) | 1.771 | 5.887 |