NER相关顶会论文、代码运行环境、注意事项

  1. EMNLP 2018-Adversarial Transfer Learning for Chinese Named Entity Recognition with Self-Attention Mechanism

论文地址
https://www.aclweb.org/anthology/D18-1017/
代码地址
tensorflow
https://github.com/CPF-NLPR/AT4ChineseNER
pytorch
https://github.com/tyistyler/pytorch-AT4ChineseNER

实验相关环境
平台:Google colab
深度学习架构:python3.6+tensorflow 1.8
注意事项:
(1)使用的NER和CWS数据;
(2)sighan2006的NER数据即MSRA数据集
(3)跑代码过程中需要根据提示做一些修改,如python2和python3的print函数;numpy的random函数等。
(4)运行命令见代码链接,由于自己使用的数据集或多或少存在一些不同,建议先训练后测试。

附:(1)使用sentence_transformers包时,需要使用pytorch>=1.6,否则报错如下:

OSError: Unable to load weights from pytorch checkpoint file. If you tried to load a PyTorch model from a TF 2.0 checkpoint, please set from_tf=True. 

使用pycharm无法导入当前文件夹中的package
解决办法:
右键单击当前文件夹上一级根目录,选择Mark Directory as -->Sources Root

2、ACL 2020-A Novel Cascade Binary Tagging Framework for Relational Triple Extraction
论文地址
https://www.aclweb.org/anthology/2020.acl-main.136/
代码地址
tensorflow-official
https://github.com/weizhepei/CasRel.
pytorch
https://github.com/longlongman/CasRel-pytorch-reimplement

tensorflow实验相关环境
平台:Google colab
requirements:
Python 3.7.10
CUDA Version: colab好像同时存在多个cuda版本,没搞懂

使用 cat /usr/local/cuda/version.txt得到的版本如下所示:

CUDA Version 11.0.228

使用 nvcc -V得到的版本如下所示:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Wed_Jul_22_19:09:09_PDT_2020
Cuda compilation tools, release 11.0, V11.0.221
Build cuda_11.0_bu.TC445_37.28845127_0

使用 nvidia-smi得到的版本如下所示:

NVIDIA-SMI 465.19.01    Driver Version: 460.32.03    CUDA Version: 11.2
  • keras==2.2.0
  • tensorflow-gpu==1.13.1
  • keras-bert==0.78.0
  • keras-transformer==0.33.0

pytorch实验相关环境

  • python==3.6.8
  • pytorch==1.4.0
  • torchvision==0.5.0
  • tensorflow-gpu==1.13.1
  • keras-bert==0.78.0
  • keras==2.2.0
  • keras_applications==1.0.7
  • sentencepiece==0.1.95

3、ACL 2021-PRGC: Potential Relation and Global Correspondence Based Joint Relational Triple Extraction
论文地址
https://aclanthology.org/2021.acl-long.486/
代码地址
pytorch
https://github.com/hy-struggle/PRGC
数据集:NYT和WebNLG及其变体。

个人的理解
PRGC模型训练时
(1)利用平均池化操作和全连接神经网络找出可能存在的关系子集;
(2)利用全连接神经网络计算全局关联矩阵(实体与实体之间是否存在关系);
(3)然后利用交叉熵计算sub和obj层的loss;利用多标签分类使用的BCE损失函数,计算关系子集的loss和全局关联矩阵的loss;最后使用三者之和进行反向传播。

PRGC模型测试时
(1)使用训练时的方法,得到关系子集和全局关联矩阵;
(2)此时真正的关系子集是未知的,利用sigmoid和阈值完成多标签分类,找到可能的关系子集(如果在给定阈值情况下无法仍没有找到一个满足条件的值,则选择value最大的关系作为当前句子中三元组的关系);并使用xi记录每个句子存在几种关系;
(3)重点,利用预测的关系子集,记录当前的sequence_output,注意此时一共有sum(x_i)个关系,而不是batch_size个关系,x_i是表示第i句话中有多少种关系。
(由于一句话可能存在多个三元组,因此一句话中可能存在多个关系,所以sequence_output可能会有多个,后续会与不同的关系向量进行拼接,然后预测。)
(4)然后使用sigmoid和阈值完成全局关联矩阵的分类。
(5)之后,利用tag_mapping_corres()方法,得到对应的三元组,计算P、R、F1.
(先找到subject和object的开头,利用global correspondence找到存在关系的sub和obj,然后再赋予二者对应的关系,这个关系在被保存在预测的关系子集中)

4、ACL 2018-Chinese NER Using Lattice LSTM
论文地址
https://aclanthology.org/P18-1144/
代码地址
pytorch0.3
https://github.com/jiesutd/LatticeLSTM
pytorch1.4
https://github.com/tyistyler/LatticeLSTM_torch_1.4
数据集:Weibo、Resume、Msra、Ontonotes4.0

5、ESwA 2018-Joint entity recognition and relation extraction as a multi-head selection problem
论文地址

