讲在前面

这次比赛对我来说是首次参加百度举办的比赛,也是第一个事件抽取方向的比赛,整体来说熟悉事件抽取的模型,以及相关的操作为主,最高得分F1,0.796分,算是低分,在这里对整个比赛过程,以及自己的一个情况做一个小结梳理,为下次比赛做好准备工作,还是比较小白的,但是在这次比赛中也收获了很多实战的经验,奈何各位大神云集,竞争激烈,对我个人而言,熟悉模型,熟悉比赛模式,收获经验为主!大佬请关掉网页2333
本次赛题属于一个多分类,多标签的问题,文本先要进行事件分类,之后进行事件抽取,将论元和内容进行抽取,一个文本可能属于多个事件,在同一个时间下,也会有多个论元。

一,baseline入坑:熟悉模型

感谢苏剑林大佬的baseline,他代码简单明确的风格深深吸引了我,立志通读大佬的代码,以大佬为明灯。主要是用Bert4keras实现,事件类型和论元同时预测,针对overlap的情况暂不考虑,执行直接覆盖的政策,模型本身的话使用Bert预训练模型+fineturn+全联接层+CRF输出层,损失是使用的交叉熵稀疏损失,优化器是Adam优化器,评价指标是每个标签粗测的训练效果。
之前的我对于fine turn也是一知半解,其实很简单,就是使用别人训练好的模型,加上自己的数据集再次进行训练,更好的拟合自己的数据集。
网址如下:

加入的一些小的改进

1⃣️可以使用比较大的词嵌入模型进行训练,word_embedding_len=1024
2⃣️可以使得句子的最长长度增加,增大的训练时间
3⃣️可以增加CRF的学习率,效果有提升,但是不知道作用在何处
4⃣️可以使用变化的学习率进行训练,效果提升一般
5⃣️动态学习率,控制每一层网络的学习率,这个我还没有实现
6⃣️使用冻结层的操作,trainable=false 效果变差

对于具体事件抽取的一些改进

1⃣️可以针对overlap的情况进行数据的拆分,感觉会有一些用
2⃣️在文本的前部加入事件类型,给模型指示,这个需要提前使用事件分类的模型
3⃣️在合并的时候进行查找,相同的事件类型进行合并操作
4⃣️可以使用问答模型进行对模型提问,这个论元是不是属于该事件类型下的论元,本次比赛还未实现,据同事介绍效果有提升。
5⃣️针对每一个事件类型可以单独训练模型进行预测,效果会变好

二,尝试新模型:2019_ner命名实体模型

这个模型看起来非常厉害的样子,但是我跑起来真的感觉没有发挥这个模型最大的效果,这个模型有这么多的输入的参数我省事直接把默认的参数更改,这样直接运行就可以出结果,这个模型是基于静态图的实体识别模型,最厉害的地方就是可以处理overlap的问题,在实际的模型中,是安装token级别垂直输入的,看了他的代码,使用factor这个结构将文本,词干,词性,标签统一处理,统一进行已经处理好的词嵌入中,直接接上RNN或者LSTM进行训练,最后一层可以选择时CRF还是Seq2Seq模型,整体而言比较复杂,花了蛮久的时间研究学习的,下面介绍一下我的研究学习的“成le果se”

非常多的介入的参数数据

tqdm 进度条程序,可以得到好看的进度条

放个不是很好看的报错的结果,可以看一下效果

  # Trainfor epochs, learning_rate in args.epochs:for epoch in tqdm(range(epochs)):network.train_epoch(train, learning_rate, args)dev_score = 0if args.dev_data:dev_score =network.evaluate("dev",dev,args)print("{}".format(dev_score))# Save networknetwork.saver.save(network.session, "{}/model".format(args.logdir), write_meta_graph=False)# Testtest_score = network.evaluate("test", test, args)network.predict_to_file(args)

输入的数据预处理

