【NLP入门系列三】NLP文本嵌入(以Embedding和EmbeddingBag为例)

在这里插入图片描述

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

博主简介:努力学习的22级本科生一枚 🌟​;探索AI算法,C++,go语言的世界;在迷茫中寻找光芒​🌸
博客主页:羊小猪~~-CSDN博客
内容简介:NLP入门三,Embedding和EmbeddingBag嵌入.
🌸箴言🌸:去寻找理想的“天空“”之城
上一篇内容:【NLP入门系列二】NLP分词和字典构建-CSDN博客

文章目录

  • NLP文本嵌入
    • 前言
    • 1、Embedding嵌入
    • 2、EmbeddingBag嵌入
    • 3、参考资料

NLP文本嵌入

前言

📄 大模型语言理解文字方式: 将每一个词当做一个数字,然后不断地进行做计算题,从而不断地输出文字;

举例

如果用一个数字表示一个词,这里用1表示男人,2表示女人,这样的作用是给词进行了编号,但是表示无法表示词与词之间的关系。

但是,如果用两位数字表示呢?

👀 参考b站大佬视频:

在数学中,向量是有方向的,可以做运算,这里也一样,如图:

在这里插入图片描述
在数学中,向量是有方向的,可以做运算,这里也一样,如图:
在这里插入图片描述
这样就实现了:将每一个词当做一个数字,然后进行做计算题,从而输出文字;


💠 词嵌入: 用向量表示词。**原理:**将词嵌入到数学的维度空间,如果词用二维表示,那么嵌入到一个二维空间里,以此类推;

本质: 将离散的词汇映射到一个低维连续的向量空间中,这样词汇之间的关系就可以在向量空间中得到体现。


📘 大模型语言训练过程

大模型语言训练是一个很复杂的过程,但是了解最基本过程还是简单的,如下图表示(刚开始不同词随机分布在二维空间中不同位置):
在这里插入图片描述

经过模型训练后:
在这里插入图片描述

将语义相近的分布在一起,但是也有一些中立词,如苹果这个词,吃苹果和苹果手机是不同意思的,所以苹果就是中立的,具体的意思需要根据模型训练过程中结合上下文进行运算得出结果。

EmbeddingEmbeddingBagpytorch处理文本数据词嵌入的工具。

1、Embedding嵌入

Embeddingpytorch中最基本的词嵌入操作。

输入:一整张向量,每个整数都代表一个词汇的索引

输出:是一个浮点型的张量,每个浮现数都代表着对应词汇的词嵌入向量。

维度变化

  • 输入shape:[batch, seqSize] ,seqSize表示单个文本长度(注意:同一批次中每个样本的序列长度(seq_len)必须相同);
  • 输出shape:[batch, seqSize, embed_dim]embed_bim 表示嵌入维度。

👙 注意:嵌入层被定义为网络的第一个隐藏层,采用随机权重初始化的方式,既可以作为深度学习模型的一部分,一起训练,也可以用于用于加载训练好的词嵌入模型。

函数原型

torch.nn.Embedding(num_embeddings, embedding_dim, padding_idx=None,                     max_norm=None,norm_type=2.0,scale_grad_by_freq=False,                     sparse=False,_weight=None,_freeze=False, device=None,                     dtype=None)

常见参数:

  • num_embeddings:词汇表大小, 即,最大整数 index + 1。
  • embedding_dim:词向量的维度。

📚 以一个二分类案例为例:

1、导入库和自定义数据格式

import torch
import torch.nn as nn 
import torch.nn.functional as F 
import torch.optim as optim 
from torch.utils.data import Dataset, DataLoader# 自定义数据维度
class MyDataset(Dataset):def __init__(self, texts, labels):super().__init__()self.texts = textsself.labels = labelsdef __len__(self):return len(self.labels)def __getitem__(self, idx):text = self.texts[idx]label = self.labels[idx]return text, label

2、定义填充函数(将所有词长度变成一致)

