狄东林 刘元兴 朱庆福 胡景雯作家刘元兴本期编辑崔一鸣本期义务编辑

四种常睹NLP框架运用总结

小序

跟着人工智能的开展,越来越众深度进修框架如雨后春笋般呈现,比如PyTorch、TensorFlow、Keras、MXNet、Theano和PaddlePaddle等。这些根底框架供应了构修一个模子需求的基本通用东西包。可是关于NLP相关的义务,我们往往需求本人编写大宗比较繁琐的代码,包罗数据预处理和教练进程中的东西等。于是,大师一般基于NLP相关的深度进修框架编写本人的模子,如OpenNMT、ParlAI和AllenNLP等。借帮这些框架,三两下就可以完成一个NLP相关根底义务的教练和预测。可是当我们需求对根底义务举行改动时,又被代码封装束缚,举步维艰。于是,本文主要针关于怎样运用框架完成自定义模子,帮帮大师疾速了解框架的运用方法。

我们起首先容广泛用于NLP/CV范畴的TensorFlow框架——Tensor2Tensor,该框架供应了NLP/CV范畴中常用的基本模子。然后先容NLP范畴的AllenNLP框架,该框架基于PyTorch平台开辟,为NLP模子供应了同一的开辟架构。叫∨先容NLP范畴中主要的两个子范畴,神经板滞翻译对话系统常用的框架,OpenNMT和ParlAI。通过这四个框架的先容,期望能帮帮大师了解差别开辟平台,差别范畴下的NLP框架的运用方法。

框架名称运用范畴开辟平台
Tensor2TensorNLP/CVTensorFlow
AllenNLPNLPPyTorch
OpenNMTNLP-板滞翻译PyTorch/TensorFlow
ParlAINLP-对话PyTorch

一、Tensor2Tensor

Tensor2Tensor[1]是一个基于TensorFlow的较为归纳性的库,既包罗少许CV 和 NLP的基本模子,如LSTM,CNN等,也供应少许稍微高级一点的模子,如各式各样的GAN和Transformer。对NLP的各项义务支撑得都比较厉密,很便当容易上手。

因为该资源库仍处于不时开辟进程中,截直タ前为止,曾经有3897次commit,66个release 版本,178 contributors。2018年《Attention is all you need》这个全网热文中,该堆栈是官方供应的Transformer模子版本,后面陆延续续其余平台架构才渐渐增补完毕。

Tensor2Tensor(Transformer)运用方法

当心:有可以跟着版本迭代更新的进程中会有部分改动

安装状况

1. 安装CUDA 9.0 (必定是9.0,不行是9.2)

2. 安装TensorFlow (现是1.12)

3. 安装Tensor2Tensor (参考官网安装)

开端运用

1. 数据预处理

这一方法是依据本人义务本人编写少许预处理的代码,比如字符串样式化,生成特征向量等操作。

2. 编写自定义problem:

  • 编写自定义的problem代码,必定需求自定义类名前加掩饰器(@registry.registry_problem)。

  • 自定义problem的类名必定是驼峰式命名,py文献名必定是下划线式命名,且与类名对应。

  • 必定需求承袭父类problem,t2t曾经供应用于生成数据的problem,需求自行将本人的题目人脑分类找到对应的父类,主要定义的父类problem有:(运转 t2t-datagen 可以查看到problem list)。

  • 必定需求__init__.py文献里导入自定义problem文献。

3. 运用t2t-datagen 将本人预处理后的数据转为t2t的样式化数据集【当心道径】

  • 运转 t2t-datagen --help 或 t2t-datagen --helpfull。比如:

1cdscripts&&t2t-datagen--t2t_usr_dir=./--data_dir=../train_data--tmp_dir=../tmp_data--problem=my_problem
  • 假如自定义problem代码的输特别式不准确,则此命令会报错

4. 运用t2t-trainer运用样式化的数据集举行教练

  • 运转t2t-trainer --help 或 t2t-trainer --helpfull。比如:

1cdscripts&&t2t-trainer--t2t_usr_dir=./--problem=my_problem--data_dir=../train_data--model=transformer--hparams_set=transformer_base--output_dir=../output--train_steps=20--eval_steps=100

