1.情感分析语料预处理

  使用酒店评论语料,正面评论和负面评论各5000条,用BERT参数这么大的模型, 训练会产生严重过拟合,,泛化能力差的情况, 这也是我们下面需要解决的问题;

2.sigmoid二分类

  回顾在BERT的训练中Next Sentence Prediction中, 我们取出$[cls]$对应的那一条向量, 然后把他映射成1个数值并用$sigmoid$函数激活:
$$\hat{y} = sigmoid(Linear(cls\_vector)) \quad \hat{y} \in (0, \ 1)$$

3.动态学习率和提前终止$(early \ stop)$

  训练方式是,每个$epoch$,用训练集训练。对模型性能的衡量标准是$AUC$, $AUC$的衡量标准对二分类非常易用。当前$epoch$训练完毕之后, 用测试集衡量当前训练结果,并记下当前$epoch$的$AUC$, 如果当前的$AUC$较上一个$epoch$没有提升,那就降低学习率,实际操作是让当前的学习率降低$1/5$, 直到$10$个$epoch$测试集的$AUC$都没有提升, 就终止训练。
  初始学习率是$1e-6$, 因为我们是在维基百科预训练语料的基础上进行训练的, 属于下游任务,只需要微调预训练模型就好。

4.解决过拟合问题

  但在实际操作中, 使用$\hat{y} = sigmoid(Linear(cls\_vector)) \quad \hat{y} \in (0, \ 1)$的方式, 发现虽然在训练集和测试集上$AUC$都很高, 但实际随便输入一些从各种网上随便找的一些酒店评论后, 发现泛化能力不好. 这是因为训练数据集非常小,即使区分训练集和测试集,但因为整体数据形态比较单一,模型遇到自己没见过的情况就很容易无法做出正确判断,为了提高模型的泛化性能,尝试了另一种模型结构:

(1)mean-max-pool

一种把隐藏层的序列转换为一条向量的方式,其实就是沿着sequence length 的维度分别求均值和max,之后拼起来成为一条向量,之后同样映射成一个值再激活。

$X_{hidden}: [batch\_size, \ seq\_len, \ embedding\_dim]$
$mean\_pooled = mean(X_{hidden}, \ dimension=seq\_len) \quad [batch\_size, \ embedding\_dim]$
$max\_pooled = max(X_{hidden}, \ dimension=seq\_len) \quad [batch\_size, \ embedding\_dim]$
$mean\_max\_pooled = concatenate(mean\_pooled, \ max\_pooled, \ dimension=embedding\_dim ) \quad [batch\_size, \ embedding\_dim * 2]$

  上式中mean_max_pooled 也就是我们得到的一句话的数学表达,含有这句话的信息, 其实这也是一种DOC2VEC的方法, 也就是把一句话转换成一条向量,而且无论这句话有多长,转换出来向量的维度都是一样的,之后可以用这些向量做一些分类聚类等任务。

下一步我们同样做映射, 之后用$sigmoid$激活:
$\hat{y} = sigmoid(Linear(mean\_max\_pooled)) \quad \hat{y} \in (0, \ 1)$
怎样理解这样的操作呢, 隐藏层就是一句话的数学表达, 我们求均值和最大值正数学表达对这句话的平均响应, 和最大响应, 之后我们用线性映射来识别这些响应, 从而得到模型的推断结果。

(2)weight decay权重衰减

  其实就是L2 normalization,在PyTorch里有接口可以直接调用, 其实$L2$正则的作用就是防止参数的值变得过大或过小,我们可以设想一下,由于我们的训练数据很少,所以实际使用模型进行推断的时候有些字和词或者句子结构的组合模型都是没见过的, 模型里面参数的值很大的话会造成遇到某一些特别的句子或者词语的时候, 模型对句子的响应过大, 导致最终输出的值偏离实际, 其实我们希望模型更从容淡定一些, 所以我们加入$L2 \ normalization$.

  除此之外, 我们预训练的BERT有6个transformer block, 我们在情感分析的时候,只用了3个,因为后面实在是参数太多,容易导致过拟合,所以在第三个transformer block之后,就截出隐藏层进行$pooling$了,后面的transformer block都没有用到。

(3)dropout

$dropout$设为了$0.4$,因为模型参数是在是太多,所以在训练的时候直接让$40\%$的参数失能,防止过拟合。

  经过以上方法, 模型训练集和测试机的$AUC$都达到了$0.95$以上, 而且经过实际的测试, 模型也可以基本比较正确的分辨出语句的情感极性.

5.阈值微调

  经过模型的推断, 输出的值介于0到1之间, 我们可以认为只要这个值在0.5以上, 就是正样本, 如果在0.5以下, 就是副样本, 其实这是不一定的, 0.5通常不是最佳的分类边界, 所以我写了一个用来寻找最佳阈值的脚本, 在./metrics/\_\_init\_\_.py里面.
  这个脚本的方法是从0.01到0.99定义99个阈值, 高于阈值算正样本, 低于算副样本, 然后与测试集计算$f1 \ score$, 之后选出可以使$f1 \ score$最高的阈值, 在训练中, 每一个$epoch$都会运行一次寻找阈值的脚本.

参考文献:

【1】BERT实战(源码分析+踩坑) - 知乎

【2】ymcui / Chinese-PreTrained-XLNet:预培训的中文XLNet(中文XLNet预训练模型)

【3】汉语自然语言处理-BERT的解读语言模型预训练-实践应用-transformer模型(二)-语料预处理-情感分析分类-数据增强-解决过拟合问题-深度学习训练技巧_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