def collate_batch(batch):# 解包texts, labels = zip(*batch) # texts、labels存储在不同[]/()这样的数据结构# 获取最大长度max_len = max(len(text) for text in texts)# 填充, 不够的填充为0padding_texts = [F.pad(text, (0, max_len - len(text)), value=0) for text in texts] # 采用右填充# 改变维度--> (batch_size, max_len)padding_texts = torch.stack(padding_texts)# 标签格式化(改变维度)--> (batch_size) --> (batch_size, 1), 不改变值labels = torch.tensor(labels, dtype=torch.float).unsqueeze(1)return padding_texts, labels

3、定义数据

# 定义三个样本
data = [torch.tensor([1, 1, 1], dtype=torch.long), torch.tensor([2, 2, 2], dtype=torch.long),torch.tensor([3, 3], dtype=torch.long)
]# 定义标签
labels = torch.tensor([1, 2, 3], dtype=torch.float)# 创建数据
data = MyDataset(data, labels)
data_loader = DataLoader(data, batch_size=2, shuffle=True, collate_fn=collate_batch)# 展示
for batch in data_loader:print(batch)print("shape:", batch)
(tensor([[1, 1, 1],[3, 3, 0]]), tensor([[1.],[3.]]))
shape: (tensor([[1, 1, 1],[3, 3, 0]]), tensor([[1.],[3.]]))
(tensor([[2, 2, 2]]), tensor([[2.]]))
shape: (tensor([[2, 2, 2]]), tensor([[2.]]))

4、定义模型

class EmbeddingModel(nn.Module):def __init__(self, vocab_size, embed_dim):super(EmbeddingModel, self).__init__()# 定义模型self.embedding = nn.Embedding(vocab_size, embed_dim) # 词汇表大小 + 嵌入维度self.fc = nn.Linear(embed_dim, 1)  # 这里假设做二分类任务def forward(self, text):print("Embedding输入文本是: ", text)print("Embedding输入文本shape: ", text.shape)embedding = self.embedding(text)embedding_mean = embedding.mean(dim=1)print("embedding输出文本维度: ", embedding_mean.shape)return self.fc(embedding_mean)

注意
如果使用embedding_mean = embedding.mean(dim=1)语句对每个样本的嵌入向量求平均,输出shape为[batch, embed_dim]。若注释掉该语句,输出shape则为[batch, seqSize, embed_dim]


5、模型训练

# 定义词表大小和嵌入维度
vacab_size = 10
embed_dim = 6# 创建模型
model = EmbeddingModel(vacab_size, embed_dim)# 设置超参数
cirterion = nn.BCEWithLogitsLoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)# 模型训练
for epoch in range(1):for batch in data_loader:text, label = batch# 前向传播outputs = model(text)loss = cirterion(outputs, label)# 方向传播optimizer.zero_grad()loss.backward()optimizer.step()print(f'Epoch {epoch+1}, Loss: {loss.item()}')
Embedding输入文本是:  tensor([[2, 2, 2],[1, 1, 1]])
Embedding输入文本shape:  torch.Size([2, 3])
embedding输出文本维度:  torch.Size([2, 6])
Epoch 1, Loss: 0.6635428667068481
Embedding输入文本是:  tensor([[3, 3]])
Embedding输入文本shape:  torch.Size([1, 2])
embedding输出文本维度:  torch.Size([1, 6])
Epoch 1, Loss: 0.5667202472686768

2、EmbeddingBag嵌入

EmbeddingBag是在Embedding基础上进一步优化的工具,其核心思想是将每个输入序列的嵌入向量进行合并,能够处理可变长度的输入序列,并且减少了计算和存储的开销,并且可以计算句子中所有词汇的词嵌入向量的均值或总和。

减少计算量:因为embedding嵌入中需要要求每一个词向量长度需要一样。

PyTorch中,EmbeddingBag输入是一个 整数张量 和一个 偏移量张量每个整数都代表着一个词汇的索引,偏移量则表示句子中每个词汇的位置输出是一个浮点型的张量,每个浮点数都代表着对应句子的词嵌入向量的均值或总和。

  • 输入shape:[seqsSize](seqsSize为单个batch文本总长度)
  • 输出shape:[batch, embed_dim](embed_dim嵌入维度)

