美文网首页Machine Learning & Recommendation & NLP & DL
自然语言处理N天-AllenNLP学习(如何训练并使用一个Tra

自然语言处理N天-AllenNLP学习(如何训练并使用一个Tra

作者: 我的昵称违规了 | 来源:发表于2019-04-02 09:54 被阅读6次
新建 Microsoft PowerPoint 演示文稿 (2).jpg

我又回来了,Pytorch的学习也是为了熟悉AllenNLP结构,所以,在完成基础tutorial之后又折回来继续学AllenNLP。四月份的目标是复现那篇论文中的结构并使用Finetuning完成Transformer。
今天开始AllenNLP入门的第二部分How-to。总共包括七个小节。

  • 如何使用json配置向导
  • 如何使用Lazy Data训练模型
  • How to train and use a Transformer-based ELMo
  • How to Debug Your AllenNLP Code
  • How to visualize model internals (BETA)
  • Using pre-trained ELMo representations
  • Using span representations

3. 如何训练并使用一个Transformer ELMo

在第三节,学习训练一个Transformer ELMo。ELMo是AllenNLP的成名之作,在2018年的NAACL上,outstanding paper award。
首先,什么是EMLo?

ELMo

Embeddings from Language Models
以下摘自ELMo最好用词向量Deep Contextualized Word Representations

近年来,研究人员通过文本上下文信息分析获得更好的词向量。ELMo是其中的翘楚,在多个任务、多个数据集上都有显著的提升。所以,它是目前最好用的词向量,the-state-of-the-art的方法。
ELMo的优势

  • ELMo能够学习到词汇用法的复杂性,比如语法、语义。
  • ELMo能够学习不同上下文情况下的词汇多义性。

ELMo模型基于大量文本,从深层的双向语言模型(deep bidirectional language model)中的内部状态(internal state)学习而来的。其效果如下:

  • Textual entailment: stanford natural language inference (SNLI)数据集上提升了1.4%。
  • Question answering: 在stanford question answering dataset (SQuAD)数据集上提升了4.2%,将ELMo加入到之前的state-of-the-art的ensemble模型中,提升了10%。
  • Semantic role labeling: 比之前的state-of-the-art模型提高了3.2%,将ELMo加入到之前的state-of-the-art的单模型中,提升了1.2%。
  • Coreference resolution: 比之前的state-of-the-art模型提高了3.2%,将ELMo加入到之前的state-of-the-art的ensemble模型中,提升了1.6%。
  • Named entity extraction: 在CoNLL 2003 NER task数据机上提高了2.06%
  • Sentiment analysis: 比之前的state-of-the-art模型提高了3.3%,将ELMo加入到之前的state-of-the-art模型中,提升了1%。

以下进入正文。

本文描述的是如何通过AllenNLP训练并使用一个基于Transformer的ELMo。模型使用该模型是Peters等人在Dissecting Contextual Word Embeddings:Architecture and Representation中描述的端口。

3.1 训练

3.1.1 先从这个地址获取数据
数据比较大,下载的时候先去处理其他部分。

http://www.statmt.org/lm-benchmark/1-billion-word-language-modeling-benchmark-r13output.tar.gz

3.1.2 获取词汇

mkdir vocabulary
export BIDIRECTIONAL_LM_VOCAB_PATH=PWD'/vocabulary' cdBIDIRECTIONAL_LM_VOCAB_PATH
aws --no-sign-request s3 cp s3://allennlp/models/elmo/vocab-2016-09-10.txt .
cat vocab-2016-09-10.txt | sed 's/<UNK>/@@UNKNOWN@@/' > tokens.txt

Avoid creating garbage namespace.

rm vocab-2016-09-10.txt
echo 'labels\ntags' > non_padded_namespaces.txt

3.1.3 进行训练
多进程数据集读取器和迭代器使用许多文件描述符,所以在这里增加相关的ulimit以提供帮助。
有关基础问题的说明,请参阅https://pytorch.org/docs/stable/multiprocessing.html#file-descriptor-file-descriptor#。
训练命令

allennlp train training_config/bidirectional_language_model.jsonnet --serialization-dir output_path

3.1.4 等待
需要等待好些天,而且这个模型的训练只进行了4次迭代

3.1.5 评价
评估。这里有一个问题,就是我们放弃3个句子太长时间(否则我们会耗尽GPU内存)。如果我们想要正式报告这个数字(在论文或类似文件中),我们需要以不同的方式处理这个问题。
评价命令

allennlp evaluate --cuda-device 0 -o '{"iterator": {"base_iterator": {"maximum_samples_per_batch": ["num_tokens", 500] }}}' output_path/model.tar.gz $BIDIRECTIONAL_LM_DATA_PATH/heldout-monolingual.tokenized.shuffled/news.en-00000-of-00100
作者列举了4词迭代后的结果,真的是拼,5点多出来,连夜跑的吧。
2018-12-12 05:42:53,711 - INFO - allennlp.commands.evaluate - loss: 3.745238332322373
ipython
In [1]: import math; math.exp(3.745238332322373) # To compute perplexity
Out[1]: 42.3190920245054

看到这里是不是心凉了,作者很皮,其实AllenNLP已经有训练好的模型,虽然是英文的……

3.2 使用AllenNLP已有的Transformer ELMo模型

使用Transformer ELMo与使用常规ELMo基本相同,这篇文档有详细说明。只有一个不同是在text_field_embedder 部分,需要将以下部分进行替换

"text_field_embedder": {
  "token_embedders": {
    "elmo": {
      "type": "elmo_token_embedder",
      "options_file": "https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/elmo_2x4096_512_2048cnn_2xhighway_options.json",
      "weight_file": "https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/elmo_2x4096_512_2048cnn_2xhighway_weights.hdf5",
      "do_layer_norm": false,
      "dropout": 0.5
    }
  }
},

替换为

"text_field_embedder": {
  "token_embedders": {
    "elmo": {
      "type": "bidirectional_lm_token_embedder",
      "archive_file": std.extVar('BIDIRECTIONAL_LM_ARCHIVE_PATH'),
      "dropout": 0.2,
      "bos_eos_tokens": ["<S>", "</S>"],
      "remove_bos_eos": true,
      "requires_grad": false
    }
  }
},

会发现,在type部分改为bidirectional_lm_token_embedder。那么是不是可以直接调用呢?

3.3 直接调用 BidirectionalLanguageModelTokenEmbedder

当然可以,用户可以直接调用 bidirectional_lm_token_embedder。


from allennlp.modules.token_embedders.bidirectional_language_model_token_embedder import BidirectionalLanguageModelTokenEmbedder
from allennlp.data.token_indexers.elmo_indexer import ELMoTokenCharactersIndexer
from allennlp.data.tokenizers.token import Token
import torch

lm_model_file = "output_path/model.tar.gz"

sentence = "It is raining in Seattle ."
tokens = [Token(word) for word in sentence.split()]

lm_embedder = BidirectionalLanguageModelTokenEmbedder(
    archive_file=lm_model_file,
    dropout=0.2,
    bos_eos_tokens=["<S>", "</S>"],
    remove_bos_eos=True,
    requires_grad=False
)

indexer = ELMoTokenCharactersIndexer()
vocab = lm_embedder._lm.vocab
character_indices = indexer.tokens_to_indices(tokens, vocab, "elmo")["elmo"]

# Batch of size 1
indices_tensor = torch.LongTensor([character_indices])

# Embed and extract the single element from the batch.
embeddings = lm_embedder(indices_tensor)[0]

for word_embedding in embeddings:
    print(word_embedding)

这里缺少数据加载和批处理机制,如果要使用的话还需要增加。

相关文章

网友评论

    本文标题:自然语言处理N天-AllenNLP学习(如何训练并使用一个Tra

    本文链接:https://www.haomeiwen.com/subject/fpkwbqtx.html