参考:bert-as-service 详细使用指南写给初学者-CSDN博客
下载:https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip
bert base chinese
首先讲了下学习bert-as-service的起因,因为实际业务中需要使用bert做线上化文本推理服务,所以经过调研选择bert-as-service开源项目;然后从理论的角度详解了bert-as-service,很纯粹的输入一条文本数据,返回对应的embedding表示。
参考:https://zhuanlan.zhihu.com/p/156941424
bert-as-service开源项目为我们提供线上的文本分类服务,所以一些基础的bert知识必不可少。
BERT这种预训练+微调两阶段模型和端到端模型的区别。
端到端模型就是使用任务相关的数据训练一个模型完成对应的任务。
而BERT这种两阶段模型属于迁移学习的范畴。
预训练阶段是通过无监督学习的方式学习海量的文本数据从而获得语言学知识;
而微调阶段则是利用预训练阶段学习到的语言学知识结合任务相关的数据去做不同的NLP任务。
预训练阶段因为要从海量的文本数据中学习语言学知识,所以需要大量的时间和计算资源。
虽然预训练阶段耗时耗资源,但是可以理解为一次性的。谷歌使用4-16个TPU花费4天才完成预训练模型。
计算机学习到了这些语言学知识后可以将这些"知识"以模型的方式存储起来,然后其他人可以直接使用这个模型结合各自的需求微调模型完成各自下游的任务。
- BERT模型
BERT模型由输入层embedding、编码层Transformer encoder和输出层三部分组成。
输入层将文本数据转化为词编码、句子对关系编码和位置编码三层embedding
编码层使用Transformer作为特征抽取器来获取文本语句的embedding表示
输出层则是根据下游的NLP任务来输出你想要的结果,可以是文本分类、命名体识别、翻译等等
主要是使用BERT模型来对用户搜索query和浏览资讯news等文本数据进行文本分类
离线文本分类服务
在线文本分类服务
bert-as-service简单来说就是通过Tensorflow和ZeroMQ来提供BERT线上化服务从而获取语句的embedding向量。
- 获得有效的embedding向量表示
Max Pooling(最大池化)和Average Pooling(平均池化)是卷积神经网络(CNN)中两种常用的下采样(subsampling)方法,它们都属于池化操作,用于减少输入数据的空间维度(如图像的高度和宽度),同时保留关键的特征信息。
-
Max Pooling:
- 在一个池化窗口(例如2x2)内,Max Pooling会选择该窗口内所有元素的最大值作为输出。这样做的好处是可以突出重要的局部特征,比如在识别物体时可能特别关注对象边缘或最显著的特征点。
- Max Pooling对于输入中的噪声具有一定的鲁棒性,因为它只传递每个区域的最大响应,从而对微小变化不敏感。
- 由于它选择的是最大激活值,因此能够捕获到强烈、独特的特征信号,有助于提高模型的泛化能力。
-
Average Pooling:
- Average Pooling则是计算池化窗口内所有元素的平均值作为输出。
- 相比于Max Pooling,Average Pooling更侧重于保留整个区域的统计特性,而不是仅仅关注最大响应。这使得它能提供更加平滑的输出特征图,可能更有利于表达图像的全局信息或者背景信息。
- 在某些场景下,Average Pooling可以降低由于个别极端值造成的偏差,并且其运算相对于Max Pooling更为稳定。
使用场景:
-
Max Pooling通常用在需要强调局部最大特征或者对噪声有较强抵抗力的场合,特别是在图像分类、目标检测等任务中被广泛采用。
-
Average Pooling则更多地应用于那些希望保持整体特征强度均衡的任务,或者当模型设计者想要避免过度重视单个最大响应时。例如,在DenseNet架构中,模块间的连接常采用Average Pooling来保持信息的有效传递。
此外,近年来还有其他形式的池化层出现,如Global Average Pooling,它在ResNet、Inception等现代网络结构的末尾经常被用来将整个特征图的尺寸压缩为一维向量,直接与全连接层进行对接,从而减少参数数量并增强模型的稳健性。
2W条资讯数据主要分成四类。整体来看,不同的pooling方式得到的embedding表示结果有一定差异。同时,查看各自的pooling方式下相邻层之间的embedding表示类似;第一层和最后一层的embedding表示差距很大;最后一层embedding的表示最接近词编码,能最好的保留初始的词语信息。
- 解耦bert模型和下游网络
Bert-as-service项目将bert预训练网络和下游网络解耦。将bert预训练网络放在配置GPU资源的服务端,同时服务多用户;下游网络一般是简单的轻量级模型,不需要复杂的深度学习库,放在CPU或者手机终端上使用。
通过解耦bert模型和下游网络,当特征提取成为瓶颈时可以通过使用或者增加GPU资源来优化服务端,同理当下游网络成为瓶颈时可以添加CPU或者量化操作来优化客户端。当训练数据没有更新或者定义发生变化时只需在服务端重新训练BERT模型即可满足下游网络获取更新后的特征向量。这种请求汇集在一个地方的方法可以使服务端的GPU利用率大大提高。
- 降低线上服务内存占用
Bert-as-service项目只需要在第一次收到新请求时生成一个新的BERT模型,后续只需要在事件循环中监听请求并提供服务即可。
- 高可用的服务方式
当服务端收到多个客户端的请求后,主要通过ventilator组件来进行批处理调度和负载均衡。当收到多个客户端请求后,ventilator首先会将这些请求划分成多个小任务,然后将这些小任务分别发送给工人们。工人们收到这些小任务后开始工作,工作内容就是使用bert进行预测,预测完之后会将结果统一发送给sink组件。sink组件会将所有工人的预测结果统一装配,同时检查ventilator组件中各个客户端请求的完整性,如果某个客户端请求的数据已经全部预测完成了,那么就返回预测结果给对应的客户端完成本次请求。通过这种方式,可以轻松解决上面小任务调度体验问题。
模型角度分析了不同的pooling策略对embedding向量的影响。通过解耦bert和下游网络、提供快速的预测服务、降低线上服务内存占用和高可用的服务方式,bert-as-service可以又快又好的提供线上推理服务。
实战bert-as-service
bert-serving-start -model_dir/tmp/english_L-12_H-768_A-12/ -num_worker=4
这里有两个参数需要说明下,一个是num_worker,这是分配的worker数目,一般分配的worker数目要少于GPU的颗数;另一个是model_dir,这是预训练模型的地址。
然后通过如下三行代码,我们就能轻松返回语句的embedding表示,简单到没朋友:
咱们就能使用BERT预训练模型得到文本的embedding表示向量。
- 获取文本分类的结果
上面已经得到BERT模型最重要的encodding编码向量。实际业务中我们是文本分类任务,其实就是添加了一层全连接层的一个微调的模型。通过如下命令即可实现bert-as-service项目用于文本分类任务:
对于文本分类任务,一个句子中的N个字符对应了E_1,...,E_N,这N个embedding。文本分类实际上是将BERT得到的T_1这一层连接上一个全连接层进行多分类。
https://kexue.fm/archives/6736
Tokenizer(分词器/符化器)是自然语言处理(NLP)领域中用于文本预处理的核心组件。它的主要功能是对输入的自然语言文本进行切分,将连续的字符流转换成一系列离散的单元或标记(tokens)。这些标记可以是单词、子词、字符或其他有意义的语言单位,具体取决于tokenizer的设计和应用需求。
在不同的NLP任务中,tokenizer的选择和配置至关重要,因为它直接影响到模型对输入数据的理解程度。例如:
- 单词级分词:将文本分割成单个单词作为token,适用于英语等空格分隔语言。
- 字符级分词:将文本中的每个字符都视为一个独立的token,对于处理拼写错误、新词发现等问题特别有用。
- 子词级分词(如BPE, WordPiece):结合了单词和字符的优点,通过学习数据集中的高频子序列来生成tokens,常用于深度学习模型以应对OOV(Out-Of-Vocabulary)问题。
在现代NLP库中,如Hugging Face Transformers库提供的BertTokenizer
等工具,不仅能够完成基本的分词工作,还能负责后续的转换步骤,如将tokens映射为唯一数字ID(词汇表索引)、添加特殊符号表示句子开始与结束等上下文信息,并支持对文本进行编码和解码操作,以便于神经网络模型的训练和推理。
在Keras中使用BERT进行文本分类是一个非常流行且效果通常较好的选择。BERT(Bidirectional Encoder Representations from Transformers)模型预训练了大规模的语料库,可以捕获文本中的深层次上下文信息,这使得它在多种NLP任务上,包括文本分类,都取得了非常好的性能。
Keras-BERT是基于Keras框架实现BERT模型的一个封装库,它可以简化在Keras环境中加载和微调BERT模型的过程。如果你的数据集不是特别大,并且有足够的计算资源(GPU),尤其是对于处理多类别文本分类问题时,Keras-BERT是一个不错的选择,因为它能够利用预训练好的语言模型来快速构建高质量的文本分类器。
然而,在实际应用中,选择哪个模型取决于多个因素:
- 数据量:小到中等规模数据集可能受益于BERT的预训练知识转移;但如果数据量极大,则可能需要考虑更轻量级或自定义的模型。
- 计算资源限制:BERT模型计算复杂度较高,对于硬件资源有限的情况,可能会考虑FastText、TextCNN、LSTM等较为轻量级的模型。
- 任务特定性:如果任务具有特定领域特性或者对速度有极高要求,可能需要针对特定场景定制模型或者寻找针对资源受限环境优化的预训练模型,如VAMPIRE或其他轻量级BERT变体(例如DistilBERT)。
- 模型复杂性与解释性需求:有时用户可能需要更容易解释的模型输出,而非最顶级的预测性能。
总之,Keras-BERT在许多情况下都是一个很好的起点,但务必根据具体项目需求权衡模型性能、计算成本以及可解释性等因素来做出最终决定。
当然,除了Keras-BERT之外,针对文本分类任务还有许多其他模型可以选择。以下是一些常见的深度学习模型:
-
卷积神经网络(CNN):例如TextCNN、Kim CNN等,利用卷积层提取局部特征,适用于捕捉文本中的n-gram特征。
-
循环神经网络(RNN)和长短时记忆网络(LSTM):通过处理序列数据来理解文本的上下文信息。可以尝试双向LSTM以获取前后文信息。
-
门控循环单元(GRU):作为RNN的一种变体,它在一定程度上简化了LSTM结构,但仍能较好地捕捉时间序列数据的长期依赖关系。
-
Transformer架构:
- BERT 的变种或优化版本:如DistilBERT、RoBERTa、ALBERT等,它们在保持一定性能的同时降低了计算复杂度。
- GPT系列:虽然GPT更多用于生成任务,但在某些情况下也可以进行微调以适应文本分类任务。
- XLNet 和 T5 等也属于Transformer家族,且在很多NLP任务中表现出色。
-
简单线性模型与集成方法:
- Logistic Regression配合TF-IDF或词嵌入表示可以实现基础但高效的文本分类器。
- 集成方法如随机森林(Random Forest)、梯度提升决策树(GBDT)结合文本特征也能获得不错的效果。
-
轻量级模型:
- FastText:Facebook提出的模型,其基于词袋模型和子词的信息构建,对计算资源需求相对较小。
每种模型都有其优势和适用场景,具体选择应根据项目的实际需求(如性能要求、资源限制、领域特性等)来进行权衡。
中文情感分类的过程,一般都是"分词------词向量------句向量(LSTM)------分类
参考:keras BERT
https://github.com/CyberZHG/keras-bert/blob/master/README.zh-CN.md
LSTM做情感分类:
双向编码器表示来自变换器(BERT,Bidirectional Encoder Representation from Transformers)
参考 【DSW Gallery】基于EasyNLP的BERT文本分类-阿里云开发者社区 (aliyun.com)
git clone https://github.com/alibaba/EasyNLP.git
python3 setup.py install
cd examples/appzoo_tutorials/sequence_classification/bert_classify
wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/classification/train.tsv
wget http://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/classification/dev.tsv
训练和测试数据都是以\t隔开的.tsv文件,数据下载完成后,可以通过以下代码查看前5条数据。
在本教程中,我们使用最基础的BERT模型:bert-base-uncased。EasyNLP中集成了丰富的预训练模型库,如果想尝试其他预训练模型,如bert-large、albert等,也可以在user_defined_parameters中进行相应修改,具体的模型名称可见模型列表。