深度学习 -- >NLP -- > Deep contextualized word representations(ELMo)

本文将分享发表在2018年的NAACL上,outstanding paper。论文链接ELMo。该论文旨在提出一种新的词表征方法,并且超越以往的方法,例如word2vec、glove等。

论文贡献点

  1. 能捕捉到更复杂的语法、语义信息。
  2. 能更好的结合上下文内容,对多义词做更好的表征。(以往的词表征方法,例如word2vec等可能无法很好的解决这个问题)
  3. 能非常容易的将这种词表征方法整合进现有的模型中,在多种NLP任务中,都极大了提高了state of the art。

Embedding from Language Models(ELMo)

论文中所提出的词表征方法是基于语言模型的。

双向语言模型

在这里插入图片描述


如上图所示,左侧是正向的L层的语言模型,右边是LLL层的反向网络。SF表示SoftmaxSoftmaxSoftmax 结构。

其中xiLMx_i^{LM}xiLM​ 表示词tit_iti​ 经过charCNNcharCNNcharCNN 后的向量,hi,jLM\overrightarrow{h}^{LM}_{i,j}hi,jLM​、hi,jLM\overleftarrow{h}^{LM}_{i,j}hi,jLM​分别表示正向反向LSTMLSTMLSTM 的第jjj 层的第iii 个LSTMCellLSTMCellLSTMCell 的隐藏层状态。

其中正向语言模型(从前往后预测):
p(t1,t2,..,tn)=k=1np(tkt1,t2,...,tk1)p(t_1,t_2, ..,t_n) = \prod_{k=1}^np(t_k|t_1,t_2,...,t_{k-1})p(t1​,t2​,..,tn​)=k=1∏n​p(tk​∣t1​,t2​,...,tk−1​)
反向语言模型(从后往前预测):
p(t1,t2,..,tn)=k=1np(kktk+1,tk+2,...,tn)p(t_1,t_2, ..,t_n) = \prod_{k=1}^np(k_k|t_{k+1},t_{k+2},...,t_n)p(t1​,t2​,..,tn​)=k=1∏n​p(kk​∣tk+1​,tk+2​,...,tn​)

需要注意的是,正向反向语言模型会共享部分参数。,两者并不是完全独立的。

优化目标,联合正反向网络:
obj=MAX(k=1n(log p(tkt1,t2,...,tk1:θx,θLSTM,θs)+log p(tktk+1,tk+2,...,tn:θx,θLSTM,θs)))obj = MAX (\sum_{k=1}^{n}(log\ p(t_k|t_1,t_2,...,t_{k-1}: \theta_x,\overrightarrow{\theta}_{LSTM}, \theta_s) + log\ p(t_k|t_{k+1},t_{k+2},...,t_n: \theta_x,\overleftarrow{\theta}_{LSTM}, \theta_s)) )obj=MAX(k=1∑n​(log p(tk​∣t1​,t2​,...,tk−1​:θx​,θLSTM​,θs​)+log p(tk​∣tk+1​,tk+2​,...,tn​:θx​,θLSTM​,θs​)))

其中θx\theta_xθx​ 表示词表征参数, θs\theta_sθs​ 表示softmaxsoftmaxsoftmax 参数,θLSTM\theta_{LSTM}θLSTM​表示LSTMLSTMLSTM 网络参数。
显然模型采用的损失函数就是MLEMLEMLE,这样我们就可以训练这个网络。

ELMO

对于训练好的LLL 层的双向语言模型,每个tokentokentoken,例如第kkk 个词tkt_ktk​ 都可以用2L+12L+12L+1 个向量集合表示,如下:
Rk={xkLM,hk,jLM,hk,jLMj=1,..,L}R_k = {\{x_k^{LM},\overrightarrow{h}^{LM}_{k,j}, \overleftarrow{h}^{LM}_{k,j} | j = 1,..,L }\}Rk​={xkLM​,hk,jLM​,hk,jLM​∣j=1,..,L}