📐 假设原始输入数据为 [[1, 1, 1, 1], [2, 2, 2], [3, 3]]

  1. 展平的词汇索引张量

    • 将所有样本的数据合并成一个一维数组。如 [1, 1, 1, 1, 2, 2, 2, 3, 3]
  2. 偏移量

    偏移量表示每个样本在展平张量中的起始位置。如本案例: [0, 4, 7]

  3. 合并操作

    • 根据偏移量进行合并
    • 合并操作可以是求和、平均或取最大值,默认是平均(mean)。以平均为例:
      • 第一个样本的平均值:(1 + 1 + 1 + 1) / 4 = 1
      • 第二个样本的平均值:(2 + 2 + 2) / 3 = 2
      • 第三个样本的平均值:(3 + 3) / 2 = 3
      • 最后结果为 [1, 2, 3],即batch维度

📑 一个简单的案例如下:

1、导入库和自定义数据格式

import torch
import torch.nn as nn 
import torch.nn.functional as F 
import torch.optim as optim 
from torch.utils.data import Dataset, DataLoader# 自定义数据维度
class MyDataset(Dataset):def __init__(self, texts, labels):super().__init__()self.texts = textsself.labels = labelsdef __len__(self):return len(self.labels)def __getitem__(self, idx):text = self.texts[idx]label = self.labels[idx]return text, label

2、定义数据

# 定义三个样本
data = [torch.tensor([1, 1, 1], dtype=torch.long), torch.tensor([2, 2, 2], dtype=torch.long),torch.tensor([3, 3], dtype=torch.long)
]# 定义标签
labels = torch.tensor([1, 2, 3], dtype=torch.float)# 创建数据
data = MyDataset(data, labels)
data_loader = DataLoader(data, batch_size=2, shuffle=True, collate_fn=lambda x : x)# 展示
for batch in data_loader:print(batch)
[(tensor([1, 1, 1]), tensor(1.)), (tensor([3, 3]), tensor(3.))]
[(tensor([2, 2, 2]), tensor(2.))]

3、定义模型

class EmbeddingModel(nn.Module):def __init__(self, vocab_size, embed_dim):super(EmbeddingModel, self).__init__()# 定义模型self.embedding_bag = nn.EmbeddingBag(vocab_size, embed_dim, mode='mean')self.fc = nn.Linear(embed_dim, 1)  # 这里假设做二分类任务def forward(self, text, offsets):print("Embedding输入文本是: ", text)print("Embedding输入文本shape: ", text.shape)embedding_bag = self.embedding_bag(text, offsets)print("embedding_bag输出文本维度: ", embedding_bag.shape)return self.fc(embedding_bag)

4、模型训练

# 定义词表大小和嵌入维度
vacab_size = 10
embed_dim = 6# 创建模型
model = EmbeddingModel(vacab_size, embed_dim)# 设置超参数
cirterion = nn.BCEWithLogitsLoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)# 模型训练
for epoch in range(1):for batch in data_loader:# 展平和计算偏移量texts, labels = zip(*batch)# 偏移量计算,就是统计文本长度offset = [0] + [len(text) for text in texts[:-1]] # 统计长度offset = torch.tensor(offset).cumsum(dim=0) # 生成偏移量,累计求和texts = torch.cat(texts)  # 合并文本labels = torch.tensor(labels).unsqueeze(1)  # 增加维度-->(batch_size, 1)# 前向传播outputs = model(texts, offset)loss = cirterion(outputs, labels)# 方向传播optimizer.zero_grad()loss.backward()optimizer.step()print(f'Epoch {epoch+1}, Loss: {loss.item()}')
Embedding输入文本是:  tensor([2, 2, 2, 1, 1, 1])
Embedding输入文本shape:  torch.Size([6])
embedding_bag输出文本维度:  torch.Size([2, 6])
Epoch 1, Loss: 0.07764509320259094
Embedding输入文本是:  tensor([3, 3])
Embedding输入文本shape:  torch.Size([2])
embedding_bag输出文本维度:  torch.Size([1, 6])
Epoch 1, Loss: 3.315852642059326

