前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >流水的NLP铁打的NER:命名实体识别实践与探索

流水的NLP铁打的NER:命名实体识别实践与探索

作者头像
yuquanle
发布于 2020-08-18 06:39:20
发布于 2020-08-18 06:39:20
7.2K04
代码可运行
举报
文章被收录于专栏:AI小白入门AI小白入门
运行总次数:4
代码可运行

作者:王岳王院长 知乎:https://www.zhihu.com/people/wang-yue-40-21 github: https://github.com/wavewangyue 编辑:yuquanle

前言

最近在做命名实体识别(Named Entity Recognition, NER)的工作,也就是序列标注(Sequence Tagging),老 NLP task 了,就是从一段文本中抽取到找到任何你想要的东西,可能是某个字,某个词,或者某个短语

为什么说流水的NLP铁打的NER?NLP四大任务嘛,分类、生成、序列标注、句子对标注。分类任务,面太广了,万物皆可分类,各种方法层出不穷;句子对标注,经常是体现人工智能(zhang)对人类语言理解能力的标准秤,孪生网络、DSSM、ESIM 各种模型一年年也是秀的飞起;生成任务,目前人工智障 NLP 能力的天花板,虽然经常会处在说不出来人话的状态,但也不断吸引 CopyNet、VAE、GAN 各类选手前来挑战;唯有序列标注,数年如一日,不忘初心,原地踏步,到现在一提到 NER,还是会一下子只想到 LSTM-CRF,铁打不动的模型,没得挑也不用挑,用就完事了,不用就是不给面子

虽然之前也做过 NER,但是想细致地捋一下,看一下自从有了 LSTM-CRF 之后,NER 在做些什么,顺便记录一下最近的工作,中间有些经验和想法,有什么就记点什么

因为能力有限,还是跟之前一样,就少讲理论少放公式,多画模型图多放代码,还是主要从工程实现角度记录和分享下经验,也记录一些个人探索过程。如果有新人苦于不知道怎么实现一个 NER 模型,不知道 LSTM-CRF、BERT-CRF 怎么写,看到代码之后便可以原地起飞,从此打开新世界的大门;或者有老 NLPer 从我的某段探索过程里感觉还挺有意思的,那我就太开心了。就这样

还是先放结论

命名实体识别虽然是一个历史悠久的老任务了,但是自从2015年有人使用了BI-LSTM-CRF模型之后,这个模型和这个任务简直是郎才女貌,天造地设,轮不到任何妖怪来反对。直到后来出现了BERT。在这里放两个问题:

  1. 2015-2019年,BERT出现之前4年的时间,命名实体识别就只有 BI-LSTM-CRF 了吗?
  2. 2019年BERT出现之后,命名实体识别就只有 BERT-CRF(或者 BERT-LSTM-CRF)了吗?

经过我不完善也不成熟的调研之后,好像的确是的,一个能打的都没有

既然模型打不动了,然后我找了找 ACL2020 做NER的论文,看看现在的NER还在做哪些事情,主要分几个方面:

  1. 多特征:实体识别不是一个特别复杂的任务,不需要太深入的模型,那么就是加特征,特征越多效果越好,所以字特征、词特征、词性特征、句法特征、KG表征等等的就一个个加吧,甚至有些中文 NER 任务里还加入了拼音特征、笔画特征。。?心有多大,特征就有多多
  2. 多任务:很多时候做 NER 的目的并不仅是为了 NER,而是服务于一个更大的目标,比如信息抽取、问答系统等等的,如果把整个大任务做一个端到端的模型,就需要做成一个多任务模型,把 NER 作为其中一个子任务;另外,如果单纯为了 NER,本身也可以做成多任务,比如实体类型多的时候,单独用一个任务来识别实体,另一个用来判断实体类型
  3. 时令大杂烩:把当下比较流行的深度学习话题或方法跟NER结合一下,比如结合强化学习的NER、结合 few-shot learning 的NER、结合多模态信息的NER、结合跨语种学习的NER等等的,具体就不提了