5. 运用t2t-decoder对测试集举行预测【当心道径】

  • 假如念运用某一个checkpoint时的结果时,需求将checkpoint文献中的第一行: model_checkpoint_path: “model.ckpt-xxxx” 的着末的序号改正即可。比如:

1cdscripts&&t2t-decoder--t2t_usr_dir=./--problem=my_problem--data_dir=../train_data--model=transformer--hparams_set=transformer_base--output_dir=../output--decode_hparams=”beam_size=5,alpha=0.6”--decode_from_file=../decode_in/test_in.txt--decode_to_file=../decode_out/test_out.txt

6. 运用t2t-exporter导出教练模子

7. 剖析结果

附: (全体代码)
 1#coding=utf-8
 2fromtensor2tensor.utilsimportregistry
 3fromtensor2tensor.data_generatorsimportproblem,text_problems
 4
 5@registry.register_problem
 6classAttentionGruFeature(text_problems.Text2ClassProblem):
 7
 8ROOT_DATA_PATH='../data_manager/'
 9PROBLEM_NAME='attention_gru_feature'
10
11@property
12defis_generate_per_split(self):
13returnTrue
14
15@property
16defdataset_splits(self):
17return[{
18"split":problem.DatasetSplit.TRAIN,
19"shards":5,
20},{
21"split":problem.DatasetSplit.EVAL,
22"shards":1,
23}]
24
25@property
26defapprox_vocab_size(self):
27return2**10#8kvocabsufficesforthissmalldataset.
28
29@property
30defnum_classes(self):
31return2
32
33@property
34defvocab_filename(self):
35returnself.PROBLEM_NAME+".vocab.%d"%self.approx_vocab_size
36
37defgenerate_samples(self,data_dir,tmp_dir,dataset_split):
38deldata_dir
39deltmp_dir
40deldataset_split
41
42#withopen('{}self_antecedent_generate_sentences.pkl'.format(self.ROOT_DATA_PATH),'rb')asf:
43##getallthesentencesforantecedentidentification
44#_sentences=pickle.load(f)
45#
46#for_sentin_sentences:
47###sumpooling,FloatTensor,Size:400
48##_sent.input_vec_sum
49###sumpoolingwithfeature,FloatTensor,Size:468
50##_sent.input_vec_sum_feature
51###GRU,FloatTensor,Size:6100
52##_sent.input_vec_hidden
53###GRUwithfeature,FloatTensor,Size:6168
54##_sent.input_vec_hidden_feature
55###AttentionGRU,FloatTensor,Size:1600
56##_sent.input_vec_attention
57###AttentionGRUwithfeature,FloatTensor,Size:1668
58##_sent.input_vec_attention_feature
59###tag(1forpositivecase,and0fornegativecase),Int,Size:1
60##_sent.antecedent_label
61###tag(1forpositivecase,and0fornegativecase),Int,Size:1
62##_sent.trigger_label
63###triggerwordfortheerroranalysis,Str
64##_sent.trigger
65###triggerwordauxiliarytypefortheexperiment,Str
66##_sent.aux_type
67###theoriginalsentencefortheerroranalysis,Str
68##_sent.sen
69#
70#yield{
71#"inputs":_sent.input_vec_attention_feature,
72#"label":_sent.antecedent_label
73#}
74
75withopen('../prep_ante_data/antecedent_label.txt')asantecedent_label,open(
76'../prep_ante_data/input_vec_attention_gru_feature.txt')asinput_vec:
77forlabalinantecedent_label:
78yield{
79"inputs":input_vec.readline().strip()[1:-2],
80"label":int(labal.strip())
81}
82
83antecedent_label.close()
84input_vec.close()
85
86
87#PROBLEM_NAME='attention_gru_feature'
88#DATA_DIR='../train_data_atte_feature'
89#OUTPUT_DIR='../output_atte_feature'
90#t2t-datagen--t2t_usr_dir=.--data_dir=$DATA_DIR--tmp_dir=../tmp_data--problem=$PROBLEM_NAME
91#t2t-trainer--t2t_usr_dir=.--data_dir=$DATA_DIR--problem=$PROBLEM_NAME--model=transformer--hparams_set=transformer_base--output_dir=$OUTPUT_DIR

Tensor2Tensor运用总结