3、参考资料

  • 【大模型靠啥理解文字?通俗解释:词嵌入embedding】https://www.bilibili.com/video/BV1bfoQYCEHC?vd_source=1fd424333dd77a7d3e2e741f7d6fd4ee
  • PyTorch 简单易懂的 Embedding 和 EmbeddingBag - 解析与实践_nn.embeddingbag-CSDN博客
  • 小团体~第十二波

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文心一言(ERNIE Bot):百度打造的知识增强大语言模型

1. 产品概述 文心一言(ERNIE Bot)是百度自主研发的知识增强大语言模型,于2023年3月16日正式发布,对标OpenAI的ChatGPT,具备文本生成、多模态交互、逻辑推理、中文理解等能力。该模型基于百度的飞桨深度学习平台和文心…

Java-49 深入浅出 Tomcat 手写 Tomcat 实现【02】HttpServlet Request RequestProcessor

点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月13日更新到: AI炼丹日志-28 - Aud…

在VB.net中,文本插入的几个自定义函数

一、如果你是高手&#xff0c;一定“识货”&#xff0c;分享给你 二、可应用于文本插入的几种方式&#xff1a;6种 三、需要用到以下的几个函数&#xff1a; 上代码&#xff1a; Module TextModule <summary> 在指定位置插入文本 </summary> <p…

QC -io 服务器排查报错方式/报错: Failed to convert string to integer of varId variable!“

进断点控制台有报错之后&#xff0c;复制报错信息到 头部菜单栏 1.编辑 -> 2.Find/Replace ->3.Advanced Find ->4. Project“xxxxx” 能找到问题点 再分析定位 在排查报错时候&#xff0c;进入了这个报错&#xff0c;msgInfo "MyTcpRedis: Failed to conver…

c++中auto与decltype使用

在 C11及后续版本中&#xff0c;关键字auto和decltype都是用于类型推导的&#xff0c;但它们的使用场景和行为有所不同。 1. auto 关键字 作用 auto 用于自动推导变量的类型&#xff0c;由编译器根据初始化表达式来确定。 常见用法 // 基本用法 auto x 42; // int…

LabVIEW机器视觉零件检测

基于LabVIEW 图形化编程平台与机器视觉技术&#xff0c;构建集图像采集、处理、尺寸计算与合格性分析于一体的自动化检测方案。通过模块化硬件架构与自适应算法设计&#xff0c;实现对机械零件多维度尺寸的非接触式高精度测量&#xff0c;相比人工检测效率提升 12 倍&#xff0…

大数据治理域——实时数据开发

摘要 本文深入探讨了大数据治理域中的实时数据开发&#xff0c;重点介绍了流式数据处理的核心价值、特点、技术挑战、典型能力和应用场景。同时&#xff0c;详细阐述了流式技术架构&#xff0c;包括数据采集、处理、存储和服务等环节&#xff0c;并针对大促场景提出了相应的技…

Halcon/C# 图像窗口、读取图片及仿射变换

一、Halcon 清理窗口 清除图像窗口的显示。 dev_clear_window() 二、Halcon 读取图片 (一) 读取一张图片 read_image (Image, printer_chip/printer_chip_01)Image&#xff1a;&#xff08;输出参数&#xff09;读取到的图片变量名 第二个参数&#xff1a;图片路径&#xf…

Nginx 反向代理服务和安装docker-compose

Nginx 反向代理服务和安装docker-compose Nginx Proxy Manager 他是一个可视化的nginx的反向代理神器&#xff0c;动动手指轻松的配置Nginx&#xff0c;我们可以通过一些网页&#xff0c;即可完成网站的代理配置&#xff0c;无需在动手安装Nginx&#xff1b; dockoer-compose部…

FPGA基础 -- Verilog 锁存器简介

由浅入深地讲解 Verilog 中的锁存器&#xff08;Latch&#xff09;**&#xff0c;包括&#xff1a; 什么是锁存器&#xff08;定义与作用&#xff09;锁存器的分类&#xff08;透明锁存器 vs 边沿触发器&#xff09;Verilog 中锁存器的建模方式锁存器与触发器的区别锁存器的时…

Eclipse Memory Analyzer (MAT) 相关配置调整

