0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用深度学习执行文本实体提取

电子设计 来源:电子设计 作者:电子设计 2020-12-25 19:15 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

本文介绍了如何使用深度学习执行文本实体提取。作者尝试了分别使用深度学习和传统方法来提取文章信息,结果深度学习的准确率达到了 85%,远远领先于传统算法的 65%。

引言

文本实体提取是自然语言处理(NLP)的主要任务之一。随着近期深度学习领域快速发展,我们可以将这些算法应用到 NLP 任务中,并得到准确率远超传统方法的结果。我尝试过分别使用深度学习和传统方法来提取文章信息,结果非常惊人:深度学习的准确率达到了 85%,远远领先于传统算法的 65%。

本项目的目标是把文章中的每个单词标注为以下四种类别之一:组织、个人、杂项以及其他;然后找到文中最突出的组织和名称。深度学习模型对每个单词完成上述标注,随后,我们使用基于规则的方法来过滤掉我们不想要的标注,并确定最突出的名称和组织。

在这里要感谢 Guillaume Genthial 这篇关于序列标注的文章(https://guillaumegenthial.github.io/),本项目建立在这篇文章的基础之上。

模型的高级架构

架构

上图是对每个单词进行分类标注的模型高级架构。在建模过程中,最耗时间的部分是单词分类。我将解释模型的每个组成部分,帮助读者对模型组件有一个全面的、更高层次的理解。通常,模型组件可分为三部分:

单词表征:在建模第一步,我们需要做的是加载一些预训练词嵌入(GloVe)。同时,我们需要从字符中提取出一些含义。

语境单词表征:我们需要利用 LSTM,对语境中的每一个单词得到一个有意义的表征。

解码:当我们得到表示单词的向量后,我们就可以用它进行预测。

hot encoding(用数值表示单词)

深度学习算法只接受数值型数据作为输入,而无法处理文本数据。如果想要在大量的非数值场景下使用深度神经网络,就需要将输入数据转变数值形式。这个过程就是 hot encoding。

下面是一小段实现 hot encoding 的代码示例:

word_counts = Counter(words)sorted_vocab = sorted(word_counts, key=word_counts.get, reverse=True)int_to_vocab = {ii: word for ii, word in enumerate(sorted_vocab)}vocab_to_int = {word: ii for ii, word in int_to_vocab.items()}

同样地,我们必须获取输入数据中的所有字符,然后将其转化为向量,作为字符嵌入。

单词嵌入 & 字符嵌入

单词嵌入是处理文本问题时使用的一种通过学习得到的表征方式,其中含义相同的单词表征相近。通常,我们利用神经网络来实现单词嵌入,其中使用的单词或短语来自于词库,并需要转变为实数构成的向量形式。

但是,在数据集上生成词向量计算成本很高,我们可以使用一些预训练的单词嵌入来避免这个问题:比如使用斯坦福大学的 NLP 研究者提供的 GloVe 向量。

字符嵌入是字符的向量表征,可用于推导词向量。之所以会使用字符嵌入,是因为许多实体并没有对应的预训练词向量,所以我们需要用字符向量来计算词向量。

LSTM

传统神经网络 VS 循环神经网络(RNN)

循环神经网络(RNN)是人工神经网络的一种,用于序列数据中的模式识别,例如文本、基因组、手写笔迹、口语词汇,或者来自传感器、股市和政府机构的数值型时间序列数据。它可以「理解」文本的语境含义。

RNN 神经元

LSTM 是一种特殊的循环神经网络,相比于简单的循环神经网络,它可以存储更多的语境信息。简单的 RNN 和 LSTM 之间的主要区别在于它们各自神经元的结构不同。

对于语境中的每一个单词,我们都需要利用 LSTM 得到它在所处语境中的有意义表征。

条件随机场(CRF)

在预测标注最后的解码步骤中,我们可以使用 softmax 函数。当我们使用 softmax 函数时,它给出单词属于每个分类的概率。但这个方法给出的是局部选择;换句话说,即使我们从文本语境中提取出了一些信息,标注决策过程依然是局部的,我们在使用 softmax 激活函数时,并没有使用到邻近单词的标注决策。例如,在「New York」这个词中,我们将「York」标注为一个地方,事实上,这应该可以帮助我们确定『New』对应地方的开始。

在 CRF 中,我们的输入数据是序列数据;同时,我们在某个数据点上进行预测时,需要考虑先前文本的语境。在本项目中,我们使用的是线性链 CRF。在线性链 CRF 中,特征只依赖当前标注和之前的标注,而不是整个句子中的任意标注。

为了对这个行为建模,我们将使用特征函数,该函数包含多个输入值:

句子s

单词在句子中的位置i

当前单词的标注 l_i

前一个单词的标注 l_i?1

接下来,对每一个特征函数 f_j 赋予权重 λ_j。给定一个句子s,现在我们可以根据下式计算s的标注l:对句子中所有单词的加权特征求和。

基于词性标注的特征函数示例

如果 l_i= ADVERB,且第 i 个单词以『-ly』结尾,则 f_1(s,i,l_i,l_i?1)=1,否则取 0。如果对应的权重 λ1 为正,且非常大,那么这个特征基本上就表示我们倾向于把以『-ly』结尾的单词标注为 ADVERB。

如果 i=1,l_i= VERB,且句子以问号结尾,则 f_2(s,i,l_i,l_i?1)=1,否则取 0。如果对应的权重 λ2 为正,且非常大,那么这个特征基本上就表示我们倾向于把疑问句的第一个单词标为 VERB。(例,「Is this a sentence beginning with a verb?」)

如果 l_i?1= ADJECTIVE,且 l_i= NOUN,则 f_3(s,i,l_i,l_i?1)=1,否则为0。对应权重为正时,表示我们倾向于认为名词跟在形容词之后。

如果 l_i?1= PREPOSITION,且 l_i= PREPOSITION,则 f_4(s,i,l_i,l_i?1)=1。此函数对应的权重 λ4 为负,表示介词不应该跟着另一个介词,因此我们应该避免这样的标注出现。

最后,我们可以通过取指数和归一化,将这些得分转换为 0~1 之间的概率 p(l|s)。

总之,要建立一个条件随机场,你只需要定义一组特征函数(可以依赖于整个句子、单词的当前位置和附近单词的标注)、赋予权重,然后加起来,最后如果有需要,转化为概率形式。简单地说,需要做两件事情:

1. 找到得分最高的标注序列;

2. 在全体标注序列上求出概率分布。

幸运的是,TensorFlow 提供了相关的库,帮助我们可以很容易地实现 CRF。

log_likelihood, transition_params=tf.contrib.crf.crf_log_likelihood(scores, labels, sequence_lengths)

模型的运行原理

对于每一个单词,我们希望建立一个向量来捕捉其意义以及和任务相关的特征。我们将该向量构建为 GloVe 单词嵌入与包含字符级特征的向量的级联。我们还可以选择使用一些特定的神经网络,自动提取出这些特征。在本文中,我们将在字符层面上使用双向 LSTM 算法。

我们将 CONLL 数据集中的所有单词都进行 hot-encode,这些单词都在 GloVe 单词嵌入中有对应的实体。如上文所述,神经网络只接受向量,不接受文本,因此我们需要将单词转换为向量。CONLL 数据集包含单词及其对应标注。在 hot encoding 后,单词和标注都被转换成了向量。

用于 hot encoding 单词及其对应标注的代码:

with open(self.filename) as f: words, tags = [], [] for line in f: line = line.strip() if (len(line) == 0 or line.startswith("-DOCSTART-")): if len(words) != 0: niter += 1 if self.max_iter is not None and niter > self.max_iter: break yield words, tags words, tags = [], [] else: ls = line.split(' ') word, tag = ls[0],ls[-1] if self.processing_word is not None: word = self.processing_word(word) if self.processing_tag is not None: tag = self.processing_tag(tag) words += [word] tags += [tag]

用于提取单词、标注和字符向量的代码:

if vocab_chars is not None and chars == True: char_ids = [] for char in word: # ignore chars out of vocabulary if char in vocab_chars: char_ids += [vocab_chars[char]]if lowercase: word = word.lower()if word.isdigit(): word = NUMif vocab_words is not None: if word in vocab_words: word = vocab_words[word] else: if allow_unk: word = vocab_words[UNK] else: print(word) print(vocab_words)if vocab_chars is not None and chars == True: return char_ids, wordelse: return word

现在,我们使用 TensorFlow 内置的函数加载单词嵌入。假定 embeddings 是一个 GloVe 嵌入的 numpy 数组,其中 embeddings[i] 表示第 i 个单词的向量形式。

L = tf.Variable(embeddings, dtype=tf.float32, trainable=False)pretrained_embeddings = tf.nn.embedding_lookup(L, word_ids)

现在,我们可以构建根据字符得到的单词嵌入。这里,我们不需要任何预训练字符嵌入。

_char_embeddings = tf.get_variable( nam, dtype=tf.float32, shape=[self.config.nchars, self.config.dim_char])char_embeddings = tf.nn.embedding_lookup(_char_embeddings, self.char_ids_tensor, nam)s = tf.shape(char_embeddings)char_embeddings = tf.reshape(char_embeddings, shape=[s[0]*s[1], s[-2], self.config.dim_char])word_lengths = tf.reshape(self.word_lengths_tensor, shape=[s[0]*s[1]])cell_fw = tf.contrib.rnn.LSTMCell(self.config.hidden_size_char, state_is_tuple=True)cell_bw = tf.contrib.rnn.LSTMCell(self.config.hidden_size_char, state_is_tuple=True)_output = tf.nn.bidirectional_dynamic_rnn( cell_fw, cell_bw, char_embeddings, sequence_length=word_lengths, dtype=tf.float32)

一旦得到了单词表征,我们就可以直接在词向量序列上运行 bi-LSTM,得到另一个向量序列。

cell_fw = tf.contrib.rnn.LSTMCell(self.config.hidden_size_lstm)cell_bw = tf.contrib.rnn.LSTMCell(self.config.hidden_size_lstm)(output_fw, output_bw), _ = tf.nn.bidirectional_dynamic_rnn( cell_fw, cell_bw, self.word_embeddings, sequence_length=self.sequence_lengths_tensor, dtype=tf.float32)output = tf.concat([output_fw, output_bw], axis=-1)output = tf.nn.dropout(output, self.dropout_tensor)

现在,每个单词都和一个向量对应,其中向量记录了这个单词的含义、字符和语境。我们使用向量来做最后的预测。我们可以使用全连接神经网络求出一个向量,该向量中每个条目对应每个标注的得分。

W = tf.get_variable("W", dtype=tf.float32, shape=[2*self.config.hidden_size_lstm, self.config.ntags])b = tf.get_variable("b", shape=[self.config.ntags], dtype=tf.float32, initializer=tf.zeros_initializer())nsteps = tf.shape(output)[1]output = tf.reshape(output, [-1, 2*self.config.hidden_size_lstm])pred = tf.matmul(output, W) + bself.logits = tf.reshape(pred, [-1, nsteps, self.config.ntags])

最后,我们使用 CRF 方法来计算每个单词的标注。实现 CRF 只需要一行代码!下面的代码计算出了损失,同时返回了在预测时很有用的 trans_params。

log_likelihood, _trans_params = tf.contrib.crf.crf_log_likelihood(self.logits, self.labels_tensor, self.sequence_lengths_tensor)self.trans_params = _trans_paramsself.loss = tf.reduce_mean(-log_likelihood)

现在,我们可以定义我们的训练算子:

optimizer = tf.train.AdamOptimizer(self.lr_tensor)self.train_op = optimizer.minimize(self.loss)

一旦我们定义好模型,在数据集上完成很少的几次迭代,就可以得到训练好的模型了。

如何使用训练好的模型

TensorFlow 提供了存储模型权重的功能,这样我们就可以在之后的场景中复原训练好的模型。无论什么时候需要进行预测,我们都可以加载模型权重,这样就不需要重新训练了。

def save_session(self): """Saves session = weights""" if not os.path.exists(self.config.dir_model): os.makedirs(self.config.dir_model) self.saver.save(self.sess, self.config.dir_model)def restore_session(self, dir_model): self.saver.restore(self.sess, dir_model)

每篇文章都被分解为单词再输入到模型中,然后经过上文所述一系列过程,得到输出结果。模型最终输出结果将每个单词分为 4 类:组织、个人、杂项以及其他。这个算法通过基于规则的方法过滤结果,然后进一步正确提取出文本中最突出的名称和组织,它并没有达到 100% 的准确率。

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 神经网络
    +关注

    关注

    42

    文章

    4840

    浏览量

    108147
  • 智能计算
    +关注

    关注

    0

    文章

    199

    浏览量

    17094
  • 工业物联网
    +关注

    关注

    25

    文章

    2541

    浏览量

    67711
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    人工智能-Python深度学习进阶与应用技术:工程师高培解读

    深度学习的工程化落地,早已不是纸上谈兵的事。从卷积神经网络到Transformer,从目标检测到大模型私有化部署,技术栈不断延伸,工程师面临的知识体系也越来越庞杂。现根据中际赛威工程师培训老师的一份
    的头像 发表于 04-21 11:01 231次阅读
    人工智能-Python<b class='flag-5'>深度</b><b class='flag-5'>学习</b>进阶与应用技术:工程师高培解读

    Linux Shell文本处理神器合集:15个工具+实战例子,效率直接翻倍

    在 Linux 系统中,文本是数据交互的 “通用语言”—— 日志文件、配置文件、数据报表、程序输出几乎都以文本形式存在。手动编辑文本不仅繁琐,还容易出错,而掌握 Shell 文本处理工
    的头像 发表于 02-03 15:42 2639次阅读
    Linux Shell<b class='flag-5'>文本</b>处理神器合集:15个工具+实战例子,效率直接翻倍

    飞凌嵌入式ElfBoard-进程之什么是进程

    将源码转换为计算机可以理解的二进制机器语言指令。解释型脚本形式:脚本是包含命令的文本文件,可以由shell或者其他命令解释器之类的程序直接处理。(如:python、Bash)等脚本语言通过解释器执行脚本可执行文
    发表于 01-26 08:42

    初识ros2 功能包建立与可执行文件的配置

    本文介绍了ROS2程序的两种启动方式:直接运行可执行文件(ros2 run)和使用启动文件(ros2 launch)。重点讲解了Python软件包的结构,包括package.xml、setup.py
    的头像 发表于 01-22 13:41 436次阅读

    机器学习深度学习中需避免的 7 个常见错误与局限性

    无论你是刚入门还是已经从事人工智能模型相关工作一段时间,机器学习深度学习中都存在一些我们需要时刻关注并铭记的常见错误。如果对这些错误置之不理,日后可能会引发诸多麻烦!只要我们密切关注数据、模型架构
    的头像 发表于 01-07 15:37 342次阅读
    机器<b class='flag-5'>学习</b>和<b class='flag-5'>深度</b><b class='flag-5'>学习</b>中需避免的 7 个常见错误与局限性

    穿孔机顶头检测仪 机器视觉深度学习

    LX01Z-DG626穿孔机顶头检测仪采用深度学习技术,能够实现顶头状态的在线实时检测,顶头丢失报警,顶头异常状态报警等功能,响应迅速,异常状态视频回溯,检测顶头温度,配备吹扫清洁系统,维护周期长
    发表于 12-22 14:33

    如何进入休眠模式或深度休眠模式?

    )的 SLEEPONEXIT 和 SLEEPDEEP 位域,可实现立即进入或退出(中断服务程序)时进入休眠模式或深度休眠模式。 •立即进入执行 WFI 指令,MCU 将立即进入休眠模式(SLEEPDEEP 为 0
    发表于 12-16 06:25

    如何深度学习机器视觉的应用场景

    深度学习视觉应用场景大全 工业制造领域 复杂缺陷检测:处理传统算法难以描述的非标准化缺陷模式 非标产品分类:对形状、颜色、纹理多变的产品进行智能分类 外观质量评估:基于学习的外观质量标准判定 精密
    的头像 发表于 11-27 10:19 319次阅读

    芯源MCU进入休眠模式或深度休眠模式

    )的SLEEPONEXIT 和SLEEPDEEP 位域,可实现立即进入或退出(中断服务程序)时进 入休眠模式或深度休眠模式。 ●● 立即进入 执行WFI 指令,MCU 将立即进入休眠模式(SLEEPDEEP 为0
    发表于 11-26 07:41

    如何在机器视觉中部署深度学习神经网络

    图 1:基于深度学习的目标检测可定位已训练的目标类别,并通过矩形框(边界框)对其进行标识。 在讨论人工智能(AI)或深度学习时,经常会出现“神经网络”、“黑箱”、“标注”等术语。这些概
    的头像 发表于 09-10 17:38 1042次阅读
    如何在机器视觉中部署<b class='flag-5'>深度</b><b class='flag-5'>学习</b>神经网络

    深度学习对工业物联网有哪些帮助

    深度学习作为人工智能的核心分支,通过模拟人脑神经网络的层级结构,能够自动从海量工业数据中提取复杂特征,为工业物联网(IIoT)提供了从数据感知到智能决策的全链路升级能力。以下从技术赋能、场景突破
    的头像 发表于 08-20 14:56 1191次阅读

    自动驾驶中Transformer大模型会取代深度学习吗?

    [首发于智驾最前沿微信公众号]近年来,随着ChatGPT、Claude、文心一言等大语言模型在生成文本、对话交互等领域的惊艳表现,“Transformer架构是否正在取代传统深度学习”这一话题一直被
    的头像 发表于 08-13 09:15 4360次阅读
    自动驾驶中Transformer大模型会取代<b class='flag-5'>深度</b><b class='flag-5'>学习</b>吗?

    ESP32驱动SPIFFS进行文件操作

    本篇文章介绍如何在ESP32开发板上使用SPIFFS(SPI Flash File System)进行文件操作。看下如何初始化SPIFFS文件系统、读取文件、列出文件、删除文件,并查看存储的剩余空间。
    的头像 发表于 08-05 18:11 4478次阅读
    ESP32驱动SPIFFS进<b class='flag-5'>行文</b>件操作

    深度学习遇上嵌入式资源困境,特征空间如何破局?

    近年来,随着人工智能(AI)技术的迅猛发展,深度学习(Deep Learning)成为最热门的研究领域之一。在语音识别、图像识别、自然语言处理等领域,深度学习取得了显著成果。从原理上看
    发表于 07-14 14:50 1309次阅读
    当<b class='flag-5'>深度</b><b class='flag-5'>学习</b>遇上嵌入式资源困境,特征空间如何破局?

    飞书开源“RTV”富文本组件 重塑鸿蒙应用富文本渲染体验

    更高效的富文本解决方案。 富文本作为内容展示和信息交互的重要形式,在内容创作、办公协作、教育学习、企业应用等多种复杂业务场景中扮演着重要角色。随着鸿蒙生态应用类型的不断丰富,富文本渲染
    的头像 发表于 07-11 15:20 776次阅读
    飞书开源“RTV”富<b class='flag-5'>文本</b>组件 重塑鸿蒙应用富<b class='flag-5'>文本</b>渲染体验