T2T 是Google 非官方供应的堆栈,是社区宽广喜好者配合起劲修设的简单初学型框架,底层封装TF,能满意阵势部CV 和 NLP的义务,许众主流成熟的模子也曾经都有完成。直接承袭或完成少许框架内预设的接口,就可以完毕许众义务。初学起来十分友好,而且文档更新也较为及时。认真阅读文档(或阅读报错新闻)就可以了解并运用该框架,便当许众非大幅立异模子的复现。

二、AllenNLP

AllenNLP是一个基于PyTorch的NLP研讨库,可为开辟者供应言语义务中的种种业内最佳教练模子。官网供应了一个很好的初学教程[2],可以让初学者30分钟内就了解AllenNLP的运用方法。

AllenNLP运用方法

因为AllenNLP曾经帮我们完成许众麻烦琐碎的预处理和教练框架,我们实行需求编写的只要:

1. DatasetReader

DatasetReader的示例代码如下所示。

 1fromtypingimportDict,Iterator
 2
 3fromallennlp.dataimportInstance
 4fromallennlp.data.fieldsimportTextField
 5fromallennlp.data.dataset_readersimportDatasetReader
 6fromallennlp.data.token_indexersimportTokenIndexer,SingleIdTokenIndexer
 7fromallennlp.data.tokenizersimportWordTokenizer,Tokenizer
 8
 9@DatasetReader.register('custom')
10classCustomReader(DatasetReader):
11
12def__init__(self,tokenizer:Tokenizer=None,token_indexers:Dict[str,TokenIndexer]=None)->None:
13super().__init__(lazy=False)
14self.tokenizer=tokenizerorWordTokenizer()
15self.word_indexers=token_indexersor{"word":SingleIdTokenIndexer('word')}
16
17deftext_to_instance(self,_input:str)->Instance:
18fields={}
19tokenized_input=self.tokenizer.tokenize(_input)
20fields['input']=TextField(tokenized_input,self.word_indexers)
21returnInstance(fields)
22
23def_read(self,file_path:str)->Iterator[Instance]:
24withopen(file_path)asf:
25forlineinf:
26yieldself.text_to_instance(line)

起首需求自定义_read函数,写好读取数据集的方法,通过yield方法返回构修一个instance需求的文本。然后通过text_to_instance函数将文本转化为instancetext_to_instance函数中,需求对输入的文本举行切分,然后构修fileld

self.tokenizer是用来切分文本成Token的。有Word级另外也有Char级另外。self.word_indexers是用来索引Token并转换为Tensor。同样TokenIndexer也有许众种,完成本人的模子之前可以看看官方文档有没有比较契合本人需求的类型。假如你需求构修众个Vocabulary,比如源言语的vocab 和目标言语的vocab, 就需求这里众定义一个self.word_indexers。差别indexersvocab中,是通过SingleIdTokenIndexer函数初始化的namespace来辨另外,也便是15行代码中着末一个的'word'

2. Model

与PyTorch完成model的方法相同,但需求当心的是:

@Model.register('') 注册之后可以运用JsonNet举行模子挑选(假如你有众个模子,可以直接改正Json值劳仆谢,不需求手动改正代码)。

因为AllenNLP封装了Trainer,以是我们需求model内完成或者挑选已有的评判目标,如许教练进程中就会主动盘算评判目标。精细方法是,__init__方法中定义评判函数,可以从官方文档[3]上看看有没有,假如没有的话就需求本人写。

1self.acc=CategoricalAccuracy()

然后forward方法中调用评判函数盘算目标

1self.acc(output,labels)

着末model的get_metrics返回对应目标的dict结果就行了。

1defget_metrics(self,reset:bool=False)->Dict[str,float]:
2return{"acc":self.acc.get_metric(reset)}
3. Trainer

一般来说直接调用AllenNLP的Trainer方法就可以主动开端教练了。可是假如你有少许特别的教练方法,比如GAN[4],你就不行纯粹地运用AllenNLP的Trainer,得把Trainer翻开举行每步的迭代,可以参考[4]中trainer的写法。

AllenNLP运用总结

