深度学习(十二)-基于 Bert 的情感分析

本文介绍了如何使用PyTorch实现基于BERT的情感分析。通过加载预训练的bert-base-chinese模型,处理中文数据,利用BertForSequenceClassification进行训练和测试。数据处理涉及分词和向量化,优化器采用BertAdam,模型训练和测试过程简洁明了。

   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) BERTBidirectionalEncoderRepresentationsfromTransformers 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 bertbasechinese,,预处理根据功能,又可分为分为几个子模型:

  我们的应用为情感分类,所以使用 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 bertbasechinese ,在该模型中,中文分词是基于字而非词的分词。

	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 的其中一个应用,并没有讲解原理等,感兴趣的朋友可以多浏览一下其他大神的解释,也可以尝试做做其他应用。应为才学习没多久,理解不深,如果哪位觉得有不对的地方,或者内容浅显,请嘴下留情。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值