使用BERT对句子进行向量化(TensorFlow版和Pytorch版)

7 篇文章 3 订阅

更多、更及时内容欢迎留意微信公众号小窗幽记机器学习

背景

用BERT对句子进行向量化

实施

TensorFlow版直接用肖涵博士的bert-as-service。使用方法真的很小白,简单概括为2点:server和client安装。

pip install bert-serving-server  # server
pip install bert-serving-client  # client, independent of `bert-serving-server`

在server安装完后,启动服务,比如:bert-serving-start -model_dir /home/pretained_models/chinese_wwm_ext_L-12_H-768_A-12 -num_worker=4
通过model_dir参数可以自行指定不同类型的BERT的模型路径,我这里使用的是哈工大发布的WWM-EXT版。在client上的测试代码:

def test_bert_tf(string):
    from bert_serving.client import BertClient
    bc = BertClient()
    s_encode = bc.encode([string])
    print(s_encode[0])

上述方案虽然简单易于上手,但是个人还是觉自己动手更香,比如基于huggingface的transformers。如何验证呢?就以bert-as-service编码得到的句向量作为标准值。将相同的文本输入到transformers试图得到与bert-as-service方案相同的句向量。

由于bert-as-service默认的句向量构造方案是取倒数第二层的隐状态值在token上的均值,即选用的层数是倒数第2层,池化策略是REDUCE_MEAN

import torch
import pdb
from transformers import AutoConfig
from transformers import BertTokenizer, BertModel, BertConfig

UNCASE = "/home/pretained_models/chinese_wwm_ext_pytorch"
VOCAB = "vocab.txt"
tokenizer = BertTokenizer.from_pretrained(UNCASE + "/" + VOCAB)

model = BertModel.from_pretrained(UNCASE, output_hidden_states = True) # 如果想要获取到各个隐层值需要如此设置
model.eval()
string = '写代码不香吗'
string1 = "[CLS]" + string + "[SEP]"

# Convert token to vocabulary indices
tokenized_string = tokenizer.tokenize(string1)
tokens_ids = tokenizer.convert_tokens_to_ids(tokenized_string)
# Convert inputs to PyTorch tensors
tokens_tensor = torch.tensor([tokens_ids])
outputs = model(tokens_tensor) # encoded_layers, pooled_output

if model.config.output_hidden_states:
    hidden_states = outputs[2]
    # last_layer = outputs[-1]
    second_to_last_layer = hidden_states[-2]
    # 由于只要一个句子,所以尺寸为[1, 10, 768]
    token_vecs = second_to_last_layer[0]
    print(token_vecs.shape)
    # Calculate the average of all input token vectors.
    sentence_embedding = torch.mean(token_vecs, dim=0)
    print(sentence_embedding.shape)
    print(sentence_embedding[0:10])

print("tf version-----")
from bert_serving.client import BertClient
bc = BertClient()
s_encode = bc.encode([string])
print(s_encode[0].shape)
# pdb.set_trace()
print(s_encode[0][0:10])

结果如下:
在这里插入图片描述
从向量的前10维可以看出,两者向量是相同的。那么进一步计算二者的余弦相似度的结果:

tf_tensor = torch.tensor(s_encode[0])
similarity = torch.cosine_similarity(sentence_embedding, tf_tensor, dim=0)
print(similarity)

余弦相似度为1,所以两个向量相同。

【更多、更及时内容欢迎留意微信公众号小窗幽记机器学习

  • 11
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 34
    评论
BERT-CRF模型是基于PyTorch实现的一种序列标注模型。它结合了BERT模型和CRF模型的优点,既能够学习上下文相关的表示,又能够进行序列标注任务。在使用过程中,首先需要进行预处理,将输入的文本按照一定规则进行分词,并将词转化为对应的索引。然后,使用BERT模型对输入序列进行特征提取,得到每个词的表示。接下来,将词的表示作为输入,结合CRF模型,进行序列标注任务的训练和预测。 在具体实现中,可以使用torchcrf库中提供的CRF类来定义CRF模型,并通过传入标签数目来初始化模型。在训练过程中,需要准备好输入的emissions(表示每个词的特征向量)、tags(表示每个词的真实标签)和mask(表示每个句子的有效长度),然后使用model函数计算得到当前句子的概率。通过调用decode函数可以得到模型对于当前句子的预测结果。 另外,在处理数据时,可以定义一个类,并实现__getitem__和__len__方法,以便于获取和处理数据集。__getitem__方法用于获取指定索引的样本数据,__len__方法用于获取数据集的大小。 总结来说,BERT-CRF模型是一种结合了BERT和CRF的序列标注模型,通过预处理、特征提取和CRF模型的训练预测等步骤来完成序列标注任务。在使用过程中,需要注意对数据进行适当的处理和准备。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Bert+LSTM+CRF命名实体识别pytorch代码详解](https://blog.csdn.net/qq_48034566/article/details/123794375)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值