对Bert的理解

最近看了机器之心的对bert源码的解读,做如下笔记:

句子情感分类

首先是整个流程,主要分为两部分:

  • 对句子进行处理,我理解的类似于embedding,类似于Word2Vec。
  • 外接模型,后续可以加Logistics模型,LSTM模型等。

首先对模型进行词嵌入:
在这里插入图片描述
之后用Scikit Learn库进行训练集、测试集的划分
这个过程会把样本的顺序打乱,而不是按照原来的顺序对样本进行划分

每个预测值是怎么计算出来的?

假设我们有句子[ a visually stunning rumination on love ] ,要对这个句子进行情感分类,第一步就是用BERT分词器tokenizer将单词word分成词token(这里好像对中文而言?),然后在开始和结束加入**[CLS]** 和 [SEP]
在这里插入图片描述
这个过程只需要一行代码就能完成

tokenizer.encode("a visually stunning rumination on love", add_special_tokens=True)

??? 那么这个tokenizer是哪里来的呢?这个我们下面再说

然后我们得到的数据就可以传给BERT了
在这里插入图片描述
最后整个模型可以想象成这个过程:
在这里插入图片描述

下面讨论代码的实现:
import numpy as np
import pandas as pd
import torch
import transformers as ppb # pytorch transformers
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split

1.导入数据
数据集的链接如下:https://github.com/clairett/pytorch-sentiment-classification/。我们可以直接将其导入为一个 pandas 数据帧。

df = pd.read_csv('https://github.com/clairett/pytorch-sentiment-classification/raw/master/data/SST2/train.tsv', delimiter='\t', header=None)

我们看一下数据的格式

在这里插入图片描述
我们在看一下数据的分布:
在这里插入图片描述
2. 加载pre_trained BERT model

# For DistilBERT:
model_class, tokenizer_class, pretrained_weights = (ppb.DistilBertModel, ppb.DistilBertTokenizer, 'distilbert-base-uncased')

## Want BERT instead of distilBERT? Uncomment the following line:
#model_class, tokenizer_class, pretrained_weights = (ppb.BertModel, ppb.BertTokenizer, 'bert-base-uncased')

# Load pretrained model/tokenizer
tokenizer = tokenizer_class.from_pretrained(pretrained_weights)
model = model_class.from_pretrained(pretrained_weights)

从这里我们可以看出: tokenizer是直接从tokenizer_class 中拿出来的,而tokenizer_class 是transformers的一个工具类,model也是transformers中的工具类。
在colab中由于算力的限制,我们只取了前2000个样本。即batch_1

下面重点
  1. Tokenization
    把句子分成BERT的输入格式——token、CLS、SEP,(还有个mask机制,这里需要再详细了解一下)
    tokenized = batch[0]_1.apply((lambda x: tokenizer.encode(x, add_special_tokens=True) 
    
    在这里插入图片描述
  2. Padding
    在这里插入图片描述
    分词后,我们有了一个list格式的数据,但是长短不一,我们需要对数据进行一下padding,把不够的补0.
    具体代码:
max_len = 0
for i in tokenized.values:
    if len(i) > max_len:
        max_len = len(i)

padded = np.array([i + [0]*(max_len-len(i)) for i in tokenized.values])

在这里插入图片描述
3. Mask
还需要对数据进行一个Mask操作,因为否则的话会对模型造成一定的混淆,具体操作就是新建一个矩阵attention_mask,值为0或1,在padded值不为的地方为1,为0的地方为0;

attention_mask = np.where(padded != 0, 1, 0)
attention_mask.shape
Mode#1

现在我们有的padded矩阵,就是对原始的token矩阵进行补齐,还有attention_mask矩阵。,把他们转换成torch.tensor的形式。

input_ids = torch.tensor(padded)  
attention_mask = torch.tensor(attention_mask)

直接输入给model,获得经过BERT之后的矩阵!!

with torch.no_grad():
last_hidden_states = model(input_ids, attention_mask=attention_mask)

结果如图:
在这里插入图片描述
提取第0个position的数据

features = last_hidden_states[0][:,0,:].numpy()
labels = batch_1[1]
Model#2 Train/Test Split
train_features, test_features, train_labels, test_labels = train_test_split(features, labels)
lr_clf = LogisticRegression()
lr_clf.fit(train_features, train_labels)
lr_clf.score(test_features, test_labels)

最后得分0.856

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值