基于双向语言模型的上下文化单词表示的tensorflow实现

bilm的Python项目详细描述


bilm tf

用于elmo计算的预训练bilm的tensorflow实现 来自"深层上下文化单词表示"

此存储库支持训练BILMS和使用预先训练的模型进行预测。

我们还有一个pytorch实现,可以在allennlp中找到。

如果您只是想进行预测,您可能会发现使用tensorflow hub中提供的版本更容易。

引文:

@inproceedings{Peters:2018,
  author={Peters, Matthew E. and  Neumann, Mark and Iyyer, Mohit and Gardner, Matt and Clark, Christopher and Lee, Kenton and Zettlemoyer, Luke},
  title={Deep contextualized word representations},
  booktitle={Proc. of NAACL},
  year={2018}
}

安装

安装python版本3.5或更高版本,tensorflow版本1.2和h5py:

pip install tensorflow-gpu==1.2 h5py
python setup.py install

通过运行以下命令确保测试在您的环境中通过:

python -m unittest discover tests/

使用Docker安装

要运行映像,必须使用nvidia docker,因为此存储库 需要GPU。

sudo nvidia-docker run -t allennlp/bilm-tf:training-gpu

使用预先培训的模型

我们有几个不同的英语语言预先训练的bilm可供使用。 每个模型都由两个单独的文件指定,一个json格式的"选项" 带有超参数的文件和带有模型的hdf5格式的文件 砝码。在这里可以找到预先培训的模型的链接

