本文(部分内容)翻译自文章A Visual Guide to Using BERT for the First Time,其作者为Jay Alammar,访问网址为:http://jalammar.github.io/a-visual-guide-to-using-bert-for-the-first-time/ ,可以作为那些不熟悉BERT的读者首次阅读。文章中如有翻译不当之处,还请批评指正。



  本文是关于如何使用BERT的变异版本来进行句子分类的简单教程。该例子足够简单,因此可以作为首次使用BERT的介绍,当然,它也包含了一些关键性的概念。

数据集:SST2

  本文中使用的数据集为SST2,它包含了电影评论的句子,每一句带有一个标签,或者标注为正面情感(取值为1),或者标注为负面情感(取值为0)。

模型:句子情感分类

  我们的目标是创建一个模型,它能够处理一个句子(就行我们数据集中的句子那样)并且输出1(表明该句子具有正面情感)或者0(表明该句子具有负面情感)。我们设想它长这样:



事实上,该模型包含两个模型:

  • DistillBERT会处理句子并把它提取后的信息传递给下一个模型。DistillBERTBERT的变异版本,由HuggingFace小组开发和开源。它是BERT的更轻量、更快速的版本,同时它的表现基本与BERT相近。
  • 下一个模型,从scikit learn中导入的一个基本的逻辑回归模型(Logistic Regression model),它会利用 DistillBERT的处理结果,然后将句子进行分类成正面情感或者负面情感(分别为1或者0)。

在两个模型之间传递的数据为1个768维的向量。我们可以把这个向量理解为这个句子的嵌入向量(Embedding Vector),用于分类。

模型训练

  尽管我们用了两个模型,但是我们只会训练逻辑回归模型。对于DistillBERT,我们会使用已经预训练好的英语模型。该模型,既不会被训练也不会做微调(fine-tuned),直接进行句子分类。这是因为,我们可以从BERT中获得句子分类的能力。这尤其适合BERT输出的第一个位置(跟[CLS]标志相关)。我相信这是由于BERT的第二个训练模型——下一句分类(Next sentence classification)。该模型的目标在于封装句子级别的语料进行训练,并输出第一个位置。transformers库已经提供了DistillBERT的操作,作为其预训练模型版本。

教程总览

  以下是该教程的计划安排。首先我们会使用DistillBERT来产生2000个句子的句子向量。



这一步之后我们不会接触DistillBERT。接下去只是Scikit Learn的操作。我们将数据集分为训练集和测试集。



接下来我们在训练集上使用逻辑回归模型进行训练。

单次预测如何计算

  在我们讲解代码和解释如何训练模型之前,让我们看一下已预训练好的模型如何进行预测。

  我们尝试着预测句子“a visually stunning rumination on love”。第一步是使用BERT tokenizer 将句子划分成tokens。然后加上句子分类的特殊tokens([CLS]在开始位置,[SEP]在句子结尾)。



第三步是通过已预训练好的模型的嵌入表(embedding table)将每一个tokens映射成各自的id。这一步可以参考word embedding,参考阅读文章The Illustrated Word2vec



我们注意到,tokenizer仅需要一行代码就能完成以上步骤。

tokenizer.encode("a visually stunning rumination on love", add_special_tokens=True)

我们的输入句子现在已经处理成DistilBERT可以处理的格式了。

如果你已经读过Illustrated BERT,那么这一步的可视化如下:

DistilBERT处理流程

  DistilBERT处理输入向量的流程类似于BERT。输出是每一个token对应一个向量。每个向量由768个浮点型数字组成。



因为这是一个句子分类任务,故我们忽略其他向量而只取第一个向量(跟[CLS]相关的那个)。这个向量我们会作为逻辑回归模型的输入。



  从这里开始,就是逻辑回归模型的事儿了,它负责将输入的向量进行分类。我们设想一个预测的流程长这样:

代码

  文章中用到的数据集下载网址为:https://github.com/clairett/pytorch-sentiment-classification/raw/master/data/SST2/train.tsv。下载DistillBERT模型文件,网址为:https://www.kaggle.com/abhishek/distilbertbaseuncased

  原文中这部分的代码讲解比较多,我这边忽略过去了,笔者想按自己的思路来处理,因此这部分内容会有调整。完整的思路如下:

  下载数据集和模型文件,与代码放在同一目录下。建立jupyter脚本,先载入必要的模块:



  接着我们利用pandas读取训练集数据,并统计标签值的频数:



  读取DistillBERT模型文件并创建tokenizer:



  通过tokenizer完成句子切分成tokens,并映射到id:



  由于每个句子的长度可能会不同,因此需要对句子进行填充(Padding),保持每个句子的输入维度一致,句子填充的长度为该数据集中句子长度的最大值。



  对句子进行填充后,然后再进行Masking。这是因为如果我们直接将padded传入BERT,这会造成一定的困扰。我们需要创建另一个变量,来告诉模型去mask之前的填充结果。这就是attention_mask的作用:



  我们的输入已经准备完毕,接下来我们尝试着用DistillBERT来获取向量,也就是之前说的第一步。这一步的处理结果会返回last_hidden_states,而我们的分类模型只需要获取[CLS]这个token对应的输出向量。