所以沿着上述思路,就在一个中文NER任务上做一些实践,写一些模型。都列在下面了,首先是 LSTM-CRF 和 BERT-CRF,然后就是几个多任务模型, Cascade 开头的(因为实体类型比较多,把NER拆成两个任务,一个用来识别实体,另一个用来判断实体类型),后面的几个模型里,WLF 指的是 Word Level Feature(即在原本字级别的序列标注任务上加入词级别的表征),WOL 指的是 Weight of Loss(即在loss函数方面通过设置权重来权衡Precision与Recall,以达到提高F1的目的),具体细节后面再讲

  • 代码:上述所有模型的代码都在这里:https://github.com/wavewangyue/ner,带 BERT 的可以自己去下载BERT_CHINESE预训练的 ckpt 模型,然后解压到 bert_model 目录下
  • 环境:Python3, Tensorflow1.12
  • 数据:一个电商场景下商品标题中的实体识别,因为是工作中的数据,并且通过远程监督弱标注的质量也一般,完整数据就不放了。但是我 sample 了一些数据留在 git 里了,为了直接 git clone 完,代码原地就能跑,方便你我他

ok 下面正经开工

1. BI-LSTM+CRF

用纯 HMM 或者 CRF 做 NER 的话就不讲了,比较古老了。从 LSTM+CRF 开始讲起,应该是2015年被提出的模型[1],模型架构在今天来看非常简单,直接上图

BI-LSTM 即 Bi-directional LSTM,也就是有两个 LSTM cell,一个从左往右跑得到第一层表征向量 l,一个从右往左跑得到第二层向量 r,然后两层向量加一起得到第三层向量 c

如果不使用CRF的话,这里就可以直接接一层全连接与softmax,输出结果了;如果用CRF的话,需要把 c 输入到 CRF 层中,经过 CRF 一通专业缜密的计算,它来决定最终的结果

这里说一下用于表示序列标注结果的 BIO 标记法。序列标注里标记法有很多,最主要的还是 BIO 与 BIOES 这两种。B 就是标记某个实体词的开始,I 表示某个实体词的中间,E 表示某个实体词的结束,S 表示这个实体词仅包含当前这一个字。区别很简单,看图就懂。一般实验效果上差别不大,有些时候用 BIOES 可能会有一内内的优势

另外,如果在某些场景下不考虑实体类别(比如问答系统),那就直接完事了,但是很多场景下需要同时考虑实体类别(比如事件抽取中需要抽取主体客体地点机构等等),那么就需要扩展 BIO 的 tag 列表,给每个“实体类型”都分配一个 B 与 I 的标签,例如用“B-brand”来代表“实体词的开始,且实体类型为品牌”。当实体类别过多时,BIOES 的标签列表规模可能就爆炸了

「基于 Tensorflow 来实现 LSTM+CRF 代码也很简单,直接上」

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
self.inputs_seq = tf.placeholder(tf.int32, [None, None], name="inputs_seq") # B * S
self.inputs_seq_len = tf.placeholder(tf.int32, [None], name="inputs_seq_len") # B
self.outputs_seq = tf.placeholder(tf.int32, [None, None], name='outputs_seq') # B * S

with tf.variable_scope('embedding_layer'):
    embedding_matrix = tf.get_variable("embedding_matrix", [vocab_size_char, embedding_dim], dtype=tf.float32)
    embedded = tf.nn.embedding_lookup(embedding_matrix, self.inputs_seq) # B * S * D

with tf.variable_scope('encoder'):
    cell_fw = tf.nn.rnn_cell.LSTMCell(hidden_dim)
    cell_bw = tf.nn.rnn_cell.LSTMCell(hidden_dim)
    ((rnn_fw_outputs, rnn_bw_outputs), (rnn_fw_final_state, rnn_bw_final_state)) = tf.nn.bidirectional_dynamic_rnn(
        cell_fw=cell_fw, 
        cell_bw=cell_bw, 
        inputs=embedded, 
        sequence_length=self.inputs_seq_len,
        dtype=tf.float32
    )
    rnn_outputs = tf.add(rnn_fw_outputs, rnn_bw_outputs) # B * S * D

