个人   github

BERT本质上是一个两段式的NLP模型。第一个阶段叫做:Pre-training,跟WordEmbedding类似,利用现有无标记的语料训练一个语言模型。第二个阶段叫做:Fine-tuning,利用预训练好的语言模型,完成具体的NLP下游任务。

Google已经投入了大规模的语料和昂贵的机器帮我们完成了Pre-training过程 附上中文预训练bert链接:https://pan.baidu.com/s/1pFY_VV6zbwwSuMCSE7QqJQ 提取码: auyr ,

中文预训练BERT-wwm(Pre-Trained Chinese BERT with Whole Word Masking):

模型简称 语料 Google下载 讯飞云下载
BERT-wwm-ext, Chinese 中文维基+
通用数据[1]
TensorFlow 
PyTorch
TensorFlow(密码thGd) 
PyTorch(密码bJns)
BERT-wwm, Chinese 中文维基 TensorFlow 
PyTorch
TensorFlow(密码mva8) 
PyTorch(密码8fX5)
BERT-base, ChineseGoogle 中文维基 Google Cloud -
BERT-base, Multilingual CasedGoogle 多语种维基 Google Cloud -
BERT-base, Multilingual UncasedGoogle 多语种维基 Google Cloud

这里主要介绍fine-tuning过程。

回到Github中的代码,只有run_classifier.py和run_squad.py是用来做fine-tuning 的,其他可以暂时不考虑。这里使用run_classifier.py进行文本相似度(本质分类建模)。

代码解析

从主函数开始,可以发现它指定了必须的参数:

data_dir指的是我们的输入数据的文件夹路径。查看代码,不难发现,作者给出了输入数据的格式:

可以发现它要求的输入分别是guid, text_a, text_b, label,其中text_b和label为可选参数。例如我们要做的是单个句子的分类任务,那么就不需要输入text_b;另外,在test样本中,我们便不需要输入lable。

这里的task_name,一开始可能不好理解它是用来做什么的。仔细查看代码可以发现:

task_name是用来选择processor的。

修改 processor

任何模型的训练、预测都是需要有一个明确的输入,而BERT代码中processor就是负责对模型的输入进行处理。我们以分类任务的为例,介绍如何修改processor来运行自己数据集上的fine-tune。在run_classsifier.py文件中我们可以看到,google对于一些公开数据集已经写了一些processor,如XnliProcessor,MnliProcessor,MrpcProcessorColaProcessor。这给我们提供了一个很好的示例,指导我们如何针对自己的数据集来写processor。

对于一个需要执行训练、交叉验证和测试完整过程的模型而言,自定义的processor里需要继承DataProcessor,并重载获取label的get_labels和获取单个输入的get_train_examples,get_dev_examplesget_test_examples函数。其分别会在main函数的FLAGS.do_trainFLAGS.do_evalFLAGS.do_predict阶段被调用。
这三个函数的内容是相差无几的,区别只在于需要指定各自读入文件的地址。

get_train_examples为例,函数需要返回一个由InputExample类组成的listInputExample类是一个很简单的类,只有初始化函数,需要传入的参数中guid是用来区分每个example的,可以按照train-%d'%(i)的方式进行定义。text_a是一串字符串,text_b则是另一串字符串。在进行后续输入处理后(BERT代码中已包含,不需要自己完成) text_a和text_b将组合成[CLS] text_a [SEP] text_b [SEP]的形式传入模型。最后一个参数label也是字符串的形式,label的内容需要保证出现在get_labels函数返回的list里。