比较难受的就是需要单独生成词嵌入到向量,
这个部分比较重要,直接关系到后面的数据存储部分,看了好几遍才看懂一些,贴一小部分,方便以后找到位置就好,这个太长了,之后和同事讨论了好久就是关于这个的编码的问题。

  # Load the sentences 加载句子。with open(filename, "r", encoding="utf-8") as file:in_sentence = Falsefor line in file:line = line.rstrip("\r\n")if line:columns = line.split("\t")for f in range(self.FACTORS):  #为什么在——FACTORS 寻找.一共有4个元素factor = self._factors[f]  #一个句子的factorif not in_sentence:  #对于一个句子进行处理factor.word_ids.append([])factor.charseq_ids.append([])factor.strings.append([])column = columns[f] if f < len(columns) else '<pad>'  #f<4words = []if f == self.TAGS and seq2seq:  #怎么处理 | 情况words = column.split("|")words.append("<eow>")else:words = [column]for word in words:  #每一个元素factor.strings[-1].append(word)

下面都是我生成的词嵌入的向量文件,大的一个就要3个G左右,

生成词嵌入的main文件

import json
import numpy as np
from bert4keras.tokenizers import Tokenizer
from bert4keras.models import build_transformer_model
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "7"
config_path = 'bert-utils-master/chinese_roberta_wwm_large_ext_L-24_H-1024_A-16/bert_config.json'
checkpoint_path = 'bert-utils-master/chinese_roberta_wwm_large_ext_L-24_H-1024_A-16/bert_model.ckpt'
dict_path = 'bert-utils-master/chinese_roberta_wwm_large_ext_L-24_H-1024_A-16/vocab.txt'
maxlen = 128
epochs = 20
batch_size = 8
learning_rate = 2e-5
crf_lr_multiplier = 100  # 必要时扩大CRF层的学习率
model = build_transformer_model(config_path, checkpoint_path)  # 建立模型,加载权重
tokenizer = Tokenizer(dict_path, do_lower_case=True)def load_data_test(filename,name):word_em=open("bert-utils-master/data/"+name+"_word_embedding_l.txt",'w', encoding='utf-8')with open(filename) as f:for l in f:l = json.loads(l)arguments = {}text=l['text']token_ids, segment_ids = tokenizer.encode(text,max_length=maxlen)tokens = tokenizer.tokenize(text)  # 转化为tokenswe=model.predict([np.array([token_ids]), np.array([segment_ids])])#token_ids = token_ids[1:-1]#tokens = tokens[1:-1]for i in range(1,len(token_ids)-1):word_em.write(tokens[i])for j in range(1024):word_em.write(" " + str(we[0][i][j]))word_em.write("\n")word_em.write("\n")
load_data_test("bert-utils-master/data/train.json", "train")
load_data_test("bert-utils-master/data/dev.json","dev")
load_data_test("bert-utils-master/data/test1.json","test")

三,自己编写脚本前后处理

生成垂直数据的主要文件

