Agora, o pré-treinamento do modelo de idioma para o entendimento da linguagem é uma etapa significativa no contexto da PNL.
Um modelo de idioma seria treinado em um corpus enorme e, em seguida, podemos usá -lo como um componente em outros modelos que precisam lidar com a linguagem (por exemplo, usando -a para tarefas a jusante).
Um modelo Lanugage (LM) captura a distribuição sobre todas as frases possíveis .
Embora a modelagem de idiomas seja um aprendizado não supervisionado típico em corpus maciço, transformamos isso em uma sequência de aprendizado supervisionado neste repositório.
O modelo de linguagem autoregressiva captura a distribuição no próximo token é baseado em todo o token anterior. Em outras palavras, ele olha para o token anterior e prevê o próximo token.
O objetivo do modelo de linguagem autoregressiva é expresso em uma fórmula da seguinte maneira:
Como o modelo de idioma autoregressivo deve ser para a frente ou para trás, apenas informações de contexto unidirecional unidirecionais podem ser usadas. Portanto, é difícil entender o contexto em ambas as direções simultaneamente.
RNNLM, ELMO são um exemplo típico de modelo de linguagem autoregressiva e modelos de idiomas LSTM unidirecionais/bidirecionais são abordados neste repositório.
A Wikipedia distribui regularmente o documento inteiro. Você pode fazer o download do dump coreano da Wikipedia aqui (e o despejo da Wikipedia em inglês aqui). A Wikipedia recomenda o uso de pages-articles.xml.bz2 , que inclui apenas a versão mais recente de todo o documento e é de aproximadamente 600 MB comprimido (para inglês, pages-articles-multistream.xml.bz2 ).
Você pode usar o script wikipedia_ko.sh para baixar o despejo no mais recente documento da Wikipedia coreana. Para inglês, use wikipedia_en.sh
exemplo:
$ cd build_corpus
$ chmod 777 wikipedia_ko.sh
$ ./wikipedia_ko.sh
O despejo baixado usando o script do shell acima está no formato XML e precisamos analisar XML para o arquivo de texto. O script python WikiExtractor.py no repositório attardi/wikiextractor, extrai e limpa o texto do despejo.
exemplo:
$ 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>
O texto extraído é salvo como arquivo de texto de um determinado tamanho. Para combiná -los, use build_corpus.py . O corpus.txt de saída contém 4.277.241 frases, 55.568.030 palavras .
exemplo:
$ python build_corpus.py > corpus.txt
$ wc corpus.txt
4277241 55568030 596460787 corpus.txt
Agora, você precisa dividir o corpus para treinar e testar.
$ 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 합계
Nosso corpus corpus.txt tem 55.568.030 palavras e 608.221 palavras únicas. Se a frequência mínima necessária para incluir um token no vocabulário estiver definida como 3, o vocabulário contém 297.773 palavras únicas.
Aqui, usamos o trem corpus corpus.train.txt para criar vocabulário. O vocabulário construído por trem corpus contém 557.627 palavras únicas e 271.503 palavras únicas que aparecem pelo menos três vezes.
exemplo:
$ 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
Como o arquivo de vocabulário é muito grande (~ 1,3 GB) para fazer upload neste repositório, eu o carreguei no Google Drive.
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
exemplo:
$ python lm_trainer.py --train_corpus build_corpus/corpus.train.txt --vocab vocab.train.pkl --model_type LSTM --batch_size 16
Você pode selecionar seus próprios valores de parâmetros por meio de entradas de argumento.
Treinar um modelo com GPU único não é apenas muito lento, mas também limita o ajuste do tamanho do lote, tamanho do modelo e assim por diante. Para acelerar o treinamento de modelos com múltiplas GPU e usar um modelo grande, o que você deve fazer é incluir -sinalizador --multi_gpu como a Bellows. Para mais detalhes, verifique aqui.
Este exemplo de código treina o modelo unidirecional-LSTM no corpus da Wikipedia usando treinamento paralelo em 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()
)
)
Este exemplo de código treina o modelo bidirecional-LSTM no corpus da Wikipedia usando treinamento paralelo em 8 * v100 gpus.
$ 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()
)
)
Um modelo de idioma captura a distribuição sobre todas as frases possíveis. E o melhor modelo de idioma é aquele que melhor prevê uma frase invisível. A perplexidade é uma medida muito comum de quão bem uma distribuição de probabilidade prevê frases invisíveis.
Perplexidade : probabilidade inversa da sentença dada, normalizada pelo número de palavras (tomando a média geométrica)
Como você pode ver na equação acima, a perplexidade é definida como a média da média de log da exponencial. Em outras palavras, maximizar a probabilidade é o mesmo que minimizar a perplexidade.
E agora, a perplexidade é a métrica que vamos usar. Uma baixa perplexidade indica que a distribuição de probabilidade é boa na previsão da frase.
| Modelo | Perda | Perplexidade |
|---|---|---|
| Unidirecional-lstm | 3.496 | 33.037 |
| Bidirecional-lstm | 1.896 | 6.669 |
| Bidirecional-LSTM-Large ( Hidden_size = 1024) | 1.771 | 5.887 |