当前位置: 首页 > news >正文

文本向量化

文本向量化表示的输出比较

import timeimport torch
from transformers import AutoTokenizer, AutoModelForMaskedLM, AutoModel# simcse相似度分数
def get_model_output(model, tokenizer, text_str):"""验证文本向量化表示的输出:param model:       模型的名称:param tokenizer:   tokenizer:param text_str:    文本内容 可以只一个str, 也可以是一个str_list:return:            返回该文本向量表示形式"""# 返回的类似一个字典类型# padding 表示填充max_len  CLS + text + [SEP] return_tensors="pt" 返回pytorch类型的张量# 如果不加这个return_tensors="pt"参数 input_ids等key的value就不是tensor而是listinputs_text = tokenizer(text_str, return_tensors="pt",  padding=True)print_inputs_source(**inputs_text)with torch.no_grad():outputs_source = model(**inputs_text)last_hidden_states = outputs_source.last_hidden_state                   # shape (b_s, max_len, 768)# 一般我们会使用的三个模型输出 建议使用 pooling_outputlast_cls_embedding = outputs_source.last_hidden_state[:, 0, :]          # shape (b_s, 768) 每个文本的CLS 表示 这个是固定的last_hidden_states_mean = outputs_source.last_hidden_state.mean(dim=1)  # shape (b_s, 768) 这个表示会有问题 对(b_s, max_len, 768) 进行平均池化得到的pooling_output = outputs_source.pooler_output                           # shape (b_s, 768) 每个文本的CLS之后在进入一次池化(全连接层)得到pool_output   这个表示也是固定的last_hidden_states_pooling = model.pooler(last_hidden_states)print("last_hidden_states shape {}".format(last_hidden_states.shape))print("last_CLS_embedding shape {}".format(last_cls_embedding.shape))print("last_hidden_states_pool shape {}".format(last_hidden_states_pooling.shape))print("last_hidden_states_mean shape {}".format(last_hidden_states_mean.shape))print("pool_output shape {}".format(pooling_output.shape))print("equal last_pool and pool_output: {}".format(torch.equal(pooling_output, last_hidden_states_pooling)))print("last_hidden_states embedding {}".format(last_hidden_states))print("last_hidden_states mead {}".format(last_hidden_states_mean))print("last_cls_embedding embedding {}".format(last_cls_embedding))print("pool_output {}".format(pooling_output))def print_inputs_source(input_ids, token_type_ids, attention_mask):"""打印模型tokenizer之后的内容:param input_ids::param token_type_ids::param attention_mask::return:"""print("input_ids: {}".format(input_ids))print("token_type_ids: {}".format(token_type_ids))print("attention_mask: {}".format(attention_mask))if __name__ == '__main__':"""字典的拆包"""# "D:\program\pretrained_model\ESimCSE-ext-chinese-bert-wwm""""Erlangshen-SimCSE-110M-ChineseESimCSE-ext-chinese-bert-wwm        这里的tokenier_config文件用的是sup-simcse的sup-simcse-bert-base-uncased"bert-base-uncased""""start_run_time = time.time()prefix_path = "D:/program/pretrained_model/"        # 本地路径前缀model_path = prefix_path + "bert-base-uncased"model = AutoModel.from_pretrained(model_path)tokenizer = AutoTokenizer.from_pretrained(model_path)text_str = "中国"text_list = ["中国", "今天是个好日子"]get_model_output(model, tokenizer, text_list)

1. CLS表示整个文本

outputs_source.hidden_states[-1][:, 0, :]这行代码是用来从模型的输出中提取最后一层的所有单词的第一个位置(通常是 [CLS] 标记)的隐藏状态。

1.1 关键代码:

        outputs_source = model(**inputs_text) last_hidden_states = outputs_source.last_hidden_state                   # shape (b_s, max_len, 768)
pooling_outputsentence_embedding = outputs_source.last_hidden_state[:, 0, :]          # shape (b_s, 768) 每个文本的CLS 表示 这个是固定的