关于AllenNLP的进修代码,可以参考[5]。因为AllenNLP是基于PyTorch的,代码立场和PyTorch的立场基本同等,于是假如你会用PyTorch,那上手AllenNLP基本没有什么妨碍。代码解释方面也比较全,模块封装方面比较灵敏。AllenNLP的代码十分容易改动,就像用纯的PyTorch相同灵敏。当然灵敏也就意味着许众繁杂的完成,AllenNLP目前还没有,阵势部可以都需求本人写。AllenNLP依赖了许众Python库,近期也更新。

三、OpenNMT

OpenNMT[6]是一个开源的神经板滞翻译(neural machine translation)项目,采用目前广泛运用的编码器-解码器(encoder-decoder)构造,于是,也可以用来完毕文本摘要、再起生成等其他文本生成义务。目前,该项目曾经开辟出PyTorch、TensorFlow两个版本,用户可以按需采纳。本文以PyTorch版本[7]为例举行先容。

OpenNMT运用方法
1. 数据处理

举措一个典范的板滞翻译框架,OpenNMT的数据主要包罗source和target两部分,对应于板滞翻译中的源言语输入和目标言语翻译。OpenNMT采用TorchText中的Field数据构造来外示每个部分。用户自定义进程中,如需添加source和target外的其他数据,可以参照source field或target field的构修方法,如构修一个自定义的user_data数据:

1fields["user_data"]=torchtext.data.Field(
2init_token=BOS_WORD,eos_token=EOS_WORD,
3pad_token=PAD_WORD,
4include_lengths=True)

此中init_token、eos_token和pad_token区分为用户自定义的开端字符、完毕字符和padding字符。Include_lengths为真时,会同时返回处理后数据和数据的长度。

2. 模子

OpenNMT完成了当心力机制的编码器-解码器模子。框架定义了编码器息争码器的接口,该接口下,进一步完成了众种差别构造的编码器解码器,可供用户按需组合,如CNN、 RNN编码器等。如用户需自定义特定构造的模块,也可以遵照该接口举行计划,以包管取得的模块可以和OpenNMT的其他模块举行组合。此中,编码器解码器接口如下:

1classEncoderBase(nn.Module):
2defforward(self,input,lengths=None,hidden=None):
3raiseNotImplementedError
4
5classRNNDecoderBase(nn.Module):
6defforward(self,input,context,state,context_lengths=None):
7raiseNotImplementedError
3. 教练

OpenNMT的教练由Trainer.py中Trainer类掌握,该类的可定制化程度并不高,只完成了最基本的序列到序列的教练进程。关于众义务、对立教练等繁杂的教练进程,需求对该类举行较大的改动。

OpenNMT运用总结

OpenNMT供应了基于PyTorch和TensorFlow这两大主流框架的差别完成,可以满意绝大大都用户的需求。关于根底框架的封装使得其丧失了必定的灵敏性,可是关于编码器-解码器构造下文本生成的义务来说,可以省去数据样式、接口定义等细节处理,将精神更众汇合其自定义模块上,疾速搭修出需求的模子。

四、ParlAI

ParlAI是Facebook公司开辟出的一个笃志于对话范畴许众对话义务上分享,教练和评估对话模子的平台[8]。这个平台可以用于教练和测试对话模子,很大都据集上举行众义务教练,而且集成了Amazon Mechanical Turk,以便数据搜罗和人工评估。

ParlAI 中的基本看法:

  • world定义了署理互结交互的状况。天下必需施行一种parley方法。每次对parley的调用都会举行一次交互,一般每个署理包罗一个举措。

  • agent可以是一私人,一个简单的板滞人,可以重复它听到的任何实质,完美调解的神经收集,读出的数据集,或者可以发送新闻或与其状况交互的任何其他实质。署理有两个他们需求定义的主要方法:

1defobserve(self,observation):#用察看更新内部形态
2defact(self):#依据内部形态生成举措
  • observations是我们称之为署理的act函数返回的对象,而且因为它们被输入到其他署理的observe函数而被命名。这是ParlAI中署理与状况之间转达新闻的主要方法。察看一般采用包罗差别类型新闻的python辞书的方式。

  • teacher是特别类型的署理人。他们像所有署理相同施行act和observe功用,但他们也会跟踪他们通过报告功用返回的目标,比如他们提出的题目数目或者准确答复这些题目的次数。