为了下游的模型能更好的使用上面得出的词表征,我们需要将2L+12L+12L+1 向量集合压缩成一个向量表示。
ELMok=E(Rk;θe){ELMo}_k=E(R_k;\theta_e)ELMok​=E(Rk​;θe​)
例如,我们可以仅仅使用双向语言模型的最后一层的输出:
E(Rk)=hk,LLME(R_k) = h^{LM}_{k,L}E(Rk​)=hk,LLM​
其中hk,LLM=[hk,jLM:hk,jLM]h^{LM}_{k,L} = [\overrightarrow{h}^{LM}_{k,j}: \overleftarrow{h}^{LM}_{k,j}]hk,LLM​=[hk,jLM​:hk,jLM​]

更普遍的做法是:
ELMoktask=E(Rk;θtask)=γtaskj=0Lsjtaskhk,jLM{ELMo}_{k}^{task}=E(R_k;\theta^{task})=\gamma^{task}\sum_{j=0}^{L}s_j^{task}h_{k,j}^{LM}ELMoktask​=E(Rk​;θtask)=γtaskj=0∑L​sjtask​hk,jLM​

sjtasks_j^{task}sjtask​ 表示按特定任务对权重做softmaxnormalizedsoftmax-normalizedsoftmax−normalized, γ\gammaγ是需要根据经验调试的超参数。

将ELMo应用到有监督学习

  1. ELMoELMoELMo 词向量直接与普通的词向量(例如本文中经过CharCNNChar-CNNChar−CNN得到的词向量)拼接,即:[xk:ELMoktask][x_k: {ELMo}_k^{task}][xk​:ELMoktask​]。
  2. ELMoELMoELMo 词向量直接与双向的语言模型的隐层状态hkh_khk​ 拼接,即:[hkELMoktask][h_k:{ELMo}_k^{task}][hk​:ELMoktask​] 拼接,论文中说这种拼接操作,在效果上更好。论文中有提到,对于网络中不同层能表示出词的不同含义。比如:High-level LSTM可以捕捉词语上下文独立的语义信息,适合做监督的词义消歧任务;Lower-level的可以捕捉句法信息,适合做词性标注。那么这里与不同层的状态拼接操作,就相当于Ensemble的操作,所以效果会比较好?
  3. ELMoELMoELMo 做正则操作,也就是对双向的LSTMLSTMLSTM 中权重做正则处理。即对模型losslossloss 函数加上λw22\lambda ||w||_2^2λ∣∣w∣∣22​。

实验分析

论文的实验部分验证了加入MLMoMLMoMLMo 的词向量在各个NLP任务上都得到了很好的表现。这里面举一些个人觉得比较有亮点的部分分析下。

使用所有层信息、使用最后一层信息、以及正则的实验效果

在这里插入图片描述


BaselineBaselineBaseline 是没有使用ELMoELMoELMo 的词向量,last onlylast\ onlylast only 是仅仅使用双向语言模型的最后一层的词向量,All layersAll\ layersAll layers 使用了双向语言模型所有层的词向量集成,显然我们可以看出当正则λ=0.001\lambda = 0.001λ=0.001 并且使用了所有层的词向量集成,效果答复提升。说明这种集成的做法是比较有效的。

将ELMo词向量用在模型的输入处和输出处的效果对比

在这里插入图片描述

关键代码

构建带残差的双向语言模型

 with tf.variable_scope("elmo_rnn_cell"):
      self.forward_cell = tf.nn.rnn_cell.LSTMCell(self.hidden_size, reuse=tf.AUTO_REUSE)
      self.backward_cell = tf.nn.rnn_cell.LSTMCell(self.hidden_size, reuse=tf.AUTO_REUSE)

  if config.get("use_skip_connection"):## 残差连接
      self.forward_cell = tf.nn.rnn_cell.ResidualWrapper(self.forward_cell)
      self.backward_cell = tf.nn.rnn_cell.ResidualWrapper(self.backward_cell)

  with tf.variable_scope("elmo_softmax"):## 下面的forward_softmax_w  就是上面所讲的$s^{task}_j$
      softmax_weight_shape = [config["word_vocab_size"], config["elmo_hidden"]]

      self.forward_softmax_w = tf.get_variable("forward_softmax_w", softmax_weight_shape, dtype=tf.float32)
      self.backward_softmax_w = tf.get_variable("backward_softmax_w", softmax_weight_shape, dtype=tf.float32)

      self.forward_softmax_b = tf.get_variable("forward_softmax_b", [config["word_vocab_size"]])
      self.backward_softmax_b = tf.get_variable("backward_softmax_b", [config["word_vocab_size"]])
