文本向量化

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

import time

import 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而是list
    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_output
        last_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-Chinese
    ESimCSE-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_output
        sentence_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 time

import 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_output
        sentence_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_embedding


def 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_time
    print("消耗时间为: {}秒".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 time

import 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_embedding


def 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_time
    print("消耗时间为: {}秒".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 time

import 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_embedding


def 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_time
    print("消耗时间为: {}秒".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 time

import 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_embedding


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_time
    print("消耗时间为: {:.2f}秒".format(used_time))


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/164953.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分组交换技术

目录 一、新型计算机网络的基本特点 二、电路交换 1、回顾电路交换的原理 2、使用交换机连接许多部电话 3、电路交换举例 4、电路交换的三个阶段 5、电路交换的特点 三、分组交换 1、因特网有边缘部分与核心部分组成 2、分组交换的原理 3、分组交换的优点 4、存储转…

RepVgg: 网络结构重参化

CVPR2021 截至目前1004引 论文连接 代码连接 文章提出的问题 大多数的研究者追求的是设计一个好的网络结构,这种“好”体现在网络具有复杂的网络设计,这种网络虽然比简单的网络收获了更加高的准确率,但是网络结构中的大量并行分支,导致模型的难以应用和自定义,主要体现…

支付、结算、对账流程

1、支付过程概览 2、微信支付流程 以微信支付为例,用户使用北京银行,商户收款银行为工行银行,列出机构名 用户在商户处选购商品或服务,选择使用微信支付进行付款。用户打开微信支付,输入支付密码或进行指纹识别等身份验证。微信支付系统将支付请求发送给北京银行。北京银行…

【Spring】之注解存取Bean对象

在本系列的上一篇文章中,我们已经了解了Spring的一些核心概念,并且还学习了Spring存取。但是我们发现在存取的过程中还是比较复杂,接下来我们将学习更为简单的Spring存取,其中涉及到的主要内容就是注解。并且在Spring家族的学习过…

kubenetes-服务发现和负载均衡

一、服务发布 kubenetes把服务发布至集群内部或者外部,服务的三种不同类型: ClusterlPNodePortLoadBalancer ClusterIP是发布至集群内部的一个虚拟IP,通过负载均衡技术转发到不同的pod中。 NodePort解决的是集群外部访问的问题,用户可能不…

FL Studio2024免费编曲音乐制作软件

用FL Studio编曲,让音乐成为你的翅膀,飞翔在无尽的创作海洋中吧! FL Studio作为一款功能强大且备受赞誉的音乐制作软件,为你提供了一个独特的创作平台。通过FL Studio,你可以自由地创作、编曲,制作属于自己…

IDEA 搭建 SpringCloud 项目【超详细步骤】

文章目录 一、前言二、项目搭建1. 数据库准备2. 创建父工程3. 创建注册中心4. 服务注册5. 编写业务代码6. 服务拉取 一、前言 所谓微服务,就是要把整个业务模块拆分成多个各司其职的小模块,做到单一职责原则,不会重复开发相同的业务代码&…

Jenkins测完通知到人很麻烦?一个设置配置钉钉消息提醒!

Jenkins 作为最流行的开源持续集成平台,其强大的拓展功能一直备受测试人员及开发人员的青睐。大家都知道我们可以在 Jenkins 中安装 Email 插件支持构建之后通过邮件将结果及时通知到相关人员。但其实 Jenkins 还可以支持钉钉消息通知,其主要通过 DingTa…

【Linux】动静态库的使用与软链接的结合

文章目录 前言一、静态库1.静态库的创建2.静态库的链接3.将库进行打包4.链接方法:1.直接链接2.拷贝到系统路径里面3.采用软链接方法 二、动态库1.解决加载找不到动态库的方法1.直接拷贝2.建立软链接3.建立自己的动态路径配置文件 2.为什么动态库权限需可执行而静态库…

【WSL/WSL2-Ubuntu】突破界限:不使用服务器在一台Windows搭建Nginx+FastDFS

打造超级开发环境:Nginx和FastDFS在WSL中的完美结合 前言 随着软件开发领域的快速发展,跨平台的开发环境变得日益重要。Windows Subsystem for Linux(WSL)和WSL 2为开发者提供了在Windows操作系统上体验Linux环境的便捷途径。本…

javaspringbootmysql学生社团管理系统26281-计算机毕业设计项目选题推荐(附源码)

目录 摘要 Abstract 1 绪论 1.1 研究背景 1.2 研究意义 1.3论文结构与章节安排 2 学生社团管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析…

用户增长模型:3A3R策略模型

一、概述 A - A - A - R - R - R 增长模型,即3A3R策略模型,由海盗模型演变而来,是目前使用最多、适用范围最广的增长策略模型。原始的海盗模型由 Acquisition (获客)、 Activation (活跃)、 Re…

【选题推荐】软件工程毕设选题可以选什么

文章目录 0 简介1 如何选题2 最新软件工程毕设选题3 最后 0 简介 学长搜集分享最新的软件工程业专业毕设选题,难度适中,适合作为毕业设计,大家参考。 学长整理的题目标准: 相对容易工作量达标题目新颖 1 如何选题 最近非常多的…

C语言选择结构 if 语句

if语句 程序运行结构if语句常见三种形式单行格式if语句多行格式if语句多条件的if语句 嵌套if语句if语句案例三只鸡那只重 if语句注意事项 程序运行结构 C语言支持最基本的三种程序运行结构:顺序结构、选择结构(分支结构)、循环结构 顺序结构&#xff1…

2023年高压电工证考试题库及高压电工试题解析

题库来源:安全生产模拟考试一点通公众号小程序 2023年高压电工证考试题库及高压电工试题解析是安全生产模拟考试一点通结合(安监局)特种作业人员操作证考试大纲和(质检局)特种设备作业人员上岗证考试大纲随机出的高压…

《洛谷深入浅出基础篇》 P5250 木材仓库————集合应用实例

上链接: P5250 【深基17.例5】木材仓库 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P5250上题干: 题目描述 博艾市有一个木材仓库,里面可以存储各种长度的木材,但是保证没有两个木材的长度是…

Java面向对象(高级)-- 类的成员之四:代码块

文章目录 一、回顾(1)三条主线(2)类中可以声明的结构及作用1.结构2.作用 二、代码块(1)代码块的修饰与分类1. 代码块的修饰2. 代码块的分类3. 举例 (2) 静态代码块1. 语法格式2. 静态…

两栏布局:左侧固定,右侧自适应

左侧宽度固定&#xff0c;右侧宽度自适应剩余空间 方法一&#xff1a;float margin 方法二&#xff1a;flex布局 相关HTML代码 <div class"container"><div class"left"></div><div class"main"></div> </d…

BGP基本配置

配置逻辑 完成所有路由器的IGP配置使用直连接口建立EBGP对等体关系使用环回接口建立IBGP对等体关系使用connect-interface命令修改IBGP建邻源IP地址使用next-hop-local命令修改路由传递时的下一跳属性若存在使用环回接口建立EBGP对等体关系&#xff0c;则需要建立通讯条件&…