https://arxiv.org/abs/1804.07847
代码地址
pytorch
https://github.com/mangonihao/MultiHeadJointEntityRelationExtraction_simple
tensorflow-official
https://github.com/bekou/multihead_joint_entity_relation_extraction
数据集:ACE04、ADE、DREC

个人理解
Multihead模型在训练阶段会使用entity的标签,但是在测试时不会使用,因此测试时效果会变差。
模型整体如下所示:
在这里插入图片描述

6、NAACL 2021-PURE-A Frustratingly Easy Approach for Entity and Relation Extraction
论文地址
https://aclanthology.org/2021.naacl-main.5/
代码地址
pytorch
https://github.com/princeton-nlp/PURE
数据集:ACE04、ACE05、SciERC

个人理解
PURE模型在实体识别层实用了Span识别,而不是给每个字符分配一个标签。
模型整体如下所示:
在这里插入图片描述

7、EMNLP 2021-TDEER: An Efficient Translating Decoding Schema for Joint Extraction of Entities and Relations
论文地址
https://aclanthology.org/2021.emnlp-main.635/
代码地址
tensorflow
https://github.com/4AI/TDEER
数据集:NYT、WebNLG

个人理解
TDEER模型包含三个大模块:Entity Tagging ModelRelation DetectorTranslating Decoding Schema
(1)Entity Tagging Model
利用两个sigmoid识别出可能存在的subject和object;
(2)Relation Detector
利用多标签分类,识别出可能存在的Relation;
(3)Translating Decoding Schema
将(1)和(2)得到的subject和relation利用attention进行组合,得到可能的object_start位置;
最后将object_start与(1)得到的object进行比较,若对应位置的确是object的开头,则得到三元组,否则不是一个三元组。
模型整体如下所示:
在这里插入图片描述

代码运行注意事项:
1、安装langml-package
(1)进入langml文件夹,根据requirement.txt和dev-requirement.txt文件安装依赖包;
(2)使用python setup.py install安装langml
2、tensorflow版本
我使用的colab,其中python=3.7,tensorflow=1.15.0,keras=2.3.1,需要注意的是,还要安装tensorflow-gpu=1.15.0才可以调用GPU(我平常使用的是pytorch,至于为何还需要tensorflow-gpu版本我猜测是因为默认调用cpu,检测到gpu版本时才调用gpu)
3、可以加入tqdm来显示进度
4、需要注意的是,建议新建一个虚拟环境,使用conda install tensorflow==1.15.0 tensorflow-gpu==1.15.0来安装tensorflow环境,我使用本地下载的方法,折腾了很久总是无法调用gpu!
5、测试的时候需要注意,使用keras=2.3.1会报错AttributeError: 'str' object has no attribute 'decode',原因可参考https://blog.csdn.net/jmh1996/article/details/111224700
我的解决办法是:pip install h5py==2.10.0

from tqdm import TqdmCallback
...
train_model.fit(
        generator.forfit(random=True),
        steps_per_epoch=len(generator),
        epochs=args.epoch,
        callbacks=[evaluator, TqdmCallback()],
        verbose=args.verbose
    )
...

8、EMNLP 2021-PFN-A Partition Filter Network for Joint Entity and Relation Extraction
论文地址
https://aclanthology.org/2021.emnlp-main.17/
代码地址
pytorch
https://github.com/Coopercoppers/PFN
数据集:NYT、WebNLG

个人理解
PFN模型包含三个大模块:Partition Filter EncoderNER unitRE unit
我感觉模型最精妙的地点在于使用了cumsum操作来分割entity partitionrelation partition and shared partition

模型整体如下所示:
在这里插入图片描述

9、ACL 2019-GraphRel: Modeling Text as Relational Graphs for Joint Entity and Relation Extraction
论文地址
https://aclanthology.org/P19-1136/
代码地址
pytorch-no-official
https://github.com/tsujuifu/pytorch_graph-rel
数据集:NYT、WebNLG

个人理解
使用了两次GCN
(1)一阶段的GCN使用了依存关系;
(2)二阶段的GCN使用了一阶段预测的实体间的关系。

