天池nlp学习赛(6)基于机器学习的文本分类3 (Bert)

基于深度学习的文本分类3


介绍:这一节的主要内容是bert的使用。bert主要内容是预训练与微调,预训练可以得到词之间的关系,可以直接用于特征提取以及预测上下文,微调在预训练的基础上实现文本分类等功能,并对预训练中的参数进行微调。

主要内容:
(1)了解Transformer的原理和基于预训练语言模型(Bert)的词表示

(2)学会Bert的使用,具体包括pretrain和finetune(预训练与微调)

具体的原理和网络结构都在里面,但是讲的有点粗糙

论文原文

一个手把手教原理和实现的up主视频,超赞!!!!就是手把手教论文细节!和他的有详细注释的github代码以及知乎专栏

part1:文本表示方法4 — 编码器:Transformer

transformer block:

(1)自向量与位置编码
(2)自注意力机制
(3)残差连接(resnet)与layer normolization
(4)feed forward

具体看这里
最后讲这些block堆叠组合(一般12个layer)

(1)位置编码

借助sin cos用以表示文字之间的位置关系(因为bert里面没有像LSTM一样的前后迭代的过程)
这样对于一个词:

表示位置的编码+文字本身的嵌入编码=文字的初始embedding(或者理解为初始的特征也行?)

(2)自注意力机制

把embedding dimension平等分成h块
h是embedding dimension分成的份数
得到三个矩阵:Q,K,V维度:[batch size,h,sequence length,embedding dim/h ]

self_attention: Q ⋅ K T Q\cdot K^T QKT
K的转置只转置后面两维,这样做出来的内积能够表示出前后的距离关系(因为sequence length所在的维度表现了语句元的位置关系)

A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk QKT)V

d k \sqrt{d_k} dk 是为了使得注意力矩阵标准化

(3)残差连接
(4)feed forward

两层线性变换后用激活函数激活再传入(3)

part2:两种预训练的方式

(1)Masked LM (masked language model)

15%的内容(token)做掩码:
(1)80%几率换成[mask]
(2)10%几率换成其它的任意词
(3)10%几率不改变

用模型预测这些被掩盖的内容,计算这些内容的loss
X h i d d e n X_{hidden} Xhidden=[batch_size,seq_len,embedding_dim]
W v o c a b : W_{vocab}: Wvocab:[embedding_dim,vocab_size] (vocab_size是字典中所有词的个数)
X h i d d e n ⋅ W v o c a b X_{hidden}\cdot W_{vocab} XhiddenWvocab对vocab_size softmax

(2)Next Sentence Prediction

在原语句中加入以下部分:
每个句子的
开头[cls]:开始符
结尾[seq]:句子间间隔符

input中对每个词的嵌入(类似于词向量)有:

[tokem embedding]:每个字的嵌入
[segment embedding]:每句话的嵌入
[position embedding]:位置的嵌入

最后取 X h i d d e n X_{hidden} Xhidden中的[:,0,:]来代表每一个句子,得到结果cls_vector=[batch_size,embedding_dim]
输出分类依据: s i g m o i d ( L i n e a r ( c l s v e c t o r ) ) sigmoid(Linear(cls_vector)) sigmoid(Linear(clsvector))

part3:微调

啥是微调
微调的方法由具体采用的分类方法决定
例子

使用方法

对于模型的使用方面有以下情况:

(1)使用自己的数据集进行预训练(适用于专业性较强或数据集已经过编码的情况)
这时候参考下面模型训练的部分,需要自己做分词,构造词典,进行预训练

(2)调用官方的预训练模型,后面就只需要进行微调

(1)模型训练

有大佬封装好了keras模块下的bert

里面的内容包含:
(1)怎样分词
(2)bert模型训练
(3)构造特征

内容具体而全面,代码简洁易懂,在这里就不做复述了。

(2)微调

微调的过程可以理解为原来的预训练模型得到了词语的特征和关联,预训练结束后房子的大致形状已经确定了,现在在原来的房子里面加电线水管,通水电煤气进行测试,测试过程中除了装管道还需要对房子的一些部分做修改,这就是对测试集的X,Y进行拟合调整参数(之前的预训练只使用了X)。

官方预训练模型,其中包含多种大的小的,中文的英文的预训练模型,进去选择点集下载

官方例子也在里面

非官方例子,(基于keras),强烈安利
(1)文本分类
(2)关系抽取
(3)主体抽取

这里只说明一下其中的文本分类部分:

主要就是在预训练模型的基础上加入一个全连接层&sigmoid函数进行分类

 from keras_bert import load_trained_model_from_checkpoint
 #导入模型
 bert_model = load_trained_model_from_checkpoint(config_path, checkpoint_path, seq_len=None)

#让原来的模型可训练
for l in bert_model.layers:
    l.trainable = True
    
#设定输入格式,每个词的输入有两部分
#(第一部分是这个词的词向量,x1代表这一部分的维度;另一部分x2是segment_id代表句子的id,即这个词属于哪一个句子)
#上面两个维度使用Tokenizer中的encode函数能直接输出
#实际上还可以加上第三个维度来体现词在句子中的位置.

x1_in = Input(shape=(None,))
x2_in = Input(shape=(None,))

x = bert_model([x1_in, x2_in])
x = Lambda(lambda x: x[:, 0])(x) # 取出句子起始符[CLS]对应的向量用来做分类
p = Dense(1, activation='sigmoid')(x)

#x1_in是预训练输入的维度
#x2_in是
model = Model([x1_in, x2_in], p)
model.compile(
    loss='binary_crossentropy',#二分类的情况,多分类用交叉熵
    optimizer=Adam(1e-5), # 用足够小的学习率
    metrics=['accuracy']
)
model.summary()

ps:由于算力问题&不想再装包了就不写这个的demo了
对于大量数据加速计算可以使用TPU,现在在colab上可以氪金用辽。

另外对于bert网络上还有其它一些包可以借鉴(HuggingFace 里面有transformer封装好的包据说也很好用,大家可以试试)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值