ParlAI 的代码包罗如下几个主要的文献夹[9]:

  • core包罗框架的主要代码;

  • agents包罗可以和差别义务交互的署理;

  • examples包罗差别轮回的少许基本示例;

  • tasks包罗差别义务的代码;

  • mturk包罗修立 Mechanical Turk 的代码及 MTurk 义务样例。

ParlAI运用方法

ParlAI内部封装了许众对话义务(如ConvAI2)和评测(如F1值和hits@1等等)。运用ParlAI现有的数据,代码以及模子举行教练和评测,可以疾速完成对话模子中的许众baseline模子。但因为代码封装性太强,不倡议运用它从头搭修本人的模子。念根底上搭修本人的模子可以精细参考官网中的教程[10]。

这里简单先容直接应用内部的数据,代码以及模子举行教练和评测的一个简单例子(Train a Transformer on Twitter):

1. 打印少许数据汇合的例子

1pythonexamples/display_data.py-ttwitter
2*#displayfirstexamplesfromtwitterdataset*

2. 教练模子

1pythonexamples/train_model.py-ttwitter-mf/tmp/tr_twitter-mtransformer/ranker-bs10-vtim3600-candsbatch-ecandsbatch--data-parallelTrue
2#traintransformerranker

3. 评测之前教练出的模子

1pythonexamples/eval_model.py-ttwitter-mlegacy:seq2seq:0-mfmodels:twitter/seq2seq/twitter_seq2seq_model
2#Evaluateseq2seqmodeltrainedontwitterfromourmodelzoo

4. 输出模子的少许预测

1pythonexamples/display_model.py-ttwitter-mf/tmp/tr_twitter-ecandsbatch
2#displaypredictionsformodelsavedatspecificfileontwitter
ParlAI运用总结

ParlAI有本人的一套方式,比如world、agent和teacher等等。代码封装性特别好,代码量庞大,假如念查找一个中心结果,需求一层一层查看调用的函数,禁止易举行改正。ParlAI中心封装了许众现有的baseline模子,关于对话研讨者,可以疾速完成baseline模子。目前ParlAI还更新,差别版本之间的代码可以构造略有差别,可是ParlAI的中心运用方法大致相同。

五、总结

本文先容了四种常睹框架构修自定义模子的方法。Tensor2Tensor涵盖比较厉密,可是只支撑TensorFlow。AllenNLP最大的优点于简化了数据预处理、教练和预测的进程。代码改起来也很灵敏,可是少许东西目前官方还没有完成,需求本人写。假如是比较古板的编码器-解码器构造下文本生成义务,运用OpenNMT能俭省许众时间。可是假如是构造比较新颖的模子,运用OpenNMT搭修模子照旧是一个不小的挑衅。ParlAI内部封装了许众对话义务,便当运用者疾速复现相关的baseline模子。但因为代码封装性太强和其特别的方式,运用ParlAI从头搭修本人的模子具有必定的挑衅性。每个框架都有各自的优点和毛病,大师需联合本身状况和运用方法举行挑选。可是不倡议每个框架都试一遍,终究掌握每个框架照旧需求必定时间资本的。

参考材料

[1] https://github.com/tensorflow/tensor2tensor

[2] https://allennlp.org/tutorials

[3] https://allenai.github.io/allennlp-docs/api/allennlp.training.metrics.html

[4] http://www.realworldnlpbook.com/blog/training-a-shakespeare-reciting-monkey-using-rl-and-seqgan.html

[5] https://github.com/mhagiwara/realworldnlp

[6] http://opennmt.net/

[7] https://github.com/OpenNMT/OpenNMT-py

[8] http://parl.ai.s3-website.us-east-2.amazonaws.com/docs/tutorial_quick.html

[9] https://www.infoq.cn/article/2017/05/ParlAI-Facebook-AI

[10] http://parl.ai.s3-website.us-east-2.amazonaws.com/docs/tutorial_basic.html

哈工大SCIR
哈工大SCIR

哈尔滨工业大学社会盘算与新闻检索研讨中心

初学NLP
4
相关数据
深度进修技能

深度进修(deep learning)是板滞进修的分支,是一种试图运用包罗繁杂构造或由众重非线性变换构成的众个处理层对数据举行高层笼统的算法。 深度进修是板滞进修中一种基于对数据举行外征进修的算法,至今依鳌有种深度进修框架,如卷积神经收集和深度置信收集和递归神经收集等已被运用盘算机视觉、语音识别、自然言语处理、音频识别与生物新闻学等范畴并获取了极好的效果。