with tf.variable_scope('projection'):
    logits_seq = tf.layers.dense(rnn_outputs, vocab_size_bio) # B * S * V
    probs_seq = tf.nn.softmax(logits_seq) # B * S * V
    if not use_crf:
        preds_seq = tf.argmax(probs_seq, axis=-1, name="preds_seq") # B * S
    else:
        log_likelihood, transition_matrix = tf.contrib.crf.crf_log_likelihood(logits_seq, self.outputs_seq, self.inputs_seq_len)
        preds_seq, crf_scores = tf.contrib.crf.crf_decode(logits_seq, transition_matrix, self.inputs_seq_len)
    
with tf.variable_scope('loss'):
    if not use_crf: 
        loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits_seq, labels=self.outputs_seq) # B * S
        masks = tf.sequence_mask(self.inputs_seq_len, dtype=tf.float32) # B * S
        loss = tf.reduce_sum(loss * masks, axis=-1) / tf.cast(self.inputs_seq_len, tf.float32) # B
    else:
        loss = -log_likelihood / tf.cast(self.inputs_seq_len, tf.float32) # B

Tensorflow 里调用 CRF 非常方便,主要就 crf_log_likelihood 和 crf_decode 这两个函数,结果和 loss 就都给你算出来了。它要学习的参数也很简单,就是这个 transition_matrix,形状为 V*V,V 是输出端 BIO 的词表大小。但是有一个小小的缺点,就是官方实现的 crf_log_likelihood 里某个未知的角落有个 stack 操作,会悄悄地吃掉很多的内存。如果 V 较大,内存占用量会极高,训练时间极长。比如我的实验里有 500 个实体类别,也就是 V=500*2+1=1001,训练 1epoch 的时间从 30min 暴增到 400min

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/gradients_impl.py:112: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.
  "Converting sparse IndexedSlices to a dense Tensor of unknown shape. "

不过好消息是,Tensorflow2.0 里,这个问题不再有了

坏消息是,Tensorflow2.0 直接把 tf.contrib.crf 移除了,目前还没有官方实现的 CRF 接口

再说一下为什么要加 CRF。从开头的 Leaderboard 里可以看到,BiLSTM 的 F1 Score 在72%,而 BiLSTM+CRF 达到 80%,提升明显

那么为什么提升这么大呢?CRF 的原理,网上随便搜就一大把,就不讲了(因为的确很难,我也没太懂),但是从实验的角度可以简单说说,就是 LSTM 只能通过输入判断输出,但是 CRF 可以通过学习转移矩阵,看前后的输出来判断当前的输出。这样就能学到一些规律(比如“O 后面不能直接接 I”“B-brand 后面不可能接 I-color”),这些规律在有时会起到至关重要的作用

例如下面的例子,A 是没加 CRF 的输出结果,B 是加了 CRF 的输出结果,一看就懂不细说了

2. BERT+CRF & BERT+LSTM+CRF

用 BERT 来做,结构上跟上面是一样的,只是把 LSTM 换成 BERT 就 ok 了,直接上代码

首先把 BERT 这部分模型搭好,直接用 BERT 的官方代码。这里我把序列长度都标成了“S+2”是为了提醒自己每条数据前后都加了“[CLS]”和“[SEP]”,出结果时需要处理掉

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from bert import modeling as bert_modeling

self.inputs_seq = tf.placeholder(shape=[None, None], dtype=tf.int32, name="inputs_seq") # B * (S+2)
self.inputs_mask = tf.placeholder(shape=[None, None], dtype=tf.int32, name="inputs_mask") # B * (S+2)
self.inputs_segment = tf.placeholder(shape=[None, None], dtype=tf.int32, name="inputs_segment") # B * (S+2)
self.outputs_seq = tf.placeholder(shape=[None, None], dtype=tf.int32, name='outputs_seq') # B * (S+2)

bert_config = bert_modeling.BertConfig.from_json_file("./bert_model/bert_config.json")

bert_model = bert_modeling.BertModel(
    config=bert_config,
    is_training=True,
    input_ids=self.inputs_seq,
    input_mask=self.inputs_mask,
    token_type_ids=self.inputs_segment,
    use_one_hot_embeddings=False
)