【4】Self-Attention & Transformer - w55100的博客 - CSDN博客

【5】使用google的Bert获得中文的词向量 - u014553172的博客 - CSDN博客

【6】aespresso/a_journey_into_math_of_ml: 汉语自然语言处理视频教程-开源学习资料

Bert实战---情感分类的更多相关文章

  1. 使用BERT进行情感分类预测及代码实例

    文章目录 0. BERT介绍 1. BERT配置 1.1. clone BERT 代码 1.2. 数据处理 1.2.1预训练模型 1.2.2数据集 训练集 测试集 开发集 2. 修改代码 2.1 加入 ...

  2. 使用bert进行情感分类

    2018年google推出了bert模型,这个模型的性能要远超于以前所使用的模型,总的来说就是很牛.但是训练bert模型是异常昂贵的,对于一般人来说并不需要自己单独训练bert,只需要加载预训练模型, ...

  3. 基于Bert的文本情感分类

    详细代码已上传到github: click me Abstract:    Sentiment classification is the process of analyzing and reaso ...

  4. 在Keras中用Bert进行情感分析

    之前在BERT实战——基于Keras一文中介绍了两个库 keras_bert 和 bert4keras 但是由于 bert4keras 处于开发阶段,有些函数名称和位置等等发生了变化,那篇文章只用了 ...

  5. 关于情感分类(Sentiment Classification)的文献整理

    最近对NLP中情感分类子方向的研究有些兴趣,在此整理下个人阅读的笔记(持续更新中): 1. Thumbs up? Sentiment classification using machine lear ...

  6. kaggle——Bag of Words Meets Bags of Popcorn(IMDB电影评论情感分类实践)

    kaggle链接:https://www.kaggle.com/c/word2vec-nlp-tutorial/overview 简介:给出 50,000 IMDB movie reviews,进行0 ...

  7. NLP文本情感分类传统模型+深度学习(demo)

    文本情感分类: 文本情感分类(一):传统模型 摘自:http://spaces.ac.cn/index.php/archives/3360/ 测试句子:工信处女干事每月经过下属科室都要亲口交代24口交 ...

  8. kaggle之电影评论文本情感分类

    电影文本情感分类 Github地址 Kaggle地址 这个任务主要是对电影评论文本进行情感分类,主要分为正面评论和负面评论,所以是一个二分类问题,二分类模型我们可以选取一些常见的模型比如贝叶斯.逻辑回 ...

  9. PaddlePaddle︱开发文档中学习情感分类(CNN、LSTM、双向LSTM)、语义角色标注

    PaddlePaddle出教程啦,教程一部分写的很详细,值得学习. 一期涉及新手入门.识别数字.图像分类.词向量.情感分析.语义角色标注.机器翻译.个性化推荐. 二期会有更多的图像内容. 随便,帮国产 ...

随机推荐

  1. TestNG参数化测试之Excel读取数据

    1.新建Excel文档,准备好测试数据 在当前工程的resources目录下,新建文件名为testdata的Excel文档 打开Excel,将当前sheet重命名为calculator,构造num1. ...

  2. 【西北师大-2108Java】第三次作业成绩汇总

    [西北师大-2108Java]第三次作业成绩汇总 熟悉PTA平台线上测试环境: 理解用户自定义类的定义: 掌握对象的声明: 学会使用构造函数初始化对象: 使用类属性与方法的使用掌握使用: 掌握pack ...

  3. 详解C++ STL multiset 容器

    详解C++ STL multiset 容器 本篇随笔简单介绍一下\(C++STL\)中\(multiset\)容器的使用方法及常见使用技巧. multiset容器的概念和性质 \(set\)在英文中的 ...

  4. Jike_Time-决策树

    根节点 非叶子节点(决策点) 叶子节点(决策结果) 分支 熵代表混乱程度 信息增益 构造树的基本想法是随着树深度的增加.节点的熵迅速地降低.熵降低的速度越快越好,这样我们有望得到一颗高度最矮的决策树 ...

  5. 微信小程序云开发-从0打造云音乐全栈小程序

    第1章 首门小程序“云开发”课程,你值得学习本章主要介绍什么是小程序云开发以及学习云开发的重要性,并介绍项目的整体架构,真机演示项目功能,详细介绍整体课程安排.课程适用人群以及需要掌握的前置知识.通过 ...

  6. go 通过select实现超时

    package main import ( "fmt" "time" ) func main() { ch := make(chan int) quit := ...

  7. 9.29 csp-s模拟测试55 联+赛+题

    T1 联 $n$最大到$1e18$,根本没法做,但$m$只有$1e5$,发现有很多区间是一起动的,或者根本没动,所以可以把区间离散化掉,然后线段树区间修改,对于第三种修改,只需要把它分解成一段一段相同 ...

  8. webrtc笔记(4): kurento 部署

    kurento是一个开源的webrtc mcu服务器,按官方的文档,建议在ubtntu上安装,过程如下: 注:建议先切换到root身份,如果不是root身份登录的,下列命令,请自行加上sudo . 另 ...

  9. 项目倒入maven 遇到的问题只有 main 了

    归根结底是倒入错了: (1)首先  view->Toolbar; (2) 点击 File==>project structure 然后:在 project settings中点击 modu ...

  10. Windows Azure Virtual Machine (39) 清除Linux挖矿病毒

    <Windows Azure Platform 系列文章目录> 1.之前客户遇到了Azure Linux CPU 100%,症状如下: 2.SSH登录到Linux,查看crontab,有从 ...