一、JDK版本过低提示 已安装高于 jdk 17 的版本依旧提示 jdk 版本过低&#xff0c;打开MAT的安装目录&#xff0c;在配置文件 MemoryAnalyzer.ini 中添加配置指向JDK即可。新增两行配置&#xff1a; -vm D:/jdk_21.0.7/bin/javaw.exe //jdk安装路径 bin 目录下的javaw.exe二…

机器学习常用评估指标

机器学习常用评估指标 机器学习的评价指标有精度、精确率、召回率、P-R曲线、F1 值、TPR、FPR、ROC等指标&#xff0c;还有在生物领域常用的敏感性、特异性等指标。 基础 在分类任务中&#xff0c;各指标的计算基础都来自于对正负样本的分类结果&#xff0c;用混淆矩阵表示&…

视频相似度检测算法(带课设报告)

摘 要 本文提出了一种基于关键帧特征提取的视频相似度检测方法&#xff0c;通过融合自适应采样与特征降维技术实现高效准确的视频内容比对。系统采用三阶段处理流程&#xff1a;首先对输入视频进行自适应关键帧采样&#xff0c;通过均匀间隔算法提取固定数量&#xff08;默…

微服务江湖的爱恨情仇:Spring Cloud 与 Kubernetes 的双雄演义

引言&#xff1a;双雄并立&#xff0c;一个时代的序幕 微服务革命&#xff0c;如同一场燎原之火&#xff0c;将庞大、笨重的单体应用烧成灰烬&#xff0c;宣告了一个敏捷、独立、快速迭代的新纪元。然而&#xff0c;这场革命在摧毁旧世界的同时&#xff0c;也催生了一片混沌的新…

深度拆解RAGFlow分片引擎之切片实现

上一篇深度拆解RAGFlow分片引擎&#xff01;3大阶段视觉增强&#xff0c;全网最硬核架构解析 讲了切片的整体流程&#xff0c;今天我们来拆下切片的实现。 我们在设置的时候&#xff0c;可以选择切片方法。这个参数是parser_id 在创建知识库的时候&#xff0c;选择对应的切片方…

CSS平滑滚动效果实现方法

一、纯CSS实现方案 使用 scroll-behavior 属性 属性值 auto (默认值)&#xff1a;滚动框立即滚动smooth&#xff1a;滚动框以平滑的方式滚动 /* 全局平滑滚动 */ html {scroll-behavior: smooth; }/* 特定容器平滑滚动 */ .scroll-container {scroll-behavior: smooth;over…

李沐动手深度学习(pycharm中运行笔记)——12.权重衰退

12.权重衰退&#xff08;与课程对应&#xff09; 目录 一、权重衰退 1、使用均方范数作为硬性限制 2、使用均方范数作为柔性限制&#xff08;通常这么做&#xff09; 3、演示对最优解的影响 4、参数更新法则 5、总结 二、代码实现从零实现 三、代码实现简介实现 一、权重…

React Native【实战范例】同步跟随滚动

最终效果 实现原理 主动滚动区触发滚动事件&#xff0c;原生监听滚动值的变化&#xff0c;并用动画的方式实时同步到跟随滚动区 技术要点 使用 Animated.ScrollView 使用动画变量 const scrollY useRef(new Animated.Value(0)).current;主动滚动触发 onScroll&#xff0c;用 …

如何仅用AI开发完整的小程序<3>—创建小程序基础框架

1、启动小程序开发者工具-选择小程序&#xff0c;点击 2、创建一个项目工程 项目名称&#xff1a;自己填默认的也行&#xff0c;最好不要中文&#xff0c;拼音也行 目录&#xff1a;选择你的项目创建路径 AppID&#xff1a;可以先点测试号&#xff0c;后面再替换自己的AppID就…

SQL等价改写优化

or 与 union all的优化 在SQL开发中&#xff0c;我们经常会遇到这样的情况&#xff1a;需要组合多个相似但略有不同的查询结果。大多数开发者本能地使用UNION/UNION ALL来解决&#xff0c;这种方式直观易懂&#xff0c;但在特定场景下却隐藏着巨大的性能浪费。 本案例将从执行…