nn.embedding函数详解(pytorch)

提示:文章附有源码!!!

文章目录


前言

最近发现prompt工程(如sam模型),也有transform的detr模型等都使用了nn.Embedding函数,对points、boxes或learn query进行编码或解码。因此,我想写一篇文章作为记录,本想简单对其 介绍,但写着写着就想把所有与它相关东西作为记录。本文章探讨了nn.Embedding参数、使用方法、模型训练与预测的变化,并附有列子源码作为支撑 ,呈现一个较为完善的理解内容。

一、nn.embedding函数解释

Embedding实际是一个索引表或查找表,它是符合随机初始化生成的正太分布的表,将输入向量化,其结构如下:

c 复制代码
nn.Embedding(num_embeddings, embedding_dim)

第1个参数 num_embeddings 就是生成num_embeddings个嵌入向量。

第2个参数 embedding_dim 就是嵌入向量的维度,即用embedding_dim值的维数来表示一个基本单位。

当然,该函数还有很多其它参数,解释如下:

参数源码注释如下:

c 复制代码
num_embeddings (int): size of the dictionary of embeddings
embedding_dim (int): the size of each embedding vector
padding_idx (int, optional): If specified, the entries at :attr:`padding_idx` do not contribute to the gradient;
                             therefore, the embedding vector at :attr:`padding_idx` is not updated during training,
                             i.e. it remains as a fixed "pad". For a newly constructed Embedding,
                             the embedding vector at :attr:`padding_idx` will default to all zeros,
                             but can be updated to another value to be used as the padding vector.
max_norm (float, optional): If given, each embedding vector with norm larger than :attr:`max_norm`
                            is renormalized to have norm :attr:`max_norm`.
norm_type (float, optional): The p of the p-norm to compute for the :attr:`max_norm` option. Default ``2``.
scale_grad_by_freq (boolean, optional): If given, this will scale gradients by the inverse of frequency of
                                        the words in the mini-batch. Default ``False``.
sparse (bool, optional): If ``True``, gradient w.r.t. :attr:`weight` matrix will be a sparse tensor.
                         See Notes for more details regarding sparse gradients.

参数中文解释:

c 复制代码
num_embeddings (python:int) -- 词典的大小尺寸,比如总共出现5000个词,那就输入5000。此时index为(0-4999)
embedding_dim (python:int) -- 嵌入向量的维度,即用多少维来表示一个符号。
padding_idx (python:int, optional) -- 填充id,比如,输入长度为100,但是每次的句子长度并不一样,后面就需要用统一的数字填充,而这里就是指定这个数字,这样,网络在遇到填充id时,就不会计算其与其它符号的相关性。(初始化为0)
max_norm (python:float, optional) -- 最大范数,如果嵌入向量的范数超过了这个界限,就要进行再归一化。
norm_type (python:float, optional) -- 指定利用什么范数计算,并用于对比max_norm,默认为2范数。
scale_grad_by_freq (boolean, optional) -- 根据单词在mini-batch中出现的频率,对梯度进行放缩。默认为False.
sparse (bool, optional) -- 若为True,则与权重矩阵相关的梯度转变为稀疏张量

注:该函数服从正太分布,该函数可参与训练,我将在后面做解释。

二、nn.embedding函数使用方法

该函数实际是对词的编码,假如你有2句话,每句话有四个词,那么你想对每个词使用6个维度表达,其代码如下:

c 复制代码
import torch.nn as nn
import torch
if __name__ == '__main__':
   embedding = nn.Embedding(100, 6)  # 我设置100个索引,每个使用6个维度表达。
   input = torch.LongTensor([[1, 2, 4, 5],
   [4, 3, 2, 3]])  # a batch of 2 samples of 4 indices each
   e = embedding(input)
   print('输出尺寸', e.shape)
   print('输出值:\n',e)
   weights=embedding.weight
   print('embed权重输出值:\n', weights[:6])
     

