当前位置: 首页 > 编程日记 > 正文

干货 | 谷歌BERT模型fine-tune终极实践教程

640?wx_fmt=jpeg


作者 | 奇点机智


从11月初开始,Google Research就陆续开源了BERT的各个版本。Google此次开源的BERT是通过TensorFlow高级API—— tf.estimator进行封装(wrapper)的。因此对于不同数据集的适配,只需要修改代码中的processor部分,就能进行代码的训练、交叉验证和测试。


奇点机智技术团队将结合利用BERT在AI-Challenger机器阅读理解赛道的实践表现以及多年的NLP经验积累,为大家奉上BERT在中文数据集上的fine tune全攻略。


在自己的数据集上运行 BERT


BERT的代码同论文里描述的一致,主要分为两个部分。一个是训练语言模型(language model)的预训练(pretrain)部分。另一个是训练具体任务(task)的fine-tune部分。在开源的代码中,预训练的入口是在run_pretraining.py而fine-tune的入口针对不同的任务分别在run_classifier.py和run_squad.py。其中run_classifier.py适用的任务为分类任务。如CoLA、MRPC、MultiNLI这些数据集。而run_squad.py适用的是阅读理解(MRC)任务,如squad2.0和squad1.1。


预训练是BERT很重要的一个部分,与此同时,预训练需要巨大的运算资源。按照论文里描述的参数,其Base的设定在消费级的显卡Titan x 或Titan 1080ti(12GB RAM)上,甚至需要近几个月的时间进行预训练,同时还会面临显存不足的问题。


不过所幸的是谷歌满足了Issues#2(https://github.com/google-research/bert/issues/2)里各国开发者的请求,针对大部分语言都公布了BERT的预训练模型。因此在我们可以比较方便地在自己的数据集上进行fine-tune。


下载预训练模型


对于中文而言,google公布了一个参数较小的BERT预训练模型。具体参数数值如下所示:


Chinese Simplified and Traditional, 12-layer, 768-hidden, 12-heads, 110M parameters


模型的下载链接:(https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip)


对下载的压缩文件进行解压,可以看到文件里有五个文件,其中bert_model.ckpt开头的文件是负责模型变量载入的,而vocab.txt是训练时中文文本采用的字典,最后bert_config.json是BERT在训练时,可选调整的一些参数。


修改 processor


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

对于一个需要执行训练、交叉验证和测试完整过程的模型而言,自定义的processor里需要继承DataProcessor,并重载获取label的get_labels和获取单个输入的get_train_examples,get_dev_examples和get_test_examples函数。其分别会在main函数的FLAGS.do_train、FLAGS.do_eval和FLAGS.do_predict阶段被调用。


这三个函数的内容是相差无几的,区别只在于需要指定各自读入文件的地址。


以get_train_examples为例,函数需要返回一个由InputExample类组成的list。InputExample类是一个很简单的类,只有初始化函数,需要传入的参数中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里。


举一个例子,假设我们想要处理一个能够判断句子相似度的模型,现在在data_dir的路径下有一个名为train.csv的输入文件,如果我们现在输入文件的格式如下csv形式:


1,你好,您好
0,你好,你家住哪 


那么我们可以写一个如下的get_train_examples的函数。当然对于csv的处理,可以使用诸如csv.reader的形式进行读入。