class SelfProcessor(DataProcessor):"""Processor for the CoLA data set (GLUE version)."""def get_train_examples(self, data_dir):file_path = os.path.join(data_dir, 'train.csv')with open(file_path, 'r', encoding="utf-8") as f:reader = f.readlines()examples = []for index, line in enumerate(reader):guid = 'train-%d' % indexsplit_line = line.strip().split("\t")print(split_line)text_a = tokenization.convert_to_unicode(split_line[1])text_b = tokenization.convert_to_unicode(split_line[2])label = split_line[3]examples.append(InputExample(guid=guid, text_a=text_a,text_b=text_b, label=label))return examplesdef get_dev_examples(self, data_dir):file_path = os.path.join(data_dir, 'val.csv')with open(file_path, 'r', encoding="utf-8") as f:reader = f.readlines()examples = []for index, line in enumerate(reader):guid = 'train-%d' % indexsplit_line = line.strip().split("\t")text_a = tokenization.convert_to_unicode(split_line[1])text_b = tokenization.convert_to_unicode(split_line[2])label = split_line[3]examples.append(InputExample(guid=guid, text_a=text_a,text_b=text_b, label=label))return examplesdef get_test_examples(self, data_dir):"""See base class."""file_path = os.path.join(data_dir, 'test.csv')with open(file_path, 'r', encoding="utf-8") as f:reader = f.readlines()examples = []for index, line in enumerate(reader):guid = 'train-%d' % indexsplit_line = line.strip().split("\t")text_a = tokenization.convert_to_unicode(split_line[1])text_b = tokenization.convert_to_unicode(split_line[2])label = split_line[3]examples.append(InputExample(guid=guid, text_a=text_a,text_b=text_b, label=label))return examplesdef get_labels(self):"""See base class."""return ["0", "1"]def _create_examples(self, lines, set_type):"""Creates examples for the training and dev sets."""examples = []for (i, line) in enumerate(lines):# Only the test set has a headerif set_type == "test" and i == 0:continueguid = "%s-%s" % (set_type, i)if set_type == "test":text_a = tokenization.convert_to_unicode(line[2])label = "0"else:text_a = tokenization.convert_to_unicode(line[2])label = tokenization.convert_to_unicode(line[4])examples.append(InputExample(guid=guid, text_a=text_a, text_b=None, label=label))return examples

可以发现这个processor就是用来对data_dir中输入的数据进行预处理的。
同时也能发现,在data_dir中我们需要将数据处理成.tsv格式,训练集、开发集和测试集分别是train.tsv, dev.tsv, test.tsv,这里我们暂时只使用train.tsv和dev.tsv。另外,label在get_labels()设定,此处为二分类,则将label设定为[“0”,”1”],同时_create_examples()中,给定了如何获取guid以及如何给text_a, text_b和label赋值。

准备好train.tsv, dev.tsv以及test.tsv

新建一个跟自己task_name对应的processor,用于将train.tsv、dev.tsv以及test.tsv中的数据提取出来赋给text_a, text_b, label

下载好Pre-training模型,设定好相关参数,run。

运行 fine-tune

之后就可以直接运行run_classsifier.py进行模型的训练。在运行时需要制定一些参数,一个较为完整的运行参数如下所示:

export BERT_BASE_DIR=/path/to/bert/chinese_L-12_H-768_A-12 #全局变量 下载的预训练bert地址
export MY_DATASET=/path/to/xnli #全局变量 数据集所在地址python run_classifier.py --task_name=sim  #自己添加processor在processors字典里的key名--do_train=true --do_eval=true --dopredict=true --data_dir=$MY_DATASET 训练数据路径--vocab_file=$BERT_BASE_DIR/vocab.txt --bert_config_file=$BERT_BASE_DIR/bert_config.json --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt --max_seq_length=128  #语句长度--train_batch_size=32 --learning_rate=5e-5 --num_train_epochs=2.0 --output_dir=./sim_output/ #模型输出路径

BERT 源代码(其他)

在开始训练我们自己fine-tune的BERT后,我们可以再来看看BERT代码里除了processor之外的一些部分。
我们可以发现,process在得到字符串形式的输入后,在file_based_convert_examples_to_features里先是对字符串长度,加入[CLS]和[SEP]等一些处理后,将其写入成TFrecord的形式。这是为了能在estimator里有一个更为高效和简易的读入。

我们还可以发现,在create_model的函数里,除了从modeling.py获取模型主干输出之外,还有进行fine-tune时候的loss计算。因此,如果对于fine-tune的结构有自定义的要求,可以在这部分对代码进行修改。如进行NER任务的时候,可以按照BERT论文里的方式,不只读第一位的logits,而是将每一位logits进行读取。

BERT这次开源的代码,由于是考虑在google自己的TPU上高效地运行,因此采用的estimator是tf.contrib.tpu.TPUEstimator,虽然TPU的estimator同样可以在gpu和cpu上运行,但若想在gpu上更高效地做一些提升,可以考虑将其换成tf.estimator.Estimator,于此同时model_fn里一些tf.contrib.tpu.TPUEstimatorSpec也需要修改成tf.estimator.EstimatorSpec的形式,以及相关调用参数也需要做一些调整。在转换成较普通的estimator后便可以使用常用的方式对estimator进行处理,如生成用于部署的.pb文件等。

参考:

1、http://www.52nlp.cn/bert-paper-%E8%AE%BA%E6%96%87-%E6%96%87%E7%AB%A0-%E4%BB%A3%E7%A0%81%E8%B5%84%E6%BA%90%E6%B1%87%E6%80%BB

2、https://www.jianshu.com/p/aa2eff7ec5c1

3、https://juejin.im/post/5c093c04f265da611d667584?utm_source=gold_browser_extension