这里首先得到模型的最后一层隐藏状态的输出last_hidden_state,shape (b_s, max_len, 768)
然后选出CLS这个token的表示将其作为整个句子的表示

1.2 整体代码

import timeimport torch
from transformers import AutoTokenizer, AutoModelForMaskedLM, AutoModel# simcse相似度分数
def get_model_output(model, tokenizer, text_str):"""验证文本向量化表示的输出:param model:       模型的名称:param tokenizer:   tokenizer:param text_str:    文本内容 可以只一个str, 也可以是一个str_list:return:            返回该文本向量表示形式"""# 返回的类似一个字典类型# padding 表示填充max_len  CLS + text + [SEP] return_tensors="pt" 返回pytorch类型的张量inputs_text = tokenizer(text_str, return_tensors="pt",  padding=True)# print_inputs_source(**inputs_text)with torch.no_grad():outputs_source = model(**inputs_text)last_hidden_states = outputs_source.last_hidden_state                   # shape (b_s, max_len, 768)# 一般我们会使用的三个模型输出 建议使用 pooling_outputsentence_embedding = outputs_source.last_hidden_state[:, 0, :]          # shape (b_s, 768) 每个文本的CLS 表示 这个是固定的print("last_hidden_state shape: {}".format(last_hidden_states.shape))print("cls_embedding shape: {}".format(sentence_embedding.shape))print("last_cls_embedding: {}".format(sentence_embedding))return sentence_embeddingdef print_inputs_source(input_ids, token_type_ids, attention_mask):"""打印模型tokenizer之后的内容  CLS + text + SEP:param input_ids::param token_type_ids::param attention_mask::return:"""print("input_ids: {}".format(input_ids))print("token_type_ids: {}".format(token_type_ids))print("attention_mask: {}".format(attention_mask))if __name__ == '__main__':start_run_time = time.time()prefix_path = "D:/program/pretrained_model/"        # 本地路径前缀model_path = prefix_path + "bert-base-uncased"model = AutoModel.from_pretrained(model_path)tokenizer = AutoTokenizer.from_pretrained(model_path)text_str = "中国"text_list = ["中国", "今天是个好日子"]get_model_output(model, tokenizer, text_str)end_run_time = time.time()used_time = end_run_time-start_run_timeprint("消耗时间为: {}秒".format(used_time))

输出结果: 中国 的文本表示如下
在这里插入图片描述

2. pooler_output表示整个文本

outputs_source.pooler_output 表示从模型的输出中提取的池化器输出(pooler output)。

在BERT模型中,经过最后一层的所有隐藏状态被经过一些池化操作,得到一个被称为"pooler output"的表示。这个表示通常被用于下游任务的输入,因为它是整个句子/序列的一个紧凑的表示。

所以,outputs_source.pooler_output 就是源文本(或输入文本)通过池化器得到的表示。

2.1 关键代码

        outputs_source = model(**inputs_text)sentence_embedding = outputs_source.pooler_output                   # shape (b_s, max_len, 768)

这里相当于是把最后一层隐藏状态通过一个全连接层然后在进行输出表示整个句子

2.2 整体代码