bert_outputs = bert_model.get_sequence_output() # B * (S+2) * D

然后在后面接东西就可以了,可以接 LSTM,可以接 CRF

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if not use_lstm:
    hiddens = bert_outputs
else:
    with tf.variable_scope('bilstm'):
        cell_fw = tf.nn.rnn_cell.LSTMCell(300)
        cell_bw = tf.nn.rnn_cell.LSTMCell(300)
        ((rnn_fw_outputs, rnn_bw_outputs), (rnn_fw_final_state, rnn_bw_final_state)) = tf.nn.bidirectional_dynamic_rnn(
            cell_fw=cell_fw, 
            cell_bw=cell_bw, 
            inputs=bert_outputs, 
            sequence_length=inputs_seq_len,
            dtype=tf.float32
        )
        rnn_outputs = tf.add(rnn_fw_outputs, rnn_bw_outputs) # B * (S+2) * D
    hiddens = rnn_outputs
    
with tf.variable_scope('projection'):
    logits_seq = tf.layers.dense(hiddens, vocab_size_bio) # B * (S+2) * V
    probs_seq = tf.nn.softmax(logits_seq)
    
    if not use_crf:
        preds_seq = tf.argmax(probs_seq, axis=-1, name="preds_seq") # B * (S+2)
    else:
        log_likelihood, transition_matrix = tf.contrib.crf.crf_log_likelihood(logits_seq, self.outputs_seq, inputs_seq_len)
        preds_seq, crf_scores = tf.contrib.crf.crf_decode(logits_seq, transition_matrix, inputs_seq_len)

其实我原来不太相信 BERT 在中文上的效果,加上我比较排斥这种不讲道理的庞然大物

真正实验了发现,BERT确实强啊

把我显存都给吃光了,但确实强啊

训练一轮要那么久,但确实强啊

讲不出任何道理,但确实强啊

相比较单纯使用 BERT,增加了 CRF 后效果有所提高但区别不大,再增加 BiLSTM 后区别很小,甚至降低了那么一内内

另外,BERT 还有一个至关重要的训练技巧,就是调整学习率。BERT内的参数在 fine-tuning 时,学习率一定要调小,特别时后面还接了别的东西时,一定要按两个学习率走,甚至需要尝试多次反复调,要不然 BERT 很容易就步子迈大了掉沟里爬不上来,个人经验

参数优化时分两个学习率,实现起来就是这样

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
with tf.variable_scope('opt'):
    params_of_bert = []
    params_of_other = []
    for var in tf.trainable_variables():
        vname = var.name
        if vname.startswith("bert"):
            params_of_bert.append(var)
        else:
            params_of_other.append(var)
    opt1 = tf.train.AdamOptimizer(1e-4)
    opt2 = tf.train.AdamOptimizer(1e-3)
    gradients_bert = tf.gradients(loss, params_of_bert)
    gradients_other = tf.gradients(loss, params_of_other)
    gradients_bert_clipped, norm_bert = tf.clip_by_global_norm(gradients_bert, 5.0)
    gradients_other_clipped, norm_other = tf.clip_by_global_norm(gradients_other, 5.0)
    train_op_bert = opt1.apply_gradients(zip(gradients_bert_clipped, params_of_bert))
    train_op_other = opt2.apply_gradients(zip(gradients_other_clipped, params_of_other))

3. Cascade

上面提到过,如果需要考虑实体类别,那么就需要扩展 BIO 的 tag 列表,给每个“实体类型”都分配一个 B 与 I 的标签,但是当类别数较多时,标签词表规模很大,相当于在每个字上都要做一次类别数巨多的分类任务,不科学,也会影响效果

从这个点出发,就尝试把 NER 改成一个多任务学习的框架,两个任务,一个任务用来单纯抽取实体,一个任务用来判断实体类型,直接上图看区别