def get_train_examples(self, data_dir):
    file_path = os.path.join(data_dir, 'train.csv')
    with open(file_path, 'r'as f:
        reader = f.readlines()
    examples = []
    for index, line in enumerate(reader):
        guid = 'train-%d'%index
        split_line = line.strip().split(',')
        text_a = tokenization.convert_to_unicode(split_line[1])
        text_b = tokenization.convert_to_unicode(split_line[2])
        label = split_line[0]
        examples.append(InputExample(guid=guid, text_a=text_a, 
                                     text_b=text_b, label=label))
    return examples


同时对应判断句子相似度这个二分类任务,get_labels函数可以写成如下的形式:


def get_labels(self):
    return ['0','1']


在对get_dev_examples和get_test_examples函数做类似get_train_examples的操作后,便完成了对processor的修改。其中get_test_examples可以传入一个随意的label数值,因为在模型的预测(prediction)中label将不会参与计算。


修改 processor 字典


修改完成processor后,需要在在原本main函数的processor字典里,加入修改后的processor类,即可在运行参数里指定调用该processor。


processors = {
      "cola": ColaProcessor,
      "mnli": MnliProcessor,
      "mrpc": MrpcProcessor,
      "xnli": XnliProcessor, 
      "selfsim": SelfProcessor #添加自己的processor
  }


运行 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=selfsim \ #自己添加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=/tmp/selfsim_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文件等。


GitHub Issues 里一些有趣的内容


从google对BERT进行开源开始,Issues里的讨论便异常活跃,BERT论文第一作者Jacob Devlin也积极地在Issues里进行回应,在交流讨论中,产生了一些很有趣的内容。


在GitHub Issues#95 (https://github.com/google-research/bert/issues/95) 中大家讨论了BERT模型在今年AI-Challenger比赛上的应用。我们也同样尝试了BERT在AI-Challenger的机器阅读理解(mrc)赛道的表现。如果简单得地将mrc的文本连接成一个长字符串的形式,可以在dev集上得到79.1%的准确率。


如果参考openAI的GPT论文(https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf)里multi-choice的形式对BERT的输入输出代码进行修改则可以将准确率提高到79.3%。采用的参数都是BERT默认的参数,而单一模型成绩在赛道的test a排名中已经能超过榜单上的第一名。因此,在相关中文的任务中,bert能有很大的想象空间。


在GitHub Issues#123(https://github.com/google-research/bert/issues/123)中,@hanxiao(https://github.com/hanxiao)给出了一个采用ZeroMQ便捷部署BERT的service,可以直接调用训练好的模型作为应用的接口。同时他将BERT改为一个大的encode模型,将文本通过BERT进行encode,来实现句子级的encode。此外,他对比了多GPU上的性能,发现bert在多GPU并行上的出色表现。


总结


总的来说,Google此次开源的BERT和其预训练模型是非常有价值的,可探索和改进的内容也很多。相关数据集上已经出现了对BERT进行修改后的复合模型,如squad2.0上哈工大(HIT)的AoA + DA + BERT以及西湖大学(DAMO)的SLQA + BERT。 在感谢google这份付出的同时,我们也可以借此站在巨人的肩膀上,尝试将其运用在自然语言处理领域的方方面面,让人工智能的梦想更近一步。


原文地址:https://www.jianshu.com/p/aa2eff7ec5c1



BDTC 2018

精彩纷呈



2018 年12月6-8 日,由中国计算机学会主办,CCF 大数据专家委员会承办,CSDN、中科天玑数据科技股份有限公司协办的 2018 中国大数据技术大会(BDTC 2018),将在北京新云南皇冠假日酒店隆重举行。


除 Keynote 外,主办方精心策划了 13 场专题技术和行业论坛,涵盖大数据分析与生态系统、深度学习、推荐系统、大数据安全与政策、大数据可视分析、精准医疗大数据、数据科学与大数据技术教育、数据库、金融大数据、知识图谱、工业大数据、区块链、交通与旅游大数据等主题。


届时,近百位技术专家及行业领袖将齐聚于此,聚焦大数据技术如何促进数字经济迅速发展,关注大数据新应用,思辨通达,深入解析热门技术在行业中的实践和落地。紧贴时代脉搏,走近数据前沿。

       640?wx_fmt=jpeg


推荐阅读

ImageNet时代将终结?何恺明新作:Rethinking ImageNet Pre-training

“万”字谏言,给那些想学Python的人,建议收藏后细看!

2W台服务器、每秒数亿请求,微信如何不“失控”?

Istio,下一个Kubernetes?

炸了!刚写完这段代码,就被开除了…

中国可以没有俞敏洪, 区块链不能没有这些女王们, 女性从业者现状调查

相关文章:

java简介 ppt 精_《JAVA》5选择结构精篇课件.ppt

《JAVA》5选择结构精篇课件选 择 结 构 if 语句 if – else语句 Switch语句 块作用域语句又被称为复合语句,其格式为:用一对花括号将若干条语句括起来,目的是从语法上可以将多条语句解释成一条语句。 { int temp; temp a; a b; …

UPDATE STATISTICS 有何妙用?

txlicenhe 马可 一直没有关注它,今天刚学到的一招,还没彻底弄清楚。 情况是这样,有一个视图,用到了好几个表,其中一个表改了一些资料,在前台操作时总是超时过期(前台设置超时时间不长 60s&#…

js with用法

1)简要说明 with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性。要给对象创建新的属性,必须明确地引用该对象。 2)语法格式 with(object instance) { //代码块 } 有…

大数据时代,谁的眼神锁定你?

数据时代当前,欢迎来到楚门的世界。双十一余韵未歇,刚处理完一波售后及退件等“剁手后遗症”的各方人马也已经为再战双十二做好了准备。截至 12 日零点,天猫双十一成交额达 2135 亿元。与此同时,据国家邮政局监测数据显示&#xf…

Java类Demo中存在_Java中的数据类型转换

先来看一个题:Java类Demo中存在方法func0、func1、func2、func3和func4,请问该方法中,哪些是不合法的定义?( )public class Demo{float func0(){byte i1;return i;}float func1(){int i1;return;}float func2(){short i2;return i…

Exchange2000需要创建的3个SMTP服务实例

前一阵搞了邮件系统的安全加固,前面说的SA是一个方面,总觉得在SMTP上还有文章可做。分析一下公司的系统环境,SMTP的访问大概分这么三类:1、来自客户端的访问。2、来自公司业务系统服务器的访问。3、来自外部其它邮件服务器的访问。…

小程序门店自提功能开启,酷客多带你玩转O2O模式

目前小程序的发展已经如火如荼,不管是新型行业还是传统行业,都进军小程序领域,由此为广大消费者带来了方便与快捷,现在许多商家品牌将线上线下结合互动起来,推广门店自提的模式,酷客多小程序(ht…

“基因编辑婴儿”惹争议,你或许不知道机器学习在脱靶效应中的作用?

作者|琥珀出品| AI科技大本营又一次,计算机科学家和生物学者站在一起,对抗人类向内探索的挑战——用机器学习预测基因编辑 CRISPR 中的脱靶效应。今年年初,发表在《自然》生物工程杂志上的一篇论文描述了 Elevation 这项工具。该工具由微软研…

Flash Player漏洞利用Exploiting Flash Reliably

以下消息来自幻影论坛[Ph4nt0m]邮件组前两天推荐过Mark Dowd的Paper “Exploiting Flash Reliably”[url]http://hi.baidu.com/secway/blog/item/242655971275376855fb96d8.html[/url]学习了一下,很好很强大。为以后Flash Player漏洞的利用开辟了一条崭新崭新的道路…

java好用的hbase库_Hbase入库基于java

计划每周写一篇博客,督促自己快点学习,懒惰会让人上瘾,努力奋斗,不忘初心。某天,忽然来任务,要做hbse入库,之前自学过hbase,感觉挺简单的,网上搜了些model直接撸码&#…

linux(ubuntu)环境下安装及配置JDK

安装完IDEA之后遇到了问题,发现jdk安装完之后配置环境变量好困难,下面总结一下我的安装及配置方式: JDK下载链接:http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c7dfaa008135/jdk-8u144-linux-x64.tar.gz 作者…

专访英特尔AIPG全球研究负责人Casimir Wierzynski:物理学、隐私和大脑将根本性塑造AI...

记者|琥珀出品| AI 科技大本营在 11 月 14 日至 15 日在北京召开的英特尔人工智能大会(AIDC)上,英特尔人工智能产品事业部(AIPG)全球研究负责人 Casimir Wierzynski 发表了主题为《人工智能研究——物理学、隐私和大脑…

flash php socket通信_php与flash as3 socket通信传送文件实现代码

前段时间在flashseer看到有人提到:可以通过socket方式传送swf文件,让用户无法获取到swf文件… 当时还没有出as3的反编译,所以对程序的保护没有在意.随着反编译程序的平民化,不希望别人看到源代码的朋友就比较着急…通过socket方式传送swf文件来避免泄漏源代码的思路(只适用as3)…

全线衰退:PC产业一枝孤秀

之三:全线衰退:PC产业一枝孤秀 在3C中,也许个人电脑(PC)产业算是当今中国最有希望的。中国的计算机工业号称已有50年历程,但成为民用产品的起始点应在30年前,与改革开放同时起步。1978年,国家成立了计算机工…

用Gogs在Windows上搭建Git服务

1.下载并安装Git,如有需求,请重启服务器让Path中的环境变量生效。2.下载并安装Gogs,请注意,在Windows中部署时,请下载MiniWinService(mws)版本。3.在MariaDB中创建一个命名为Gogs的数据库&#…

wamp安装多版本php,WampServer安装多个php版本

早期的WampServer安装多个版本php很简单,只需要单击php下的Get more...就行了,WampServer会自动导航到http://www.wampserver.com/addons_php.php下去安装php,但目前这种方式好像不行了,该页面找不到了,那么我们只能手…

利用Windows自带服务架设免费邮件服务器

在Windows Server 2003中带有完整的SMTP和POP3服务,并且能够支持有域和无域两种环境,非常便于中小型企业实施。今天,小编就以Windows Server 2003企业版为例带领大家架设一台免费的邮件服务器,希望能够对各位朋友学习邮件服务器提…

阿里首次开源深度学习框架X-Deep Learning

今年,各企业在开源路上的势头可以说是“你追我赶”,谁也不甘落后。6 月,小米宣布开源自己在移动端深度学习框架 MACE;9 月,腾讯 AI Lab 宣布开源一款自动化深度学习模型压缩与加速的框架——PocketFlow。双十一刚过&am…

应用基于资产的开发到 SOA 的服务中1

SOA 的主要原则之一是在整个 SOA 生命周期中将服务视为可重用资产。因此,务必在 SOA 中对服务应用正式的资产开发流程和指南。本文可帮助 IT 架构师、项目经理和 SOA 管理员全面了解一些主要 IBM 产品如何协作来帮助有效地在 SOA 中将服务作为可重用资产进行创建、使…

用Piranha来实现WEB的负载均衡

简述:利用(LVSPiranha)基于完整开源软件的架构可以提供一个简单的负载均衡及高可用的服务架构。LVS 集群采用 IP 负载均衡技术和基于内容请求分发技术。调度器具有很好的吞吐率(在DR模式下),将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故 障,…

SQLServer数据库试题及答案

选择题:(20分) 1、根据关系数据基于的数据模型——关系模型的特征判断下列正确的一项:(___) A、只存在一对多的实体关系,以图形方式来表示。 B、以二维表格结构来保存数据,在…

php中怎样阻止网页进行跳转,阻止php页面跳转方法

阻止php页面跳转方法一、 header 函数header()函数的主要功能是将HTTP协议标头(header)输出到浏览器。参数void header (string string [,bool replace [,int http_response_code]])可选参数replace指明是替换前一条类似标头还是添加一条相同类型的标头,默认为替换。…

张宏江:人工智能的长远发展需要有人坐冷板凳

从金山 CEO 退休两年后,除了在源码资本任职投资合伙人,张宏江又在刚刚成立不久的北京智源人工智能研究院担任首届理事长,致力于推动不同行业分享大数据,让从事基础研究院所和 AI 的创业公司更容易获得数据。作为一个横跨产学研、投…

Python 中的进程、线程、协程、同步、异步、回调(一)

在进一步之前,让我们先回顾一下各种上下文切换技术。 不过首先说明一点术语。当我们说“上下文”的时候,指的是程序在执行中的一个状态。通常我们会用调用栈来表示这个状态——栈记载了每个调用层级执行到哪里,还有执行时的环境情况等所有有关…

php iis6 安装ssl证书,在IIS下部署SSL证书实现HTTPS

HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版。谷歌已经制定了一项长远的计划,它的最终目标是将所有通过HTTP协议呈现的网页标为“不安全”,对于站长来说,部署SSL证书来迁移到HTTPS是一个现实和重要的问题,那么…

今晚8点直播 | 微软亚洲研究院副院长刘铁岩:机器学习技术前沿与未来展望

人工智能正受到越来越多的关注,而这波人工智能浪潮背后的最大推手就是“机器学习”。机器学习从业者在当下需要掌握哪些前沿技术?展望未来,又会有哪些技术趋势值得期待? AI科技大本营联合华章科技特别邀请到了微软亚洲研究院副院…

11月最佳机器学习开源项目Top10!

整理 | Jane出品 | AI科技大本营过去一个月,我们从近 250 个机器学习开源项目中挑选出了最受大家关注的前十名。这些项目在 GitHub 上平均 Stars 数为 2713。这些项目涉及由 Google AI Research 开源的 BERT 预训练模型、DeepMind 开源的图网络库、Facebook Researc…

notepad php发布网站,谈谈如何把WordPress部署到服务器上

第一次部署本网站,稀里糊涂差不多用了大半天,真是惭愧呀,很想狠狠的抽自己一下。老子信了你的邪!!!废话不多说,大概的步骤是:前奏1.注册域名--云主机购买--域名备案--域名解析(dodo也是首次对这…

单列索引和复合索引的使用

表结构: mysql> desc car; ----------------------------------------------------------- | Field | Type | Null | Key | Default | Extra | ----------------------------------------------------------- | id | int(3) | NO …

java学习1

工作了很久,以前学的技术都差不多忘了,为了不荒废技术,现在开始起学习java,并将学习中遇到的问题加以记录。问题1、Exception in thread "main" java.lang.NoClassDefFoundError解决方法:这类问题导致的可能…