embedding_output = self.embedding.forward(data)## 将data经过char-cnn得到普通词向量
        with tf.variable_scope("elmo_rnn_forward"):
            forward_outputs, forward_states = tf.nn.dynamic_rnn(self.forward_cell,
                                                                inputs=embedding_output,
                                                                sequence_length=data["input_len"],
                                                                dtype=tf.float32)

        with tf.variable_scope("elmo_rnn_backward"):
            backward_outputs, backward_states = tf.nn.dynamic_rnn(self.backward_cell,
                                                                  inputs=embedding_output,
                                                                  sequence_length=data["input_len"],
                                                                  dtype=tf.float32)

        # #将正反向模型链接起来
        forward_projection = tf.matmul(forward_outputs, tf.expand_dims(tf.transpose(self.forward_softmax_w), 0))
        forward_projection = tf.nn.bias_add(forward_projection, self.forward_softmax_b)

        backward_projection = tf.matmul(backward_outputs, tf.expand_dims(tf.transpose(self.backward_softmax_w), 0))
        backward_projection = tf.nn.bias_add(backward_projection, self.backward_softmax_b)

        return forward_outputs, backward_outputs, forward_projection, backward_projection

上面只是定义了一层的LSTM网络,但是通过残差连接,把一层的输入和输出连接在一起了。就相当于将不同层的隐状态集成到一起了。

模型训练

def train(self, data, global_step_variable=None):
        forward_output, backward_output, _, _ = self.forward(data)

		## 注意data[target]只是比输入延后了一步
        forward_target = data["target"]
        forward_pred = tf.cast(tf.argmax(tf.nn.softmax(forward_output, -1), -1), tf.int32)
        forward_correct = tf.equal(forward_pred, forward_target)
        forward_padding = tf.sequence_mask(data["target_len"], maxlen=self.seq_len, dtype=tf.float32)

        forward_softmax_target = tf.cast(tf.reshape(forward_target, [-1, 1]), tf.int64)
        forward_softmax_input = tf.reshape(forward_output, [-1, self.hidden_size])
        forward_train_loss = tf.nn.sampled_softmax_loss(
            weights=self.forward_softmax_w, biases=self.forward_softmax_b,
            labels=forward_softmax_target, inputs=forward_softmax_input,
            num_sampled=self.config["softmax_sample_size"],
            num_classes=self.config["word_vocab_size"]
        )

        forward_train_loss = tf.reshape(forward_train_loss, [-1, self.seq_len])
        forward_train_loss = tf.multiply(forward_train_loss, forward_padding)
        forward_train_loss = tf.reduce_mean(forward_train_loss)
		## 反向模型需要将target翻转,因为是从后向前预测的。
        backward_target = tf.reverse_sequence(data["target"], data["target_len"], seq_axis=1, batch_axis=0)
        backward_pred = tf.cast(tf.argmax(tf.nn.softmax(backward_output, -1), -1), tf.int32)
        backward_correct = tf.equal(backward_pred, backward_target)
        backward_padding = tf.sequence_mask(data["target_len"], maxlen=self.seq_len, dtype=tf.float32)

        backward_softmax_target = tf.cast(tf.reshape(backward_target, [-1, 1]), tf.int64)
        backward_softmax_input = tf.reshape(backward_output, [-1, self.hidden_size])
        backward_train_loss = tf.nn.sampled_softmax_loss(
            weights=self.backward_softmax_w, biases=self.backward_softmax_b,
            labels=backward_softmax_target, inputs=backward_softmax_input,
            num_sampled=self.config["softmax_sample_size"],
            num_classes=self.config["word_vocab_size"]
        )

        backward_train_loss = tf.reshape(backward_train_loss, [-1, self.seq_len])
        backward_train_loss = tf.multiply(backward_train_loss, backward_padding)
        backward_train_loss = tf.reduce_mean(backward_train_loss)

        train_loss = forward_train_loss + backward_train_loss
        train_correct = tf.concat([forward_correct, backward_correct], axis=-1)
        train_acc = tf.reduce_mean(tf.cast(train_correct, tf.float32))

        tf.summary.scalar("train_acc", train_acc)
        tf.summary.scalar("train_loss", train_loss)

        train_ops = tf.train.AdamOptimizer().minimize(train_loss)
        return train_loss, train_acc, train_ops