这个是参考 ACL2020 的一篇论文[2]的思路改的,“Cascade”这个词是这个论文里提出来的。翻译过来就是“级联”,直观来讲就是“锁定对应关系”。结合模型来说,在第一步得到实体识别的结果之后,返回去到 LSTM 输出那一层,找各个实体词的表征向量,然后再把实体的表征向量输入一层全连接做分类,判断实体类型

关于如何得到实体整体的表征向量,论文里是把各个实体词的向量做平均,但是我搞了好久也没明白这个操作是怎么通过代码实现的,后来看了他的源码,好像只把每个实体最开头和最末尾的两个词做了平均。然后我就更省事,只取了每个实体最末尾的一个词

具体实现上这样写:在训练时,每个词,无论是不是实体词,都过一遍全连接,做实体类型分类计算 loss,然后把非实体词对应的 loss 给 mask 掉;在预测时,就取实体最后一个词对应的分类结果,作为实体类型。上图解释

代码不贴了,感兴趣的可以在 git 里看

说一下效果。将单任务 NER 改成多任务 NER 之后,基于 LSTM 的模型效果降低了 0.4%,基于 BERT 的模型提高了 2.7%,整体还是提高更明显。另外,由于 BIO 词表得到了缩减,CRF 运行时间以及消耗内存迅速减少,训练速度得到提高

P.S. 另外,既然提到了 NER 中的实体类型标签较多的问题,就提一下之前看过的一篇文章[3]。这篇论文主要就是为了解决实体类型标签过多的问题(成千上万的数量级)。文中的方法是:把标签作为输入,也就是把所有可能的实体类型标签都一个个试一遍,根据输入的标签不同,模型会有不同的实体抽取结果。文章没给代码,我复现了一下,效果并不好,具体表现就是无论输入什么标签,模型都倾向于把所有的实体都抽出来,不管这个实体是不是对应这个实体类型标签。也可能是我复现的有问题,不细讲了,就是顺便提一句,看有没有人遇到了和我一样的情况

❝Scaling Up Open Tagging from Tens to Thousands: Comprehension Empowered Attribute Value Extraction from Product Title. ACL 2019 ❞

4. Word-Level Feature

中文 NER 和英文 NER 有个比较明显的区别,就是英文 NER 是从单词级别(word level)来做,而中文 NER 一般是字级别(character level)来做。不仅是 NER,很多 NLP 任务也是这样,BERT 也是这样

因为中文没法天然分词,只能靠分词工具,分出来的不一定对,比如“黑啤酒精酿”,如果被错误分词为“黑啤、酒精、酿”,那么“啤酒”这个实体就抽取不到了。类似情况有很多

但是无论字级别、词级别,都是非常贴近文本原始内容的特征,蕴含了很重要的信息。比如对于英文来说,给个单词“Geilivable”你基本看不懂啥意思,但是看到它以“-able”结尾,就知道可能不是名词;对于中文来说,给个句子“小龙女说我也想过过过儿过过的生活”就一时很难找到实体在哪,但是如果分好词给你,一眼就能找到了。就这个理解力来说,模型跟人是一样的

在英文 NLP 任务中,想要把字级别特征加入到词级别特征上去,一般是这样:单独用一个BiLSTM 作为 character-level 的编码器,把单词的各个字拆开,送进 LSTM 得到向量 vc;然后和原本 word-level 的(经过 embedding matrix 得到的)的向量 vw 加在一起,就能得到融合两种特征的表征向量。如图所示

但是对于中文 NER 任务,我的输入是字级别的,怎么把词级别的表征结果加入进来呢?

ACL2018 有个文章[4]是做这个的,提出了一种 Lattice-LSTM 的结构,但是涉及比较底层的改动,不好实现。后来在 ACL2020 论文里看到一篇文章[5],简单明了。然后我就再简化一下,直接把字和词分别通过 embedding matrix 做表征,按照对应关系,拼在一起就完事了,看图就懂

具体代码就不放了,感兴趣可以上 git 看

从结果上看,增加了词级别特征后,提升很明显

很可惜,我还没有找到把词级别特征结合到 BERT 中的方法。因为 BERT 是字级别预训练好的模型,如果单纯从 embedding 层这么拼接,那后面那些 Transformer 层的参数就都失效了