模型整体如下所示:
在这里插入图片描述

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基于PyTorch的NER任务代码示例,其中使用了BiLSTM-CRF模型: ```python import torch import torch.nn as nn import torch.optim as optim class BiLSTM_CRF(nn.Module): def __init__(self, vocab_size, tag_to_ix, embedding_dim, hidden_dim): super(BiLSTM_CRF, self).__init__() self.embedding_dim = embedding_dim self.hidden_dim = hidden_dim self.vocab_size = vocab_size self.tag_to_ix = tag_to_ix self.tagset_size = len(tag_to_ix) self.word_embeddings = nn.Embedding(vocab_size, embedding_dim) self.lstm = nn.LSTM(embedding_dim, hidden_dim // 2, num_layers=1, bidirectional=True) self.hidden2tag = nn.Linear(hidden_dim, self.tagset_size) self.transitions = nn.Parameter( torch.randn(self.tagset_size, self.tagset_size)) self.transitions.data[tag_to_ix[START_TAG], :] = -10000 self.transitions.data[:, tag_to_ix[STOP_TAG]] = -10000 self.hidden = self.init_hidden() def init_hidden(self): return (torch.randn(2, 1, self.hidden_dim // 2), torch.randn(2, 1, self.hidden_dim // 2)) def _forward_alg(self, feats): init_alphas = torch.full((1, self.tagset_size), -10000.) init_alphas[0][self.tag_to_ix[START_TAG]] = 0. forward_var = init_alphas for feat in feats: alphas_t = [] for next_tag in range(self.tagset_size): emit_score = feat[next_tag].view( 1, -1).expand(1, self.tagset_size) trans_score = self.transitions[next_tag].view(1, -1) next_tag_var = forward_var + trans_score + emit_score alphas_t.append(torch.logsumexp(next_tag_var, dim=1).view(1)) forward_var = torch.cat(alphas_t).view(1, -1) terminal_var = forward_var + self.transitions[self.tag_to_ix[STOP_TAG]] alpha = torch.logsumexp(terminal_var, dim=1)[0] return alpha def _get_lstm_features(self, sentence): self.hidden = self.init_hidden() embeds = self.word_embeddings(sentence).view(len(sentence), 1, -1) lstm_out, self.hidden = self.lstm(embeds, self.hidden) lstm_out = lstm_out.view(len(sentence), self.hidden_dim) lstm_feats = self.hidden2tag(lstm_out) return lstm_feats def _score_sentence(self, feats, tags): score = torch.zeros(1) tags = torch.cat([torch.tensor([self.tag_to_ix[START_TAG]], dtype=torch.long), tags]) for i, feat in enumerate(feats): score = score + \ self.transitions[tags[i+1], tags[i]] + feat[tags[i+1]] score = score + self.transitions[self.tag_to_ix[STOP_TAG], tags[-1]] return score def _viterbi_decode(self, feats): backpointers = [] init_vvars = torch.full((1, self.tagset_size), -10000.) init_vvars[0][self.tag_to_ix[START_TAG]] = 0 forward_var = init_vvars for feat in feats: bptrs_t = [] viterbivars_t = [] for next_tag in range(self.tagset_size): next_tag_var = forward_var + self.transitions[next_tag] best_tag_id = argmax(next_tag_var) bptrs_t.append(best_tag_id) viterbivars_t.append(next_tag_var[0][best_tag_id].view(1)) forward_var = (torch.cat(viterbivars_t) + feat).view(1, -1) backpointers.append(bptrs_t) terminal_var = forward_var + \ self.transitions[self.tag_to_ix[STOP_TAG]] best_tag_id = argmax(terminal_var) path_score = terminal_var[0][best_tag_id] best_path = [best_tag_id] for bptrs_t in reversed(backpointers): best_tag_id = bptrs_t[best_tag_id] best_path.append(best_tag_id) start = best_path.pop() assert start == self.tag_to_ix[START_TAG] best_path.reverse() return path_score, best_path def neg_log_likelihood(self, sentence, tags): lstm_feats = self._get_lstm_features(sentence) forward_score = self._forward_alg(lstm_feats) gold_score = self._score_sentence(lstm_feats, tags) return forward_score - gold_score def forward(self, sentence): lstm_feats = self._get_lstm_features(sentence) score, tag_seq = self._viterbi_decode(lstm_feats) return score, tag_seq START_TAG = "<START>" STOP_TAG = "<STOP>" EMBEDDING_DIM = 5 HIDDEN_DIM = 4 training_data = [( "the wall street journal reported today that apple corporation made money".split(), "B I I I O O O B I O O".split() ), ( "georgia tech is a university in georgia".split(), "B I O O O O B".split() )] word_to_ix = {} for sentence, tags in training_data: for word in sentence: if word not in word_to_ix: word_to_ix[word] = len(word_to_ix) tag_to_ix = {"B": 0, "I": 1, "O": 2, START_TAG: 3, STOP_TAG: 4} model = BiLSTM_CRF(len(word_to_ix), tag_to_ix, EMBEDDING_DIM, HIDDEN_DIM) optimizer = optim.SGD(model.parameters(), lr=0.01, weight_decay=1e-4) for epoch in range(300): for sentence, tags in training_data: model.zero_grad() sentence_in = prepare_sequence(sentence, word_to_ix) targets = torch.tensor([tag_to_ix[t] for t in tags], dtype=torch.long) loss = model.neg_log_likelihood(sentence_in, targets) loss.backward() optimizer.step() with torch.no_grad(): precheck_sent = prepare_sequence(training_data[0][0], word_to_ix) print(model(precheck_sent)) ``` 这份代码实现了一个简单的NER任务的训练和预测,其中BiLSTM-CRF模型结合了BiLSTM和CRF两种技术,用于标注每个单词的实体类型。可以通过调整模型超参数和优化器参数来改进模型性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值