import timeimport torch
from transformers import AutoTokenizer, AutoModelForMaskedLM, AutoModel# simcse相似度分数
def get_model_output(model, tokenizer, text_str):"""验证文本向量化表示的输出:param model:       模型的名称:param tokenizer:   tokenizer:param text_str:    文本内容 可以只一个str, 也可以是一个str_list:return:            返回该文本向量表示形式"""# 返回的类似一个字典类型# padding 表示填充max_len  CLS + text + [SEP] return_tensors="pt" 返回pytorch类型的张量inputs_text = tokenizer(text_str, return_tensors="pt",  padding=True)# print_inputs_source(**inputs_text)with torch.no_grad():outputs_source = model(**inputs_text)sentence_embedding = outputs_source.pooler_output                   # shape (b_s, max_len, 768)# 一般我们会使用的三个模型输出 建议使用 pooling_output# sentence_embedding = outputs_source.last_hidden_state[:, 0, :]          # shape (b_s, 768) 每个文本的CLS 表示 这个是固定的print("pooling_embedding shape: {}".format(sentence_embedding.shape))print("pooling_embedding: {}".format(sentence_embedding))return sentence_embeddingdef print_inputs_source(input_ids, token_type_ids, attention_mask):"""打印模型tokenizer之后的内容  CLS + text + SEP:param input_ids::param token_type_ids::param attention_mask::return:"""print("input_ids: {}".format(input_ids))print("token_type_ids: {}".format(token_type_ids))print("attention_mask: {}".format(attention_mask))if __name__ == '__main__':start_run_time = time.time()prefix_path = "D:/program/pretrained_model/"        # 本地路径前缀model_path = prefix_path + "bert-base-uncased"model = AutoModel.from_pretrained(model_path)tokenizer = AutoTokenizer.from_pretrained(model_path)text_str = "中国"text_list = ["中国", "今天是个好日子"]get_model_output(model, tokenizer, text_str)end_run_time = time.time()used_time = end_run_time-start_run_timeprint("消耗时间为: {}秒".format(used_time))

输出结果: 中国 的文本表示如下
在这里插入图片描述

3. 利用最后隐藏状态的mean进行表示

3.1 关键代码

        outputs_source = model(**inputs_text)sentence_embedding = outputs_source.last_hidden_state.mean(dim=1)         # shape (b_s, max_len, 768)

这里是利用last_hidden_state的mean进行表示 但这个表示如果利用批量文本向量化的时候可能会出现问题,因为mean的时候会考虑padding, cls_embedding, 和pool_embedding就不会出现这种情况

3.2 整体代码

import timeimport torch
from transformers import AutoTokenizer, AutoModelForMaskedLM, AutoModel# simcse相似度分数
def get_model_output(model, tokenizer, text_str):"""验证文本向量化表示的输出:param model:       模型的名称:param tokenizer:   tokenizer:param text_str:    文本内容 可以只一个str, 也可以是一个str_list:return:            返回该文本向量表示形式"""# 返回的类似一个字典类型# padding 表示填充max_len  CLS + text + [SEP] return_tensors="pt" 返回pytorch类型的张量inputs_text = tokenizer(text_str, return_tensors="pt",  padding=True)# print_inputs_source(**inputs_text)with torch.no_grad():outputs_source = model(**inputs_text)sentence_embedding = outputs_source.last_hidden_state.mean(dim=1)         # shape (b_s, max_len, 768)# 一般我们会使用的三个模型输出 建议使用 pooling_output# sentence_embedding = outputs_source.last_hidden_state[:, 0, :]          # shape (b_s, 768) 每个文本的CLS 表示 这个是固定的print("last_mean_embedding shape: {}".format(sentence_embedding.shape))print("last_mean_embedding: {}".format(sentence_embedding))return sentence_embeddingdef print_inputs_source(input_ids, token_type_ids, attention_mask):"""打印模型tokenizer之后的内容  CLS + text + SEP:param input_ids::param token_type_ids::param attention_mask::return:"""print("input_ids: {}".format(input_ids))print("token_type_ids: {}".format(token_type_ids))print("attention_mask: {}".format(attention_mask))if __name__ == '__main__':start_run_time = time.time()prefix_path = "D:/program/pretrained_model/"        # 本地路径前缀model_path = prefix_path + "bert-base-uncased"model = AutoModel.from_pretrained(model_path)tokenizer = AutoTokenizer.from_pretrained(model_path)text_str = "中国"text_list = ["中国", "今天是个好日子"]get_model_output(model, tokenizer, text_str)end_run_time = time.time()used_time = end_run_time-start_run_timeprint("消耗时间为: {}秒".format(used_time))

输出结果: 中国 的文本表示如下
在这里插入图片描述

输出结果: 如果输入文本为text_list(批量向量化)那么输出结果如下
在这里插入图片描述

这里可以发现中国的文本表示变化了 说明padding填充影响了mean的结果
所以这种方法慎重使用

4. 总结:

4.1 三种表示方法

        model(**inputs_text).last_hidden_state.mean(dim=1)model(**inputs_text).last_hidden_state[:, 0, :]model(**inputs_text).pooler_output

4.2 last_hidden_state 和 pooler_output的区别以及转化

参考博客: https://blog.csdn.net/ningyanggege/article/details/132206331

last_hidden_states = model(**inputs_text).last_hidden_state 
model.pooler(last_hidden_state) == model(**inputs_text).pooler_output
import timeimport torch
from transformers import AutoTokenizer, AutoModelForMaskedLM, AutoModel# simcse相似度分数
def get_model_output(model, tokenizer, text_str):"""验证文本向量化表示的输出:param model:       模型的名称:param tokenizer:   tokenizer:param text_str:    文本内容 可以只一个str, 也可以是一个str_list:return:            返回该文本向量表示形式"""# 返回的类似一个字典类型# padding 表示填充max_len  CLS + text + [SEP] return_tensors="pt" 返回pytorch类型的张量inputs_text = tokenizer(text_str, return_tensors="pt",  padding=True)# print_inputs_source(**inputs_text)with torch.no_grad():outputs_source = model(**inputs_text)pooling_embedding = outputs_source.pooler_output                   # shape (b_s, max_len, 768)last_pool_embedding = model.pooler(outputs_source.last_hidden_state)# 一般我们会使用的三个模型输出 建议使用 pooling_output# sentence_embedding = outputs_source.last_hidden_state[:, 0, :]          # shape (b_s, 768) 每个文本的CLS 表示 这个是固定的print("valid equals {}".format(torch.equal(pooling_embedding, last_pool_embedding)))return pooling_embeddingif __name__ == '__main__':start_run_time = time.time()prefix_path = "D:/program/pretrained_model/"        # 本地路径前缀model_path = prefix_path + "bert-base-uncased"model = AutoModel.from_pretrained(model_path)tokenizer = AutoTokenizer.from_pretrained(model_path)text_str = "中国"text_list = ["中国", "今天是个好日子"]get_model_output(model, tokenizer, text_str)end_run_time = time.time()used_time = end_run_time-start_run_timeprint("消耗时间为: {:.2f}秒".format(used_time))

水平有限 如有问题欢迎指正交流
参考博客: https://blog.csdn.net/ningyanggege/article/details/132206331

http://www.lryc.cn/news/235650.html

相关文章:

  • java--贪吃蛇
  • 录制第一个jmeter性能测试脚本2(http协议)
  • pip命令大全
  • Redis篇---第二篇
  • 【LeetCode刷题日志】232.用栈实现队列
  • 单元测试实战(二)Service 的测试
  • LabVIEW和NIUSRP硬件加快了认知无线电开发
  • 嵌入式软件工程师面试题——2025校招社招通用(十六)
  • 白盒测试之测试用例设计方法
  • 在CentOS 7上关闭SELinux
  • 基于单片机温湿度PM2.5报警系统
  • OpenHarmony系统编译环境
  • 二十三种设计模式全面解析-职责链模式(Chain of Responsibility Pattern):解放代码责任链,提升灵活性与可维护性
  • 通过制作llama_cpp的docker镜像在内网离线部署运行大模型
  • JavaScript 异步编程
  • linux课程第一课------命令的简单的介绍
  • XLua热更新框架原理和代码实战
  • Hive客户端hive与beeline的区别
  • <MySQL> 什么是数据库索引?数据库索引的底层结构是什么?
  • 对于koa中间件的理解
  • 分页文件pagefile.sys引出的疑问
  • 【开题报告】疫苗在线预约小程序的设计与实现
  • 【深度学习实验】注意力机制(二):掩码Softmax 操作
  • idea运行项目之后一直卡在Writing classes… 解决方案
  • CentOS7 安装mysql8(离线安装)postgresql14(在线安装)
  • 使用vant list实现订单列表,支持下拉加载更多
  • OpenCV快速入门:图像形态学操作
  • Scrapy----Scrapy简介
  • 基环树(pseudotree)入门
  • nrm的安装以及使用