必威体育Betway必威体育官网
当前位置:首页 > IT技术

ELMo词向量用于中文

时间:2019-08-15 20:11:05来源:IT技术作者:seo实验室小编阅读:86次「手机版」
 

elmo

转载自 http://www.linzehui.me/2018/08/12/碎片知识/如何将ELMo词向量用于中文/


ELMo于今年二月由AllenNLP提出,与word2vec或GloVe不同的是其动态词向量的思想,其本质即通过训练language model,对于一句话进入到language model获得不同的词向量。根据实验可得,使用了Elmo词向量之后,许多NLP任务都有了大幅的提高。

论文:Deep contextualized word representations

AllenNLP一共release了两份ELMo的代码,一份是Pytorch版本的,另一份是Tensorflow版本的。Pytorch版本的只开放了使用预训练好的词向量的接口,但没有给出自己训练的接口,因此无法使用到中文语料中。Tensorflow版本有提供训练的代码,因此本文记录如何将ELMo用于中文语料中,但本文只记录使用到的部分,而不会分析全部的代码。

需求:

使用预训练好的词向量作为句子表示直接传入到RNN中(也就是不使用代码中默认的先过CNN),在训练完后,将模型保存,在需要用的时候load进来,对于一个特定的句子,首先将其转换成预训练的词向量,传入language model之后最终得到ELMo词向量。

准备工作:

  1. 将中文语料分词
  2. 训练好GloVe词向量或者word2vec
  3. 下载bilm-tf代码
  4. 生成词表 vocab_file (训练的时候要用到)
  5. optional:阅读Readme
  6. optional:通读bilm-tf的代码,对代码结构有一定的认识

思路:

  1. 将预训练的词向量读入
  2. 修改bilm-tf代码
    1. option部分
    2. 添加给embedding weight赋初值
    3. 添加保存embedding weight的代码
  3. 开始训练,获得checkpoint和option文件
  4. 运行脚本,获得language model的weight文件
  5. 将embedding weight保存为hdf5文件形式
  6. 运行脚本,将语料转化成ELMo embedding。

训练GloVe或word2vec

可参见我以前的博客或者网上的教程

注意到,如果要用gensim导入GloVe训好的词向量,需要在开头添加num_word embedding_dim。 如:

获得vocab词表文件

注意到,词表文件的开头必须要有<S> </S> <UNK>,且大小写敏感。并且应当按照单词的词频降序排列。可以通过手动添加这三个特殊符号。

如:

代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

model=gensim.models.Keyedvectors.load_word2vec_format(

fname='/home/zhlin/GloVe/vectors.txt',binary=False

)

words=model.vocab

with open('vocab.txt','w') as f:

f.write('<S>')

f.write('\n')

f.write('</S>')

f.write('\n')

f.write('<UNK>')

f.write('\n') # bilm-tf 要求vocab有这三个符号,并且在最前面

for word in words:

f.write(word)

f.write('\n')

修改bilm-tf代码

注意到,在使用该代码之前,需要安装好相应的环境。

如果使用的是conda作为默认的Python解释器,强烈建议使用conda安装,否则可能会出现一些莫名的错误。

1

2

3

conda install tensorflow-gpu=1.4

conda install h5py

python setup.py install #应在bilm-tf的文件夹下执行该指令

然后再运行测试代码,通过说明安装成功。

修改train_elmo.py

bin文件夹下的train_elmo.py是程序的入口。

主要修改的地方:

  1. load_vocab的第二个参数应该改为None
  2. n_gpus CUDA_VISIBLE_DEVICES 根据自己需求改
  3. n_train_tokens 可改可不改,影响的是输出信息。要查看自己语料的行数,可以通过wc -l corpus.txt 查看。
  4. option的修改,将char_cnn部分都注释掉,其他根据自己需求修改

如:

修改LanguageModel类

由于我需要传入预训练好的GloVe embedding,那么还需要修改embedding部分,这部分在bilm文件夹下的training.py,进入到LanguageModel类中_build_word_embeddings函数中。注意到,由于前三个是<S> </S> <UNK>,而这三个字符在GloVe里面是没有的,因此这三个字符的embedding应当在训练的时候逐渐学习到,而正因此 embedding_weightstrainable应当设为True

如:

修改train函数

添加代码,使得在train函数的最后保存embedding文件。

训练并获得weights文件

训练需要语料文件corpus.txt,词表文件vocab.txt。

训练

cd到bilm-tf文件夹下,运行

1

2

3

4

5

export CUDA_VISIBLE_DEVICES=4

nohup python -u bin/train_elmo.py \

--train_prefix='/home/zhlin/bilm-tf/corpus.txt' \

--vocab_file /home/zhlin/bilm-tf/glove_embedding_vocab8.10/vocab.txt \

--save_dir /home/zhlin/bilm-tf/try >bilm_out.txt 2>&1 &

根据实际情况设定不同的值和路径

运行情况:

PS:运行过程中可能会有warning:

‘list’ object has no attribute ‘name’

WARNING:tensorflow:ERROR encountered when serializing lstm_output_embeddings.

Type is unsupported, or the types of the items don’t match field type in CollectionDef.

应该不用担心,还是能够继续运行的,后面也不受影响。

在等待了相当长的时间后,在save_dir文件夹内生成了几个文件,其中checkpoint和options是关键,checkpoint能够进一步生成language model的weights文件,而options记录language model的参数。

获得language model的weights

接下来运行bin/dump_weights.py将checkpoint转换成hdf5文件。

1

2

3

nohup python -u  /home/zhlin/bilm-tf/bin/dump_weights.py  \

--save_dir /home/zhlin/bilm-tf/try \

--outfile /home/zhlin/bilm-tf/try/weights.hdf5 >outfile.txt 2>&1 &

其中save_dir是checkpoint和option文件保存的地址。

接下来等待程序运行:

最终获得了想要的weights和option:

将语料转化成ELMo embedding

由于我们有了vocab_file、与vocab_file一一对应的embedding h5py文件、以及language model的weights.hdf5和options.json。

接下来参考usage_token.py将一句话转化成ELMo embedding。

参考代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

import tensorflow as tf

import os

from bilm import TokenBATcher, BidirectionalLanguageModel, weight_layers, \

dump_token_embeddings

# Our small dataset.

raw_context = [

'这 是 测试 .',

'好的 .'

]

tokenized_context = [sentence.split() for sentence in raw_context]

tokenized_question = [

['这', '是', '什么'],

]

vocab_file='/home/zhlin/bilm-tf/glove_embedding_vocab8.10/vocab.txt'

options_file='/home/zhlin/bilm-tf/try/options.json'

weight_file='/home/zhlin/bilm-tf/try/weights.hdf5'

token_embedding_file='/home/zhlin/bilm-tf/glove_embedding_vocab8.10/vocab_embedding.hdf5'

## Now we can do inference.

# Create a TokenBatcher to map text to token ids.

batcher = TokenBatcher(vocab_file)

# Input placeholders to the biLM.

context_token_ids = tf.placeholder('int32', shape=(None, None))

question_token_ids = tf.placeholder('int32', shape=(None, None))

# Build the biLM graph.

bilm = BidirectionalLanguageModel(

options_file,

weight_file,

use_character_inputs=False,

embedding_weight_file=token_embedding_file

)

# Get ops to compute the LM embeddings.

context_embeddings_op = bilm(context_token_ids)

question_embeddings_op = bilm(question_token_ids)

elmo_context_input = weight_layers('input', context_embeddings_op, l2_coef=0.0)

with tf.variable_scope('', reuse=True):

# the reuse=True scope reuses weights from the context for the question

elmo_question_input = weight_layers(

'input', question_embeddings_op, l2_coef=0.0

)

elmo_context_output = weight_layers(

'output', context_embeddings_op, l2_coef=0.0

)

with tf.variable_scope('', reuse=True):

# the reuse=True scope reuses weights from the context for the question

elmo_question_output = weight_layers(

'output', question_embeddings_op, l2_coef=0.0

)

with tf.session() as sess:

# It is necessary to initialize variables once before running inference.

sess.run(tf.global_variables_initializer())

# Create batches of data.

context_ids = batcher.batch_sentences(tokenized_context)

question_ids = batcher.batch_sentences(tokenized_question)

# Compute ELMo representations (here for the input only, for simplicity).

elmo_context_input_, elmo_question_input_ = sess.run(

[elmo_context_input['weighted_op'], elmo_question_input['weighted_op']],

feed_dict={context_token_ids: context_ids,

question_token_ids: question_ids}

)

print(elmo_context_input_,elmo_context_input_)

可以修改代码以适应自己的需求。

Reference

https://github.com/allenai/bilm-tf

相关阅读

英文pdf文件翻译为中文(免费、快速)

前几天阅读一本英文书籍,但是有一些晦涩难懂,网上又找不到直接的中文翻译版本,一段段的复制到谷歌翻译又觉得太麻烦,找了好久终于找到

xmanager enterprise 5中文破解版下载(附产品密钥)

xmanager 5破解版是一款功能强大的远程桌面管理软件,广泛用于各种领域的工作,包括大型工艺与半导体和服务器管理设计的IDC(互联网数

ubuntu 16.04中文输入法安装

转自: http://blog.csdn.net/u011795345/article/details/53041707最近刚给笔记本装了Ubuntu+win10双系统,但是ubuntu16.04没有自带

Axure 8.0中文版下载(支持windows和Mac)

期待已久的Axure 8.0已经发布,今天小编妹妹收集了MAC/windows版下载地址给大家,产品汪/设计湿/交互喵&#8230;.赶紧围观过来。Axure

Synonyms: 中文近义词工具包

Synonyms Chinese Synonyms for Natural Language Processing and Understanding. 最好的中文近义词工具包: https://github.com

分享到:

栏目导航

推荐阅读

热门阅读