class data_generator(DataGenerator):"""数据生成器"""def __iter__(self, random=False):   # 迭代器 : batch id segment_id labelfor is_end, (text, arguments) in self.sample(random):token_ids, segment_ids = tokenizer.encode(text,max_length=maxlen)tokens = tokenizer.tokenize(text)  #转化为tokenstoken_ids=token_ids[1:-2]tokens=tokens[1:-2]print(tokens)label = ["O"] * len(tokens)for argument in arguments.items():a_token_ids = tokenizer.encode(argument[0])[0][1:-1]start_index = search(a_token_ids, token_ids)mapping = tokenizer.rematch(text, tokens)    # 进行文本和token的匹配token_ids = tokenizer.tokens_to_ids(tokens)  # 找到tokens的ID#print(list(map(lambda x:text[x],mapping[start_index])))if start_index != -1:if len(a_token_ids)==1:if label[start_index]=="O" : print(arguments[argument[0]][0]+"-"+arguments[argument[0]][1] )label[start_index]="U-"+arguments[argument[0]][0]+"-"+arguments[argument[0]][1] else: label[start_index]=label[start_index]+"|"+"U-"+arguments[argument[0]][0]+"-"+arguments[argument[0]][1]else :if label[start_index]=="O" : label[start_index]="B-"+arguments[argument[0]][0]+"-"+arguments[argument[0]][1]else :  label[start_index]=label[start_index]+"|"+"B-"+arguments[argument[0]][0]+"-"+arguments[argument[0]][1]for i in range(1, len(a_token_ids)-1):if label[start_index + i]=="O" :  label[start_index + i] = "I-"+arguments[argument[0]][0]+"-"+arguments[argument[0]][1]else:label[start_index + i] = label[start_index + i]+"|"+"I-"+arguments[argument[0]][0]+"-"+arguments[argument[0]][1]if label[start_index + len(a_token_ids)-1]=="O" : label[start_index + len(a_token_ids)-1] = "L-"+arguments[argument[0]][0]+"-"+arguments[argument[0]][1]else :    label[start_index + len(a_token_ids)-1] = label[start_index + len(a_token_ids)-1]+"|"+"L-"+arguments[argument[0]][0]+"-"+arguments[argument[0]][1]with open('dev_data_label.txt','a') as f: for i in range(len(tokens)):f.write("{}\t{}\t{}\t{}\n".format(tokens[i],"_",list(map(lambda x:x.flag,pseg.cut(tokens[i])))[0],label[i]))f.write("\n")
train_generator = data_generator(train_data, len(train_data))
for i in train_generator:pass

将预测的结果进行合并的文件

import json
def load_data():filename="event_predict_lr_scheduler.jsonl"filename1="ner_pred_bert_v7.json"D = []fw = open("ner_pred_final_v4.json", 'w', encoding='utf-8')arguments={}with open(filename) as f:for x in f:x = json.loads(x)arguments["text"]=x["text"]arguments["id"]=x["id"]D.append(arguments)arguments={}i=0with open(filename1) as ner:for l in ner:l = json.loads(l)arguments = {}event_list=[]for event in l['event_list']:for argument in event['arguments']:key = argument['argument']value = argument['role']  #事件类型+论元角色arguments[key] = valueevent_list.append({'event_type': "-".join(key.split("-")[0:-1]),'arguments': [{'role': key.split("-")[-1].replace("##", ""),'argument': value.replace("##", "")}]})l = {}l['text'] = D[i]['text']l['id']=D[i]['id']l['event_list']=event_listi=i+1print(l)l = json.dumps(l, ensure_ascii=False)fw.write(l + '\n')
load_data()

四,跑服务器相关的一些知识

1⃣️学习SHH协议连接服务器
2⃣️使用iterm2 进行窗口化
3⃣️学习类Git相关知识
4⃣️使用pychram 连接服务器

五,关于词嵌入相关的知识

不同的词嵌入模型的效果可能相差还是比较大的,在这次比赛中我主要使用了一下预训练的词嵌入模型
chinese_L-12_H-768_A-12
chinese_roberta_L-6_H-384_A-12
chinese_roberta_wwm_large_ext_L-24_H-1024_A-16
其中层数越好训练效果会变好,但是训练时间增加。
1⃣️非常深的模型可以显著提升nlp任务的训练精确度,模型可以从无标记数据中训练得到。
2⃣️基于transformer 时候encoder-decoder结构,利用transform的encoder进行训练。
3⃣️BERT则选择了两个看起来更简单的任务:完形填空和句对预测
4⃣️MaskLM的方式来训练语言模型
最后,BERT也打开了一个思路:可以继续在无标注数据上挖潜,而不仅仅限于语言模型。

[1]基于全词遮罩(Whole Word Masking)技术的中文预训练模型BERT-wwm https://github.com/ymcui/Chinese-BERT-wwm/
[2]NLP历史突破!快速解读Google BERT模型 + Word Embedding https://www.youtube.com/watch?v=Po38Dl-XDd4
[3]基于keras的BiLstm与CRF实现命名实体标注 https://www.cnblogs.com/vipyoumay/p/ner-chinese-keras.html

