이제 언어 이해를위한 언어 모델의 사전 훈련은 NLP의 맥락에서 중요한 단계입니다.
언어 모델은 거대한 코퍼스에서 교육을받은 다음 언어를 처리 해야하는 다른 모델에서 구성 요소로 사용할 수 있습니다 (예 : 다운 스트림 작업에 사용).
Lanugage 모델 (LM)은 가능한 모든 문장에 대한 분포를 캡처합니다.
언어 모델링은 대규모 코퍼스에서 전형적인 감독 학습 이지만, 우리는 이것을이 레포지기에서 감독 된 학습의 시퀀스 로 바꿉니다.
자동 회귀 언어 모델은 다음 토큰의 분포를 캡처합니다. 다시 말해, 이전 토큰을보고 다음 토큰을 예측합니다.
자동 회귀 언어 모델의 목적은 다음과 같이 공식으로 표현됩니다.
자가 회귀 언어 모델은 앞으로 또는 뒤로 있어야하기 때문에 일원 단방향 컨텍스트 정보 만 사용할 수 있습니다. 따라서 양방향으로 컨텍스트를 동시에 이해하기가 어렵습니다.
RNNLM, ELMO는 자동 회귀 언어 모델의 전형적인 예이며, 단방향/양방향 LSTM 언어 모델은 이 repo에서 다룹니다.
Wikipedia는 정기적으로 전체 문서를 배포합니다. 여기에서 한국 Wikipedia 덤프 (및 영어 Wikipedia 덤프를 여기에서 다운로드 할 수 있습니다). Wikipedia는 전체 문서의 최신 버전 만 포함되어 있으며 약 600MB 압축 (영어, pages-articles-multistream.xml.bz2 )을 포함하는 pages-articles.xml.bz2 사용하는 것이 좋습니다.
wikipedia_ko.sh 스크립트를 사용하여 최신 한국 Wikipedia 문서에서 덤프를 다운로드 할 수 있습니다. 영어의 경우 wikipedia_en.sh 사용하십시오
예:
$ cd build_corpus
$ chmod 777 wikipedia_ko.sh
$ ./wikipedia_ko.sh
위의 쉘 스크립트를 사용하여 다운로드 한 덤프는 XML 형식이므로 XML을 텍스트 파일로 구문 분석해야합니다. attardi/wikiextractor repo의 파이썬 스크립트 WikiExtractor.py 는 덤프에서 텍스트를 추출하고 정리합니다.
예:
$ 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.3GB)이 저장소에 업로드하기에는 Google 드라이브에 업로드했습니다.
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
인수 입력을 통해 자신의 매개 변수 값을 선택할 수 있습니다.
단일 GPU로 모델을 훈련시키는 것은 매우 느리게 진행될뿐만 아니라 배치 크기, 모델 크기 등 조정을 제한합니다. 여러 GPU로 모델 교육을 가속화하고 대형 모델을 사용하려면 --multi_gpu 플래그와 같은 벨로그를 포함하는 것입니다. 자세한 내용은 여기를 확인하십시오.
이 예제 코드는 8 * V100 GPU에 대한 병렬 교육을 사용하여 Wikipedia 코퍼스에서 단방향 LSTM 모델을 훈련시킵니다.
$ 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()
)
)
이 예제 코드는 8 * V100 GPU에 대한 병렬 교육을 사용하여 Wikipedia Corpus에서 양방향 LSTM 모델을 훈련시킵니다.
$ 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()
)
)
언어 모델은 가능한 모든 문장에 대한 분포를 캡처합니다. 그리고 최고의 언어 모델은 가장 좋은 언어 모델이 보이지 않는 문장을 예측하는 것입니다. Perplexty는 확률 분포가 보이지 않는 문장을 얼마나 잘 예측하는지에 대한 매우 일반적인 측정입니다.
당황 : 주어진 문장의 역 확률은 단어 수로 정규화됩니다 (기하학적 평균을 취함으로써)
위의 방정식에서 볼 수 있듯이, 당황은 지수화 된 음의 평균 로그-크기 관계로 정의됩니다. 다시 말해, 확률을 극대화하는 것은 당황을 최소화하는 것과 동일합니다.
그리고 지금은 당황 스러움은 우리가 사용할 수있는 지표입니다. 당연 성이 낮 으면 확률 분포가 문장을 예측하는 데 능숙하다는 것을 나타냅니다.
| 모델 | 손실 | 당황 |
|---|---|---|
| 단방향 LSTM | 3.496 | 33.037 |
| 양방향 LSTM | 1.896 | 6.669 |
| Bidirectional-lstm-large ( hidden_size = 1024) | 1.771 | 5.887 |