上面的论文里也提到了和 BERT 结合的问题,论文里还是用 LSTM 来做,只是把句子通过 BERT 得到的编码结果作为一个“额外特征”拼接过来。但是我觉得这不算“结合”,至少不应该。但是也非常容易理解为什么论文里要这么做,BERT 当道的年代,不讲道理,打不过就只能加入,方法不同也得强融,么得办法

5. Weight of Loss

本来打算到这就结束了,后来临时决定再加一点,因为感觉这点应该还挺有意思的

大多数 NLP task 的评价指标有这三个:Precision / Recall / F1Score,Precision 就是找出来的有多少是正确的,Recall 是正确的有多少被找出来了,F1Score是二者的一个均衡分。这里有三点常识

  1. 方法固定的条件下,一般来说,提高了 Precision 就会降低 Recall,提高了 Recall 就会降低 Precision,结合指标定义很好理解
  2. 通常来说,F1Score 是最重要的指标,为了让 F1Score 最大化,通常需要调整权衡 Precision 与 Recall 的大小,让两者达到近似,此时 F1Score 是最大的
  3. 但是 F1Score 大,不代表模型就好。因为结合工程实际来说,不同场景不同需求下,对 P/R 会有不同的要求。有些场景就是要求准,不允许出错,所以对 Precision 要求比较高,而有些则相反,不希望有漏网之鱼,所以对 Recall 要求高

对于一个分类任务,是很容易通过设置一个可调的“阈值”来达到控制 P/R 的目的的。举个例子,判断一张图是不是 H 图,做一个二分类模型,假设模型认为图片是 H 图的概率是 p,人为设定一个阈值 a,假如 p>a 则认为该图片是 H 图。默认情况 p=0.5,此时如果降低 p,就能达到提高 Recall 降低 Precision 的目的

但是 NER 任务怎么整呢,他的结果是一个完整的序列,你又不能给每个位置都卡一个阈值,没有意义

然后我想了一个办法,通过控制模型学习时的 Loss 来控制 P/R:如果模型没有识别到一个本应该识别到的实体,就增大对应的 Loss,加重对模型的惩罚;如果模型识别到了一个不应该识别到的实体,就减小对应的 Loss,当然是选择原谅他

实现上也是通过 mask 来实现,看图就懂

实现也非常简单,放一下对应的代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# logits_bio 是预测结果,形状为 B*S*V,softmax 之后就是每个字在BIO词表上的分布概率,不过不用写softmax,因为下面的函数会帮你做
# self.outputs_seq_bio 是期望输出,形状为 B*S
# 这是原本计算出来的 loss
loss_bio = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits_bio, labels=self.outputs_seq_bio) # B * S
# 这是根据期望的输出,获得 mask 向量,向量里出现1的位置代表对应的字是一个实体词,而 O_tag_index 就是 OBIO 词表中的位置
masks_of_entity = tf.cast(tf.not_equal(self.outputs_seq_bio, O_tag_index), tf.float32) # B * S
# 这是基于 mask 计算 weights
weights_of_loss = masks_of_entity + 0.5 # B  *S
# 这是加权后的 loss
loss_bio = loss_bio * weights_of_loss # B * S

从实验效果来看,原本 Precision 远大于 Recall,通过权衡,把两个分数拉到同个水平,可以提升最终的 F1Score

除此之外,在所有深度学习任务上,都可以通过调整 Loss 来达到各种特殊的效果,还是挺有意思的,放飞想象,突破自我

总结

总结放在开头了,就这样

完结,撒花

