搜索
您的当前位置:首页正文

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

来源:二三娱乐
新建 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

近年来,研究人员通过文本上下文信息分析获得更好的词向量。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 先从这个地址获取数据
数据比较大,下载的时候先去处理其他部分。

3.1.2 获取词汇

Avoid creating garbage namespace.

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

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

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

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

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

3.2 使用AllenNLP已有的Transformer ELMo模型

"text_field_embedder": {
  "token_embedders": {
    "elmo": {
      "type": "elmo_token_embedder",
      "options_file": 
      "weight_file": 
      "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)

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

Top