B
E
R
T
(
B
i
d
i
r
e
c
t
i
o
n
a
l
E
n
c
o
d
e
r
R
e
p
r
e
s
e
n
t
a
t
i
o
n
s
f
r
o
m
T
r
a
n
s
f
o
r
m
e
r
s
)
BERT(BidirectionalEncoderRepresentations fromTransformers)
BERT(BidirectionalEncoderRepresentationsfromTransformers) 是
G
o
o
g
l
e
Google
Google 开发的一种
n
l
p
nlp
nlp 领域的预训练语言表示模型,
B
E
R
T
BERT
BERT在11项
N
L
P
NLP
NLP 任务中刷新了记录,
G
o
o
g
l
e
Google
Google 在11月份开源了
b
e
r
t
bert
bert 的代码,同时发布了多种语言版本的模型。
B
e
r
t
Bert
Bert 的出现彻底改变了预训练产生词向量和下游具体NLP任务的关系。针对
b
e
r
t
bert
bert 的概念,网上各种介绍,讲的我也有点脑壳儿痛,为了不误导各位看官,这里就麻烦各位自己去看看其他博客和论文了,我们这里主要浅显的讲解一下分类应用。
G
o
o
g
l
e
Google
Google 官方的
B
E
R
T
BERT
BERT 源码为
T
e
n
s
o
r
f
l
o
w
Tensorflow
Tensorflow 的,所以网上比较多的是使用
T
e
n
s
o
r
f
l
o
w
Tensorflow
Tensorflow 的应用,由于我并不是很懂
T
e
n
s
o
r
f
l
o
w
Tensorflow
Tensorflow,所以我这里使用
P
y
T
o
r
c
h
PyTorch
PyTorch 来处理这些。
官方推荐的 P y T o r c h PyTorch PyTorch 版本为 p y t o r c h _ p r e t r a i n e d _ b e r t pytorch\_pretrained\_bert pytorch_pretrained_bert,安装和使用可以参考官方文档。安装完成后,就可以开始我们的情感分析应用。
模型准备
B E R T BERT BERT 模型是将预训练模型和下游任务模型结合在一起的,也就是说在做下游任务时仍然是用 B E R T BERT BERT 模型,而且天然支持文本分类任务,在做文本分类任务时不需要对模型做修改。 G o o g l e Google Google 提供了下面七种预训练好的模型文件。:
B E R T BERT BERT 模型在英文数据集上提供了两种大小的模型, B a s e Base Base 和 L a r g e Large Large 。 u n c a s e d uncased uncased是意味着输入的词都会转变成小写, c a s e d cased cased 是意味着输入的词会保存其大写(在命名实体识别等项目上需要)。 M u l t i l i n g u a l Multilingual Multilingual 是支持多语言的,最后一个是中文预训练模型。
我们这里处理的是中文数据集,所以使用最后一个预处理模型 b e r t − b a s e − c h i n e s e bert-base-chinese bert−base−chinese,,预处理根据功能,又可分为分为几个子模型:
我们的应用为情感分类,所以使用 B e r t F o r S e q u e n c e C l a s s i f i c a t i o n BertForSequenceClassification BertForSequenceClassification 来训练。加载该模型:
bert_model = BertForSequenceClassification.from_pretrained(pretrained_model_name_or_path='bert-base-chinese', num_labels=2)
f r o m _ p r e t r a i n e d from\_pretrained from_pretrained 第一个参数为模型,可以跟本地的模型路径,也可以是模型名, n u m _ l a b e l s num\_labels num_labels 默认为 2,官方说可以不用写,但是我没加该参数编译报错,下面为两种模型加载方式,有兴趣的可以看看源码:
BertForSequenceClassification.from_pretrained(pretrained_model_name_or_path='bert-base-chinese', num_labels=2)
BertForSequenceClassification.from_pretrained(pretrained_model_name_or_path=path, num_labels=2)
根据源码,我们可以轻松的找到模型输入的数据格式:
其中输入的参数中:
i
n
p
u
t
_
i
d
s
input\_ids
input_ids: 在中文模式中就是每个分词的
i
d
id
id
a
t
t
e
n
t
i
o
n
_
m
a
s
k
attention\_mask
attention_mask : 句子中的字符对应1,补全的字符对应0
t
o
k
e
n
_
t
y
p
e
_
i
d
s
token\_type\_ids
token_type_ids: 句子标识符,第一句全为0,第二句全为1
l
a
b
e
l
s
labels
labels: 将
l
a
b
e
l
_
l
i
s
t
label\_list
label_list 转化为相应的
i
d
id
id 表示
输出:
输入参数中没有
l
a
b
e
l
s
labels
labels,则输出为预测
l
a
b
e
l
s
labels
labels, 输入中存在
l
a
b
e
l
s
labels
labels, 则输出为
l
o
s
s
loss
loss。
知道了模型输入的参数为什么样的数据,接下来就需要将我们的数据处理为需要的格式。
数据处理
数据还是使用深度学习(十一)-基于LSTM的情感分类 中小米8的评论,首先还是将评论使用词嵌入来向量化。
老规矩,词嵌入的第一步依然是分词,
B
E
R
T
BERT
BERT 发布的支持中文预训练模型为
b
e
r
t
−
b
a
s
e
−
c
h
i
n
e
s
e
bert-base-chinese
bert−base−chinese ,在该模型中,中文分词是基于字而非词的分词。
import torch
from pytorch_pretrained_bert import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese') # 分词器
text = "商品不错,京东让我很失望"
print(tokenizer.tokenize(text))
分词结果为:
B e r t Bert Bert 自带的有向量化的函数: c o n v e r t _ t o k e n s _ t o _ i d s convert\_tokens\_to\_ids convert_tokens_to_ids,根据源码,修改出我自己的数据处理函数,大家也可以使用源码中的函数:
def convert_examples_to_features(sentence, seq_length, tokenizer):
tokens_a = tokenizer.tokenize(sentence)
# Account for [CLS] and [SEP] with "- 2"
if len(tokens_a) > seq_length - 2:
tokens_a = tokens_a[0: (seq_length - 2)]
tokens = []
input_type_ids = []
tokens.append("[CLS]")
input_type_ids.append(0)
for token in tokens_a:
tokens.append(token)
input_type_ids.append(0)
tokens.append("[SEP]")
input_type_ids.append(0)
input_ids = tokenizer.convert_tokens_to_ids(tokens)
# The mask has 1 for real tokens and 0 for padding tokens. Only real
# tokens are attended to.
input_mask = [1] * len(input_ids)
# Zero-pad up to the sequence length.
while len(input_ids) < seq_length:
input_ids.append(0)
input_mask.append(0)
input_type_ids.append(0)
assert len(input_ids) == seq_length
assert len(input_mask) == seq_length
assert len(input_type_ids) == seq_length
return input_ids, input_mask, input_type_ids
其中输入参数为: s e n t e n c e sentence sentence 为输入中文语句, s e q l e n g t h seq_length seqlength 一句话的长度, t o k e n i z e r tokenizer tokenizer 分词方法。
优化/损失函数
- 优化
在 B e r t Bert Bert中,优化函数改为 B e r t A d a m BertAdam BertAdam:
optimizer = BertAdam(bert_model.parameters(), lr=1e-5)
- 损失
从源码中我们可以看出,损失函数在定义的模型中已经给我们写好了,所以我们完全可以不用管损失函。
模型训练
这里还是跟之前一样,不多讲,不懂的可以看看前面的博客或者在下面留言,看到必回。
for num, (input_ids, segment_ids, input_mask, label_ids) in enumerate(train_sampler):
input_ids = Variable(torch.Tensor(input_ids).long())
segment_ids = Variable(torch.Tensor(segment_ids).long())
input_mask = Variable(torch.Tensor(input_mask).long())
label_ids = Variable(torch.Tensor(label_ids).long())
bert_model.train()
optimizer.zero_grad()
loss = bert_model(input_ids, segment_ids, input_mask, label_ids)
loss.backward()
optimizer.step()
模型测试
测试依然参考之前博客,但是输入同模型训练一样为 [ n p u t _ i d s , s e g m e n t _ i d s , i n p u t _ m a s k ] [nput\_ids, segment\_ids, input\_mask] [nput_ids,segment_ids,input_mask],只是不需要 l a b e l s labels labels 即可。
总结
我这里只是浅显的讲解了 B e r t Bert Bert 的其中一个应用,并没有讲解原理等,感兴趣的朋友可以多浏览一下其他大神的解释,也可以尝试做做其他应用。应为才学习没多久,理解不深,如果哪位觉得有不对的地方,或者内容浅显,请嘴下留情。
本文介绍了如何使用PyTorch实现基于BERT的情感分析。通过加载预训练的bert-base-chinese模型,处理中文数据,利用BertForSequenceClassification进行训练和测试。数据处理涉及分词和向量化,优化器采用BertAdam,模型训练和测试过程简洁明了。

6322

被折叠的 条评论
为什么被折叠?