「参考」

  1. Bidirectional LSTM-CRF Models for Sequence Tagging
  2. A Novel Cascade Binary Tagging Framework for Relational Triple Extraction
  3. Scaling Up Open Tagging from Tens to Thousands: Comprehension Empowered Attribute Value Extraction from Product Title
  4. Chinese NER Using Lattice LSTM
  5. Simplify the Usage of Lexicon in Chinese NER
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI小白入门 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
tf44:tensorflow CRF的使用
版权声明:本文为博主原创文章,未经博主允许不得转载。有问题可以加微信:lp9628(注明CSDN)。 https://blog.csdn.net/u014365862/article/details/81298373
MachineLP
2019/05/26
1.8K0
命名实体识别之bert+bilstm(基于tensorflow)
我们可以直接调用官方的tensorflow的bert模型来使用bert,接下来,我们使用output_layer = model.get_sequence_output()来获得最后一层的特征,然后接下来在添加bilstm层,
西西嘛呦
2020/12/16
1.9K0
【NLP-NER】什么是命名实体识别?
命名实体识别(Named Entity Recognition,NER)是NLP中一项非常基础的任务。NER是信息提取、问答系统、句法分析、机器翻译等众多NLP任务的重要基础工具。
用户1508658
2019/09/20
2.4K0
【NLP-NER】什么是命名实体识别?
object object_无监督命名实体识别
实体识别和关系抽取是例如构建知识图谱等上层自然语言处理应用的基础。实体识别可以简单理解为一个序列标注问题:给定一个句子,为句子序列中的每一个字做标注。因为同是序列标注问题,除去实体识别之外,相同的技术也可以去解决诸如分词、词性标注(POS)等不同的自然语言处理问题。
全栈程序员站长
2022/11/01
8000
教程 | 如何使用深度学习执行文本实体提取
选自TowardsDataScience 作者:Dhanoop Karunakaran等 机器之心编译 参与:Tianci LIU、路 本文介绍了如何使用深度学习执行文本实体提取。作者尝试了分别使用深
机器之心
2018/05/08
1.5K0
教程 | 如何使用深度学习执行文本实体提取
Tensorflow动态seq2seq使用总结
tf-seq2seq是Tensorflow的通用编码器 - 解码器框架,可用于机器翻译,文本汇总,会话建模,图像字幕等。 动机 其实差不多半年之前就想吐槽Tensorflow的seq2seq了(后面博
用户1332428
2018/03/09
2K0
Tensorflow动态seq2seq使用总结
缺少训练样本怎么做实体识别?小样本下的NER解决方法汇总
本文带你走进命名实体识别(NER)任务,首先介绍了解决NER任务的经典模型结构,然后通过3篇顶会论文介绍当缺少训练样本的时候,如何解决NER任务。
圆圆的算法笔记
2022/09/22
1.3K0
缺少训练样本怎么做实体识别?小样本下的NER解决方法汇总
seq2seq模型之raw_rnn
本文是seq2seq模型的第二篇,主要是通过raw_rnn来实现seq2seq模型。 github地址是:https://github.com/zhuanxuhit/nd101 原文地址:https://github.com/ematvey/tensorflow-seq2seq-tutorials/blob/master/2-seq2seq-advanced.ipynb
zhuanxu
2018/08/23
1.2K0
seq2seq模型之raw_rnn
美团搜索中NER技术的探索与实践
命名实体识别NER是信息提取、问答系统、句法分析、机器翻译、面向Semantic Web的元数据标注等应用领域的重要基础工具,在自然语言处理技术走向实用化的过程中占有重要的地位。
美团技术团队
2020/07/27
2.3K2
美团搜索中NER技术的探索与实践
【论文复现】命名实体识别
命名实体识别(NER)是自然语言处理领域的一个核心任务,它的目标是从文本数据中找出并分类出各种命名实体,这些实体往往指的是特定的名词,比如人名、地理位置名称以及机构或组织名称等。
Eternity._
2024/11/28
3420
【论文复现】命名实体识别
NER | 商品标题属性识别探索与实践
每天给你送来NLP技术干货! ---- ©作者 | 康洪雨 单位 | 有赞科技 研究方向 | NLP/推荐算法 来自 | PaperWeekly 最近一段时间在做商品理解的工作,主要内容是从商品标题里识别出商品的一些属性标签,包括不限于品牌、颜色、领型、适用人群、尺码等等。这类任务可以抽象成命名实体识别(Named Entity Recognition, NER)工作,一般用序列标注(Sequence Tagging)的方式来做,是比较成熟的方向。 ▲ 商品理解示例,品牌:佳丰;口味:蒜香味 本文主要记录
zenRRan
2022/07/27
2.4K0
NER | 商品标题属性识别探索与实践
tensorflow学习笔记(三十九):双向rnn
本文介绍了双向循环神经网络在序列数据处理上的应用,并给出了TensorFlow和Keras两个库在双向RNN上的实例代码。同时,文章还探讨了循环神经网络在序列数据处理上的应用,包括双向循环神经网络和序列循环神经网络的应用,并给出了相应的代码实例。
ke1th
2018/01/02
2.3K0
tensorflow学习笔记(三十九):双向rnn
中文NER的那些事儿1. Bert-Bilstm-CRF基线模型详解&代码实现
这个系列我们来聊聊序列标注中的中文实体识别问题,第一章让我们从当前比较通用的基准模型Bert+Bilstm+CRF说起,看看这个模型已经解决了哪些问题还有哪些问题待解决。以下模型实现和评估脚本,详见 Github-DSXiangLi/ChineseNER
风雨中的小七
2021/04/30
9.4K3
中文NER的那些事儿1. Bert-Bilstm-CRF基线模型详解&代码实现
【NLP-NER】如何使用BERT来做命名实体识别
命名实体识别(Named Entity Recognition,NER)是NLP中一项非常基础的任务。NER是信息提取、问答系统、句法分析、机器翻译等众多NLP任务的重要基础工具。
用户1508658
2019/09/30
3.5K0
[TensorFlow深度学习入门]实战十一·用双向BiRNN(LSTM)做手写数字识别准确率99%+
此博文是我们在完成实战五·用RNN(LSTM)做手写数字识别的基础上使用BiRNN(LSTM)结构,进一步提升模型的准确率,1000steps准确率达到99%。
小宋是呢
2019/06/27
1.2K0
中文NER的那些事儿2. 多任务,对抗迁移学习详解&代码实现
第一章我们简单了解了NER任务和基线模型Bert-Bilstm-CRF基线模型详解&代码实现,这一章按解决问题的方法来划分,我们聊聊多任务学习,和对抗迁移学习是如何优化实体识别中边界模糊,垂直领域标注样本少等问题的。Github-DSXiangLi/ChineseNER中提供了bert_bilstm_crf_mtl多任务, 和bert_bilstm_crf_adv对抗迁移两个模型,支持任意NER+NER,CWS+NER的Joint Training。
风雨中的小七
2021/05/18
2.8K0
中文NER的那些事儿2. 多任务,对抗迁移学习详解&代码实现
命名实体识别的深度学习综述
A Survey on Deep Learning for Named Entity Recognition
马上科普尚尚
2020/09/24
1.9K0
命名实体识别的深度学习综述
『深度应用』NLP命名实体识别(NER)开源实战教程
近几年来,基于神经网络的深度学习方法在计算机视觉、语音识别等领域取得了巨大成功,另外在自然语言处理领域也取得了不少进展。在NLP的关键性基础任务—命名实体识别(Named Entity Recognition,NER)的研究中,深度学习也获得了不错的效果。
小宋是呢
2019/08/26
1.6K0
『深度应用』NLP命名实体识别(NER)开源实战教程
基于tensorflow的bilstm_crf的命名实体识别(数据集是msra命名实体识别数据集)
github地址:https://github.com/taishan1994/tensorflow-bilstm-crf
西西嘛呦
2020/11/24
1.3K0
基于tensorflow的bilstm_crf的命名实体识别(数据集是msra命名实体识别数据集)
天池大赛——瑞金医院MMC人工智能辅助构建知识图谱大赛审题解题思路解题训练模型编写预测结果
实体抽取就是自然语言中的命名实体识别,命名实体识别的算法非常多, 比如隐马尔科夫、条件随机场、rnn、lstm等等 用标注好的数据训练模型参数,调优,预测就可以啦
DC童生
2018/12/05
2.2K1
天池大赛——瑞金医院MMC人工智能辅助构建知识图谱大赛审题解题思路解题训练模型编写预测结果
推荐阅读
相关推荐
tf44:tensorflow CRF的使用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验