获得EMLo词向量

def pred(self, data):
        -,-, forward_projection, backward_projection= self.forward(data)
        eval_output = tf.concat([forward_projection, backward_projection], axis=-1)
        return eval_output

上面的 forward_projection,backward_projectionforward\_projection, backward\_projectionforward_projection,backward_projection 分别表示正向,反向网络集成各层隐状态得到词向量表示,将其连接起来就得到了上某种形式的EMLoEMLoEMLo 词向量。

原文地址:https://blog.csdn.net/Mr_tyting/article/details/89675087

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


python方向·数据分析   ·自然语言处理nlp   案例:中文分词·社交网络分析      案例:人物关系分析·人工智能·深度学习·计算机视觉案例:行人检测·网络爬虫·量化交易          案例:多因子策略模型 
原文地址http://blog.sina.com.cn/s/blog_574a437f01019poo.html昨天实验室一位刚进组的同学发邮件来问我如何查找学术论文,这让我想起自己刚读研究生时茫然四顾的情形:看着学长们高谈阔论领域动态,却不知如何入门。经过研究生几年的耳濡目染,现在终于能自信地知道去哪儿了解最新科研
ptb数据集是语言模型学习中应用最广泛的数据集,常用该数据集训练RNN神经网络作为语言预测,tensorflow对于ptb数据集的读取也定义了自己的函数库用于读取,在python1.0定义了models文件用于导入ptb库函数,然而当python升级后,导入models文件时就会出现:ModuleNotFountError错误,这时需
 Newtonsoft.JsonNewtonsoft.Json是.Net平台操作Json的工具,他的介绍就不多说了,笔者最近在弄接口,需要操作Json。以某个云计算平台的Token为例,边操作边讲解。Json转为Model将Model转为Json将LINQ转为JSONLinq操作命名空间、类型、方法大全 Json转为Model 