BERT中文实战(文本相似度)相关推荐

  1. 中文/英文 文本相似度/文本推理/文本匹配数据集汇总(SNLI、MSRP、MultiNLI、Quora、SciTail、SICK、STS、CCKS2018、LCQMC、OCNLI、XNLI)

    中文/英文 文本相似度/文本推理/文本匹配数据集汇总(SNLI.MSRP.MultiNLI.Quora.SciTail.SICK.STS.CCKS2018.LCQMC.OCNLI.XNLI) 1. 所 ...

  2. bert 中文基于文本的问答系统

    bert 中文基于文本的问答系统 # -!- coding: utf-8 -!- import torch if torch.cuda.is_available():device = torch.de ...

  3. BERT求古诗文本相似度

    大概学了原理,简单实践一下发现了一些问题: 1.对于不同长度的诗句可能要用0来补齐向量长度 2.直接用两个句子的last_hidden_state向量计算余弦相似度时会报梯度相关的错误 不能计算.不很 ...

  4. 【创新实训】BERT4EL,基于文本相似度的实体消歧实现

    任务描述 现有douban.mtime.maoyan三个来源的电影,包含名称.简介.导演.演员.类型等等属性. 需要相同的电影融合为一个电影条目,其中maoyan数量很少,可以合并到mtime中. 参 ...

  5. 百度千言-中文文本相似度实战

    文章目录 百度千言-中文文本相似度实战 任务1:报名比赛,下载比赛数据集并完成读取 任务2:对句子对提取TFIDF以及统计特征,训练和预测 任务3:加载中文词向量,自己训练中文词向量 任务4:使用中文 ...

  6. 使用BERT做中文文本相似度计算与文本分类

    转载请注明出处,原文地址: https://terrifyzhao.github.io/2018/11/29/使用BERT做中文文本相似度计算.html 简介 最近Google推出了NLP大杀器BER ...

  7. 【NLP实战】基于ALBERT的文本相似度计算

    实战是学习一门技术最好的方式,也是深入了解一门技术唯一的方式.因此,NLP专栏推出了实战专栏,让有兴趣的同学在看文章之余也可以自己动手试一试. ALBERT是一个比BERT要轻量,效果更好的模型,本篇 ...

  8. 最准的中文文本相似度计算工具

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx text2vec, chinese text to vetor.(文本向量化表示工具,包括词向 ...

  9. Bert实战--文本分类(一)

    使用Bert预训练模型进行文本分类 bert做文本分类,简单来说就是将每句话的第一个位置加入了特殊分类嵌入[CLS].而该[CLS]包含了整个句子的信息,它的最终隐藏状态(即,Transformer的 ...

最新文章

  1. python写小程序-用python写个简单的小程序,编译成exe跑在win10上
  2. 初级算法——两个物种(蓝桥杯)
  3. try catch finally 执行顺序问题
  4. 生成网页没有标题_网页设计公司有哪些?用这个快速建站!
  5. ELK报错hese locations are not writable or multiple nodes were started without inc
  6. spring事务(三)
  7. c++:json字符串拼接,json对象组装
  8. 去BAT面试完的Mysql面试题总结(55道)
  9. Celery多个定时任务使用RabbitMQ,Queue冲突解决
  10. 字符串怎样实例化成对象
  11. 老版本xcode下载_下载xcode旧版历史版本
  12. Android篮球计分器课程设计,篮球计分器课程设计详解.doc
  13. 取字模软件的资源与链接
  14. Windows Server2012 服务器修改密码过期时间
  15. 产品经理如何进行用户需求分析?
  16. AES算法中S盒的FPGA实现
  17. Unity实现发光材质
  18. 18个最好的代码编辑器/IDE工具,希望你会喜欢。
  19. 华为西欧副总裁:华为很快就能推出自研操作系统
  20. MySQL - 用户管理

热门文章

  1. 经典排序算法-----选择排序(C语言实现)
  2. html多张图片合成,js+canvas多张图片合成一张图片代码
  3. 计算机985大学高考分数,高考志愿“捡漏王”。460分被985大学录取,考生填报志愿要注意...
  4. QUAR_CH_USB2TTL V1 USB转4路UART串口侦听板设计日志2
  5. 微信程序开发之小程序交互
  6. 编译器与解释器的区别
  7. python扩展库xlwt支持对excel_Python扩展库xlwt支持对Excel2003或更低版本的Excel文件进行写操作...
  8. 树结构使用实例---实现数组和树结构的转换
  9. block()/blockFirst()/blockLast() are blocking,which is not supported in thread reactor-http-kqueue-3
  10. axios实现同步请求