神经板滞翻译技能

2013 年,Nal Kalchbrenner 和 Phil Blunsom 提出了一种用于板滞翻译的新型端到端编码器-解码器构造 [4]。该模子可以运用卷积神经收集(CNN)将给定的一段源文本编码成一个延续的向量,然后再运用轮回神经收集(RNN)举措解码器将该形态向量转换成目标言语。他们的研讨效果可以说是神经板滞翻译(NMT)的降生;神经板滞翻译是一种运用深度进修神经收集获取自然言语之间的映照联系的方法。NMT 的非线性映照差别于线性的 SMT 模子,而且是运用了连接编码器息争码器的形态向量来描画语义的等价联系。另外,RNN 应当槐ボ取得无量长句子背后的新闻,从而办理所谓的「长间隔从头排序(long distance reordering)」题目。

TensorFlow技能

TensorFlow是一个开源软件库,用于种种感知和言语了解义务的板滞进修。目前被50个团队用于研讨和生产许众Google商业产物,如语音识别、Gmail、Google 相册和搜寻,此中许众产物曾运用过其前任软件DistBelief。

当心力机制技能

我们可以大约地把神经当心绪制类比成一个可以笃志于输入实质的某一子集(或特征)的神经收集. 当心力机制最早是由 DeepMind 为图像分类提出的,这让「神经收集施行预测义务时可以更众体恤输入中的相关部分,更少体恤不相关的部分」。当解码器生成一个用于构成目标句子的词时,源句子中仅有少部分是相关的;于是,可以运用一个基于实质的当心力机制来依据源句子动态地生成一个(加权的)语境向量(context vector), 然后收集会依据这个语境向量而不是某个固定长度的向量来预测词。

板滞翻译技能

板滞翻译(MT)是应用板滞的力气「主动将一种自然言语(源言语)的文本翻译成另一种言语(目标言语)」。板滞翻译方法一般可分成三大类:基于规矩的板滞翻译(RBMT)、统计板滞翻译(SMT)和神经板滞翻译(NMT)。

神经收集技能

(人工)神经收集是一种根源于 20 世纪 50 年代的监视式板滞进修模子,那时分研讨者念象了「感知器(perceptron)」的念法。这一范畴的研讨者一般被称为「勾结主义者(Connectionist)」,因为这种模子模拟了人脑的功用。神经收集模子一般是通过反向传达算法运用梯度下降教练的。目前神经收集有两大主要类型,它们都是前馈神经收集:卷积神经收集(CNN)和轮回神经收集(RNN),此中 RNN 又包罗好坏期记忆(LSTM)、门控轮回单位(GRU)等等。深度进修是一种主要运用于神经收集帮帮其取得更好结果的技能。尽管神经收集主要用于监视进修,但也有少许为无监视进修计划的变体,比如主动编码器和生成对立收集(GAN)。

对立教练技能

对立教练涉及两个模子的联合教练:一个模子是生成器,进修生成假样本,目标是骗过另一个模子;这另一个模子是判别器,通过比照实数据进修判别生成器生成样本的真伪,目标是不要被骗。一般而言,两者的目标函数是相反的。

MXNet技能

MXNet是开源的,用来教练安排深层神经收集的深度进修框架。它是可扩展的,容许疾速模子教练,并灵敏支撑众种言语(C ++,Python,Julia,Matlab,JavaScript, Go,R,Scala,Perl,Wolfram言语)

对话系统技能

对话系统大致被分成两类: 义务为导向的对话系统,帮帮用户去完毕特定义务,比如找商品,订住宿,订餐厅等。完成义务为导向的对话系统,主要有两类方法,流水线方法和端到端方法。非义务导向的对话系统,与用户举行互动并供应答复,简单的说,便是绽放范畴的闲聊。完成非义务导向对话系统也主要可分为两类,生成方法和基于检索的方法。

序列到序列技能

F1值技能

为了可以评判差别算法的优劣,Precision和Recall的根底上提出了F1值的看法,来对Precision和Recall举行全体评判。F1的定义如下: F1值 = 准确率 * 召回率 * 2 / (准确率 + 召回率)

引荐作品
暂无评论
暂无评论~