根据您的用例,有三种方法可以将elmo表示集成到下游任务中。

  1. 使用字符输入从原始文本动态计算表示。这是最通用的方法,可以处理任何输入文本。它也是计算上最昂贵的。
  2. 预计算并缓存上下文无关的令牌表示,然后使用BILSTM计算输入数据的上下文相关表示。此方法的计算成本低于1,但仅适用于固定的、指定的词汇表。
  3. 预计算整个数据集的表示并保存到文件。
  4. < > >

    在过去,我们已经将所有这些方法用于各种用例。#1是在测试时评估未公开数据(如公开小组排行榜)所必需的。#对于3中文件大小不可行的大型数据集来说,2是一个很好的折衷方案(snli,squad)。#对于较小的数据集或是在其他框架中使用elmo的情况下,3是一个不错的选择。

    在所有情况下,流程大致遵循相同的步骤。 首先,创建批处理程序(或标记批处理程序,用于2)将标记化字符串转换为字符(或标记)id的numpy数组。 然后,加载预训练的elmo模型(classbidirectionallangagemodel)。 最后,对于步骤1和步骤2,使用weight\u layers计算最终的elmo表示。 对于3,使用bidirectionallangagemodel将所有中间层写入文件。

    形状惯例

    每个标记化的句子都是一个str列表,包含一批句子 标记化句子的列表(list[list[str])。

    批处理程序将它们打包成一个形状 (n个句子,最大句子长度+2,50)numpy字符数组 id,对于小于最大值的句子,在右侧填充0 id 长度。每个句子的第一个和最后一个标记是特殊的 由批处理程序添加的句子id的开头和结尾

    输入字符id占位符可以被标注为(none,none,50), 同时确定批次维度(轴=0)和时间维度(轴=1) 对于每个批次,增加 bidirectionallangagemodel构造函数。

    在对批处理运行推断之后,返回的bilm嵌入是 具有形状的numpy数组(n_语句,3,max_语句长度,1024), 删除特殊的开始/结束标记后。

    词汇文件

    批处理程序为提高效率而输入的ry文件。这是一个 文本文件,每行一个标记,用新行分隔(\n)。 词汇表中的每个标记都缓存为适当的50个字符的id 顺序一次。由于模型完全基于字符,因此标记不在 词汇表文件在运行时被适当地处理,只需稍微 减少运行时间。建议始终包括 <;s>;和词汇文件中的标记(区分大小写)。

    带字符输入的elmo

    有关详细的用法示例,请参见usage\u character.py

    具有预先计算和缓存的上下文无关令牌表示的elmo

    为了使用固定的、指定的词汇表加速模型推理,可以 可以预先计算上下文无关的令牌表示, 将它们写入一个文件中,并重新使用它们进行推理。注意我们没有 支持词汇量不足的单词返回字符输入, 因此,只有当bilm用于计算嵌入时,才应该使用这个函数。 用于输入固定的、定义好的词汇。

    使用此选项:

    1. 首先创建一个词汇表文件,其中包含 数据集并添加特殊的<;s>;<;s>;标记。
    2. 使用完整模型运行dump_token_embeddings 嵌入到HDF5文件。
    3. 在词汇表文件中使用TokenBatcher(而不是Batcher), 并传递use_token_inputs=false和步骤中输出文件的名称 2到双向语言模型构造函数。
    4. < > >

      有关详细的用法示例,请参见usage\u token.py

      将整个数据集的bilm嵌入转储到单个文件。

      要使用此选项,请使用标记化数据集创建文本文件。每一行是一个标记化的句子(空格分隔)。然后使用dump bilm\u嵌入

      输出文件是hdf5格式。输入数据中的每个句子都存储为一个数据集,其中键str(sentence_id)其中sentence_id是数据集文件中的行号(从0开始索引)。 每个句子的嵌入是一个shape(3,n_tokens,1024)数组。

      有关详细示例,请参见usage\u cached.py

      在新的语料库上训练bilm

      广义地说,培训和使用新的bilm的过程是:

      1. 准备输入数据和词汇文件。
      2. 训练比尔姆。
      3. 在直升机数据上测试(计算复杂性)。
      4. 将重量从经过训练的bilm写入hdf5文件。
      5. 有关在下游型号中使用步骤4的输出,请参阅上面的说明。
      6. < > > <H4>1。准备输入数据和词汇文件。

        要培训和评估bilm,您需要提供:

        • 词汇表文件
        • 一套培训文件
        • 一组heldout文件

        词汇表文件是一个文本文件,每行有一个标记。它还必须包括文件中的特殊标记<;s>;<;/s>;<;unk>;(区分大小写)。

        重要信息:词汇表文件应按训练数据中的标记计数降序排序。前三行应该是特殊标记(<;s>;<;<;unk>;),然后是训练数据中最常用的标记,以最不常用的标记结尾。

        注意:培训中使用的词汇文件可能与预测中使用的词汇文件不同。

        训练数据应随机分成多个训练文件, 每个包含一个数据片段。每个文件都包含预标记和 空格分隔文本,每行一句话。 不要在培训数据中包含<;s>;<;s>;标记。

        所有标记化/nor恶意化是在训练一个模型之前完成的,所以 词汇表文件和培训文件应该包括规范化的标记。 由于默认设置使用完全基于字符的标记表示,通常我们不建议除标记化以外的任何规范化。

        最后,保留少量的训练数据作为heldout数据,用于评估训练的bilm。

        <H4>2。训练bilm。

        用于训练elmo模型的超参数可以在bin/train\u elmo.py

        elmo模型是在3个gpu上训练的。 要使用相同的超参数训练新模型,请首先从10亿字基准中下载训练数据。 然后下载词汇文件。 最后,运行:

        export CUDA_VISIBLE_DEVICES=0,1,2
        python bin/train_elmo.py \
            --train_prefix='/path/to/1-billion-word-language-modeling-benchmark-r13output/training-monolingual.tokenized.shuffled/*' \
            --vocab_file /path/to/vocab-2016-09-10.txt \
            --save_dir /output_path/to/checkpoint
        
        <H4>3。评估训练模型。

        使用bin/run\u test.py评估经过培训的模型,例如

        export CUDA_VISIBLE_DEVICES=0
        python bin/run_test.py \
            --test_prefix='/path/to/1-billion-word-language-modeling-benchmark-r13output/heldout-monolingual.tokenized.shuffled/news.en.heldout-000*' \
            --vocab_file /path/to/vocab-2016-09-10.txt \
            --save_dir /output_path/to/checkpoint
        
        <H4>4。使用bilmallennlp将tensorflow检查点转换为hdf5进行预测

        首先,为新训练的模型创建一个options.json文件。这样做, 遵循现有文件中的模板(例如原始的选项.json并修改超参数。

        重要信息:培训后,请将n_个字符设置为262(见下文)。

        然后运行:

        python bin/dump_weights.py \
            --save_dir /output_path/to/checkpoint
            --outfile /output_path/to/weights.hdf5
        

        常见问题和其他警告

        你能提供训练后的Tensorflow检查点吗?

        TensorFlow检查点可通过下载以下文件获得:

        如何在附加的未标记数据上微调模型?

        首先下载上面的检查点文件。 然后按照"在新语料库上训练bilm"一节中所述准备数据集,但我们将使用现有词汇表文件而不是创建新的词汇表文件。最后,使用脚本bin/restart.py使用新数据集上的现有检查点重新启动培训。 对于小数据集(例如1000万个令牌),我们只建议调整少量的时间段并监视heldout集上的困惑,否则模型将过适合小数据集。

        SoftMax重量是否可用?

        它们在上面的培训检查站提供。

        你能提供更多关于模特是如何训练的细节吗?

        脚本bin/train_elmo.py有用于训练模型的超参数。 最初的模型在3gtx 1080上训练了10个阶段,大约需要 两周。

        对于输入处理,我们使用原始的10亿字基准数据集 这里,以及现有的793471个令牌词汇表,包括<;s>;<;s>;<;unk>;。 您可以在这里找到我们的词汇文件。 在模型输入时,所有文本都使用基于全字符的表示, 包括歌手之外的标记。 对于SoftMax输出,我们将OOV令牌替换为<;unk>;

        该模型使用20个令牌的固定大小窗口进行训练。 这些批是通过在句子中填充<;s>;<;s>;来构建的,然后将一个或多个句子中的标记打包到每一行中,以完全填充每个批。 部分语句和lstm状态被从一个批传递到另一个批,这样语言模型就可以使用跨批的信息作为上下文,但是在每个批边界处都会破坏反向传播。

        如果我在预先训练的模型中运行相同的文本两次,为什么会得到稍微不同的嵌入?

        作为训练方法(见上文)的结果,lstms是有状态的,并将其状态从一个批传递到另一个批。 因此,这引入了少量的非决定论,特别是 前两批。

        为什么即使是我的小数据集,培训似乎也要花很长时间?

        训练过程中渐变更新的次数由确定:

        请确保在bin/train\u elmo.py中为您的特定数据集设置这些值。

        字符和填充有什么关系?

        在培训过程中,我们通过在每个句子中添加<;s>;<;s>;来将每一批中的标记填充到正好20个标记,然后将一个或多个句子中的标记打包到每一行中,以完全填充每一批。 因此,我们不为特殊的填充标记分配空间。 将标记字符串转换为字符列表的UnicodeChars词汇表 ids总是使用固定数量的字符嵌入n_characters=261,因此总是 在训练过程中设置n_characters=261

        但是,为了预测,我们确保每个句子都完全包含在一个批中, 结果是用一个特殊的填充id填充不同长度的句子。 这发生在批处理程序中请参见此处。 因此,在options.json的预测过程中,设置n_characters=262

        如何使用elmo计算句子表示?

        简单的方法,如单词级elmo表示在句子中的平均和最大池,效果很好,通常在基准数据集上优于有监督的方法。 参见"下游和语言探测任务中句子嵌入的评估",Perone等人,2018年arxiv链接

        序列化模型时,我看到一个警告,是不是有问题?

        可以安全地忽略以下警告:

        2018-08-24 13:04:08,779 : WARNING : Error encountered when serializing lstm_output_embeddings.
        Type is unsupported, or the types of the items don't match field type in CollectionDef.
        'list' object has no attribute 'name'
        

        欢迎加入QQ群-->: 979659372 Python中文网_新手群

        推荐PyPI第三方库


热门话题
java重写父类中的特定行   java Apache Commons CLI订购帮助选项?   java如何将数据添加到网格视图   java如何在Apache Camel批处理后移动文件?   java如何为日期范围的between子句编写hql查询?   雅加达ee开始Java编程,我应该从哪里开始?   排序Java8+流:检查我的objectinstances的两个字段的列表顺序是否正确   java如何将json转换为Map<String,Object>确保整数为整数   java不能在Spring数据JPA批处理过程中创建TransactionException   java损坏的PDF文件从FTP下载到使用Apache Common Net的设备   java无法使用Spring批处理和Wso2为XML架构命名空间找到Spring NamespaceHandler   java Android ImageView未显示在SherlockFragment中   Maven在构建时出错=无法识别Java路径   java如何使用批处理文件调用关闭处理程序?   java admob广告横幅重叠我的游戏屏幕安卓