六,关于训练模型知识

1⃣️快速试错,快速尝试
2⃣️使用融合模型进行训练效果更好
3⃣️在小模型验证方法正确,处理报错,大模型上服务器进行训练。

七,一些常用的终端命令行

[1]conda install tensorflow==1.14.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/
[2]pip install \-i https://pypi.tuna.tsinghua.edu.cn/simple/ \
https://mirrors.tuna.tsinghua.edu.cn/tensorflow/linux/gpu/tensorflow_gpu-1.4.0-cp27-none-linux_x86_64.whl
[4] pip install git+https://www.github.com/keras-team/keras-contrib.git
[5] pip install keras==2.1.4
[6]import tensorflow.compat.v1 as tf.               tf.disable_v2_behavior()
[7] pip install tensorflow==1.14.0 -I https://pypi.tuna.tsinghua.edu.cn/simple/
[8]pip install git+https://github.com/danielfrg/word2vec
[9]针对MATADATA 问题只要复制一个文件,到目录下即可
[10] 设置LINUX conda 环境变量    -I 插入. ZZ 保存
vim ~/profile
export PATH=/data/lisong/anaconda3/bin:$PATH.
source ~/profile
[11]安装对映清华镜像下tensorflow
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes
conda install tensorflow==1.14.0
[12]限制一块卡进行运行程序.    import os.  os.environ["CUDA_VISIBLE_DEVICE"] = 6
[13] git clone https://github.com/Determined22/zh-NER-TF.git  进行克隆
[14]
1.    词干提取(Stemming):词干提取是一个初级的、基于规则的脱去后缀(如“ing”,“ly”,“es”,“s”等等)的过程
2.    词元化(Lemmatization):另一方面,词元化,是一个组织好的、一步一步的获取词根的过程。
并使用了词汇表(单词在字典里的重要性)和形态学分析(单词结构与语法关系)
[15]ImportError: cannot import name 'run_classifier' from 'bert' (/opt/anaconda3/envs/tensorflow/lib/python3.7/site-packages/bert/__init__.py)
[16] chmod u+x *.sh  python. 为sh文件增加可执行权限
[17]
conda env list
conda activate tensorflow
pip list | grep bert
[18]ps aux | grep 75457
[19] nohup python my.py >> /usr/local/python/xxf/my.log 2>&1 &
[20]tensorboard --logdir=/Users/tobeace/PycharmProjects/acl2019_nested_ner的副本/logs/
[21]Not a TBLoader or TBPlugin subclass: <class 'tensorboard_plugin_wit.wit_plugin_loader.WhatIfToolPluginLoader'>
需要在tensor flow环境下启用
tensorflow可视化tensorboard “No graph definition files were found.” 错误
需要 返回一层文件夹即可;
[22]replace(##”,””)

【百度LIC2020事件抽取赛道】赛后小结(小白篇,大佬略过)相关推荐

  1. 基于百度2020语言与智能技术竞赛:事件抽取任务

    关注微信公众号:NLP分享汇.[喜欢的扫波关注,每天都在更新自己之前的积累] 文章链接:https://mp.weixin.qq.com/s/4oGMn1eZehGCBrmKJSf1_A ​[前言] ...

  2. 使用MRC(机器阅读理解)方式做事件抽取任务,基于2020百度事件抽取任务

    ​关注微信公众号:NLP分享汇.[喜欢的扫波关注,每天都在更新自己之前的积累] 文章链接:https://mp.weixin.qq.com/s/aKB6j42bC1MnWCFIEyjwQQ [前言] ...

  3. 百度机器阅读理解比赛赛后总结

    百度机器阅读理解比赛赛后总结 <!-- 文章内容 --><div data-note-content="" class="show-content&qu ...

  4. 事件抽取中的“门面技术”:事件名称生成浅谈

    6月10日,"网信中国"微信公众号发布消息称:微博热搜榜.热门话题榜暂停更新一周,这使得很多热榜平台都受到波及,而在吃瓜之余,我们更进一步地思考热点榜单以及热点名称生成背后的技术, ...

  5. 赏析“百度大脑事件图谱:洞察复杂世界中的事件知识”

    前言: 近年来,互联网生态经历了高速发展,数字信息呈爆炸式增长.<中国互联网发展状况统计报告>显示:截止到2020年3月,中国网民规模达9.04亿,网页总数超2978亿.繁杂.海量的信息给 ...

  6. 事件抽取与事件图谱构建

    公众号 系统之神与我同在 知识图谱是下一代人工智能的基础设施, 是实现可解释人工智能的重要手段. 事件图谱的意义:通用领域 丰富现有的知识图谱 支撑其它信息获取引擎 事件图谱构建的关键技术:事件抽取 ...

  7. 综述 | 事件抽取及推理 (下)

    本文转载在公众号:知识工场 . 上篇事件抽取及推理的推文已经介绍了事件抽取的基本方法,本篇主要介绍事件推理的相关工作.就目前来看,事件方向相关的研究还是以事件抽取为主流任务,当前大多都是在模型的框架和 ...

  8. 百度大脑事件图谱:洞察复杂世界中的事件知识

    近年来,互联网生态经历了高速发展,数字信息呈爆炸式增长.<中国互联网发展状况统计报告>显示:截止到2020年3月,中国网民规模达9.04亿,网页总数超2978亿.繁杂.海量的信息给人们对知 ...

  9. 论文导读 | 事件抽取技术发展现状

    1.   问题定义 事件抽取(Event Extraction)是一种面向非结构化文本或半结构化数据的信息抽取(Information Extraction)任务,与传统面向知识图谱的实体.关系.属性 ...

最新文章

  1. 关于C#调用非托管DLL,报“内存已损坏的”坑,坑,坑
  2. 架构师说了:不想做背锅侠?生产问题要这样查
  3. ●BZOJ 1934 [Shoi2007]Vote 善意的投票
  4. 关于SVM,面试官们都怎么问
  5. 模拟windows任务管理器列举系统进程,并关闭进程......
  6. Linq 实现 DataTable 行转列
  7. 编码GBK的不可映射字符
  8. python怎么退出调试模式_python – 在验尸调试时如何退出ipdb?
  9. 信息学奥赛一本通(1052:计算邮资)
  10. 设计师作品交流社区,让你的原创设计作品展示给世界
  11. Golang defer 快速上手
  12. linux新漏洞,「漏洞通告」Linux Kernel 信息泄漏权限提升漏洞(CVE-2020-8835)
  13. Keil中如何生成bin文件
  14. 2021年常规赛NBA球员数据分析
  15. Alien Skin X7PS调色滤镜插件下载及PS调色滤镜教程
  16. 生信工作流框架搭建 | 02-nextflow 实战
  17. 机器学习:深度信念网络(DBN)原理和实现
  18. 【计算机网络】6 路由器与静态路由配置
  19. Docker 容器监控方案随手记
  20. 银行欺诈banking fraud

热门文章

  1. PDF文件只能打印出第一页
  2. 改文拽少爷的校花女友33
  3. CSS、HTML补充
  4. 解决 C# 中 Using ‘UseMvcWithDefaultRoute‘ to configure MVC is not supported while using Endpoint Routin
  5. 顾大嫂贴肉藏了尖刀 水浒传
  6. Pytorch入门:60分钟快速入门,第一节:张量(tensor)
  7. Pytorch的骚操作
  8. JavaScript百炼成仙 1.15 天秀
  9. 那些从阿里离职的人,凭什么占据了中国互联网行业的半壁江山?
  10. c语言GLUT头文件下载,GLUT教程.pdf