输出结果:

从图上可看出,输入编码是通过索引查找已编号embedding的权重,并将其赋值替换表达。换句话说,nn.Embedding(100, 6)生成正太分布100行6列数据,行必须超过输入句子词语长度,而句子每个词使用整数编码成索引,该索引对应之前embedding行寻找,得到对应行

维度,即可转为表达该词的特征向量。

四、模型训练与预测的权重变化探讨

之前已说过nn.Embedding()在训练过程中会发生变化,但在预测中将不在变化,应该是被训练成最佳词的向量维度表达,也就是说每个词唯一对应索引,被Embedding特征表达训练成最佳特征表达,也可说训练词索引特征表达固定。为探讨此过程,我写了对应示列,如下:

c 复制代码
import torch
from torch.nn import Embedding

class Model(torch.nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.emb = Embedding(5, 3)
    def forward(self,vec):
        input = torch.tensor([0, 1, 2, 3, 4])
        emb_vec1 = self.emb(input)
        # print(emb_vec1)  ### 输出对同一组词汇的编码
        output = torch.einsum('ik, kj -> ij', emb_vec1, vec)
        return output
def simple_train():
    model = Model()
    vec = torch.randn((3, 1))
    label = torch.Tensor(5, 1).fill_(3)
    loss_fun = torch.nn.MSELoss()
    opt = torch.optim.SGD(model.parameters(), lr=0.015)
    print('初始化emebding参数权重:\n',model.emb.weight)
    for iter_num in range(100):
        output = model(vec)
        loss = loss_fun(output, label)
        opt.zero_grad()
        loss.backward(retain_graph=True)
        opt.step()
        # print('第{}次迭代emebding参数权重{}:\n'.format(iter_num, model.emb.weight))
    print('训练后emebding参数权重:\n',model.emb.weight)
    torch.save(model.state_dict(),'./embeding.pth')
    return model

def simple_test():
   model = Model()
   ckpt = torch.load('./embeding.pth')
   model.load_state_dict(ckpt)

   model=model.eval()
   vec = torch.randn((3, 1))

   print('加载emebding参数权重:\n', model.emb.weight)
   for iter_num in range(100):
      output = model(vec)
   print('n次预测后emebding参数权重:\n', model.emb.weight)

if __name__ == '__main__':
   simple_train()  # 训练与保存权重
   simple_test()

结果如下:

训练代码参考博客:点击这里

相关推荐
摸鱼仙人~11 小时前
BERT分类的上下文限制及解决方案
人工智能·分类·bert
神一样的老师11 小时前
微型机器学习(TinyML):研究趋势与未来应用机遇
人工智能·机器学习
木头程序员11 小时前
机器学习概述:核心范式、关键技术与应用展望
大数据·人工智能·机器学习·回归·聚类
悟道心11 小时前
5. 自然语言处理NLP - Transformer
人工智能·自然语言处理·transformer
摸鱼仙人~11 小时前
使用 BERT 系列模型实现 RAG Chunk 分类打标
人工智能·分类·bert
c76911 小时前
【文献笔记】Mixture-of-Agents Enhances Large Language Model Capabilities
人工智能·笔记·语言模型·自然语言处理·论文笔记·提示工程
我的offer在哪里11 小时前
Unsloth,为大语言模型(LLM)微调设计的高效开源框架
人工智能·语言模型·开源
zhengfei61111 小时前
【AI工具】——人工智能驱动的自动化网络安全威胁检测平台
人工智能·web安全·自动化
2503_9469718611 小时前
【BruteForce/Pruning】2026年度物理层暴力破解与神经网络剪枝基准索引 (Benchmark Index)
人工智能·神经网络·算法·数据集·剪枝·网络架构·系统运维
~央千澈~11 小时前
AI音乐100%有版权的路劲是什么?AI音乐的版权处理卓伊凡
人工智能