可视化的操作说明如下图:



  这样,我们就把之前的每一个句子映射成了1个768维的句子向量,然后就利用逻辑回归模型直接进行训练就可以了。



  最后,我们来看一下这个模型在测试集上的效果:

总结

  本文主要介绍了如何利用DistillBERT和已经封装好的transformers模块,结合逻辑回归模型对英文句子进行文本二分类。后续笔者还会研究在中文上的文本分类以及如何进行微调(Fine_tuning)。

  本项目的Gitlab地址为:https://gitlab.com/jclian91/sentence_classify_using_distillBERT_LR,原文章作者的Github地址为https://github.com/jalammar/jalammar.github.io/blob/master/notebooks/bert/A_Visual_Notebook_to_Using_BERT_for_the_First_Time.ipynb

  感谢大家阅读~

NLP(十九)首次使用BERT的可视化指导的更多相关文章

  1. NLP(二十)利用BERT实现文本二分类

      在我们进行事件抽取的时候,我们需要触发词来确定是否属于某个特定的事件类型,比如我们以政治上的出访类事件为例,这类事件往往会出现"访问"这个词语,但是仅仅通过"访问&q ...

  2. WPF,Silverlight与XAML读书笔记第三十九 - 可视化效果之3D图形

    原文:WPF,Silverlight与XAML读书笔记第三十九 - 可视化效果之3D图形 说明:本系列基本上是<WPF揭秘>的读书笔记.在结构安排与文章内容上参照<WPF揭秘> ...

  3. NLP十大里程碑

    NLP十大里程碑 2.1 里程碑一:1985复杂特征集 复杂特征集(complex feature set)又叫做多重属性(multiple features)描写.语言学里,这种描写方法最早出现在语 ...

  4. Web 开发人员和设计师必读文章推荐【系列二十九】

    <Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  5. Gradle 1.12翻译——第十九章. Gradle 守护进程

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  6. 第三百五十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装

    第三百五十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装 elasticsearch(搜索引擎)介绍 ElasticSearch是一个基于 ...

  7. 无废话ExtJs 入门教程十九[API的使用]

    无废话ExtJs 入门教程十九[API的使用] extjs技术交流,欢迎加群(201926085) 首先解释什么是 API 来自百度百科的官方解释:API(Application Programmin ...

  8. Python之路【第十九章】:Django进阶

    Django路由规则 1.基于正则的URL 在templates目录下创建index.html.detail.html文件 <!DOCTYPE html> <html lang=&q ...

  9. Bootstrap <基础二十九>面板(Panels)

    Bootstrap 面板(Panels).面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .pa ...

随机推荐

  1. vue-router学习之二

    本文的学习来自技术胖大神的教程:https://jspang.com/ 这里的路由是指SPA(单页应用)的路径管理器.vue-router就是WebApp的链接路径管理系统. 为什么不能直接用< ...

  2. (四)注册登录--重用Django

    一.使用已有登录功能 (1)进入Lib\sitepackages\django\contrib\admin\templates\registration下,将对应模板,复制到项目template模板中 ...

  3. NSOperationQueue队列依赖相关思考

    添加依赖后,队列中网络请求任务有依赖关系时,任务结束判定以数据返回为准还是以发起请求为准? waitUntilFinished方法容易误解. 依赖关系 // // ViewController.m / ...

  4. 应急响应&&取证

    查看日志    eventvwr.exe   中了勒索病毒 1.查看download目录有没有病毒样本,C:\Users\86132\Downloads 2.查看系统开放端口 3.导出systemin ...

  5. ACWing 248. 窗内的星星|扫描线+懒惰标记

    传送门 题目描述 在一个天空中有很多星星(看作平面直角坐标系),已知每颗星星的坐标和亮度(都是整数). 求用宽为W.高为H的矩形窗户(W,H为正整数)能圈住的星星的亮度总和最大是多少.(矩形边界上的星 ...

  6. Markdown 复杂公式&常用符号

    公式格式 行内公式 行内公式(不会换行)使用 $ 作为起止符,例如:$a + b = c$, 效果为:\(a + b = c\) 块级公式 块级公式(单独一行)使用 $$ 作为起止符,例如:$$a + ...

  7. TensorFlow——Graph的基本操作

    1.创建图 在tensorflow中,一个程序默认是建立一个图的,除了系统自动建立图以外,我们还可以手动建立图,并做一些其他的操作. 下面我们使用tf.Graph函数建立图,使用tf.get_defa ...

  8. Android Gradle脚本从Groovy迁移到Kotlin DSL

    Android Gradle从Groovy迁移到Kotlin Android项目用Gradle构建, 其脚本语言之前是Groovy, 目前也提供了Kotlin的支持, 所以可以迁移到Kotlin. 官 ...

  9. Spring Boot 入门(十一):集成 WebSocket, 实时显示系统日志

    以前面的博客为基础,最近一篇为Spring Boot 入门(十):集成Redis哨兵模式,实现Mybatis二级缓存.本篇博客主要介绍了Spring Boot集成 Web Socket进行日志的推送, ...

  10. 枚举 + exgcd

    题意:已知xi=(a*xi-1+b) mod 10001,且告诉你x1,x3.........x2*t-1,让你求出其偶数列 思路分析 : 题目所要求的的是对 10001 取余,由模运算的性质可知,a ...