NLP(NaturalLanguageProcessing)自然语言处理是人工智能的一个子领域,它是能够让人类与智能机器进行沟通交流的重要技术手段,同时也是人工智能中最为困难的问题之一。因此,NLP的研究处处充满魅力和挑战,也因此被称为人工智能“皇冠上的明珠”。目前各家主流深度学习框架,都开放了相应
做一个中文文本分类任务,首先要做的是文本的预处理,对文本进行分词和去停用词操作,来把字符串分割成词与词组合而成的字符串集合并去掉其中的一些非关键词汇(像是:的、地、得等)。再就是对预处理过后的文本进行特征提取。最后将提取到的特征送进分类器进行训练。一、什么是自然语言处
NLP(NaturalLanguageProcessing)自然语言处理是人工智能的一个子领域,它是能够让人类与智能机器进行沟通交流的重要技术手段,同时也是人工智能中最为困难的问题之一。因此,NLP的研究处处充满魅力和挑战,也因此被称为人工智能“皇冠上的明珠”。目前各家主流深度学习框架,都开放了相应
编者注:文中超链接如果不能访问可以点击“阅读原文”访问本文原页面;可以参考2018年5月21-24日伦敦Strata数据会议上的教学辅导课《使用spaCy和SparkNLP进行自然语言理解》。本系列博客的目地是通过使用两个领先的生产级语言处理库(JohnSnowLabs的ApacheSparkNLP和Explosion
NLP文本相似度相似度相似度度量:计算个体间相似程度相似度值越小,距离越大,相似度值越大,距离越小最常用--余弦相似度:​一个向量空间中两个向量夹角的余弦值作为衡量两个个体之间差异的大小余弦值接近1,夹角趋于0,表明两个向量越相似如果向量a和b不是二维而是n维​
0.原文NLP系列(6)_从NLP反作弊技术看马蜂窝注水事件-寒小阳-CSDN博客https://blog.csdn.net/han_xiaoyang/article/details/842057011.马蜂窝是否有大量抄袭点评1.1先用词袋模型快速筛选一批相似点评词袋子模型是一种非常经典的文本表示。顾名思义,它就是将字符串视为
地址:https://gitbook.cn/books/5c7888e1a19247277cb5c313/index.html深度学习优势总结:手工特征耗时耗力,还不易拓展自动特征学习快,方便拓展深度学习提供了一种通用的学习框架,可用来表示世界、视觉和语言学信息深度学习既可以无监督学习,也可以监督学习在DeepNLP
本文将分享发表在2018年的NAACL上,outstandingpaper。论文链接ELMo。该论文旨在提出一种新的词表征方法,并且超越以往的方法,例如word2vec、glove等。论文贡献点能捕捉到更复杂的语法、语义信息。能更好的结合上下文内容,对多义词做更好的表征。(以往的词表征方法,例如word2ve
时间:2016年1月。出处:http://blog.csdn.net/longxinchen_ml/article/details/50597149http://blog.csdn.net/han_xiaoyang/article/details/50616559声明:版权所有,转载请联系作者并注明出处##1.引言贝叶斯方法是一个历史悠久,有着坚实的理论基础的方法,同时处理很多问题时
NLP的工程化,不是一个个算法的累积,也不是一个个任务的独立优化,而应该是系统工程,综合考虑语言、计算、场景等多种因素,不断演进融合,寻求效果满意解的过程。根据赫伯特.西蒙(图灵奖和诺贝尔奖双料得主)的有限理性模型,受到所处环境的高度复杂性和有限的信息加工能力限制,因此NLP应用
继NLP之后,我又开了ML这个大坑。这是因为NLP涉及到太多的ML模型,仅仅拿过来用的话,我实现的HanLP已经快到个人极限了。而模型背后的原理、如何优化、如何并行化等问题,都需要寻根求源才能解决。所以我找了个书单自学,电子书为主,顺便分享出来。 ML书单│  李航.统计学习方法.
少玩ai,人工智能,nlp,tensorflow之类的玄学,多学学基础,三大浪漫,C++,搞开发,千万不要变成调参侠
 0.introductionGAN模型最早由IanGoodfellowetal于2014年提出,之后主要用于signalprocessing和naturaldocumentprocessing两方面,包含图片、视频、诗歌、一些简单对话的生成等。由于文字在高维空间上不连续的问题(即任取一个wordembedding向量不一定能找到其所对应的文字),GA
自然语言处理Firstatall 因为本人换系统之前都在用oneNote,在ubuntu上部署不便,所以将一些常用的信息写成博客 本文主要引用Ruder大神的NLP-proress做了一下翻译和提取原文地址:传送门1.前沿技术StateoftheArt 机器学习和自然语言处理(NLP)的研究近来发展
北风网-人工智能就业班培训链接:https://pan.baidu.com/s/128DJgMY9G-fjzRAxq1QO-w  提取码:ngwi课程体系阶段一、人工智能基础-高等数学必知必会本阶段主要从数据分析、概率论和线性代数及矩阵和凸优化这四大块讲解基础,旨在训练大家逻辑能力,分析能力。拥有良好的数学基础,有利