pytorch api文档:torch.nn.Embedding()创建嵌入层 作者:马育民 • 2026-01-14 22:28 • 阅读:10000 # 介绍 `torch.nn.Embedding` 是 PyTorch 中用于实现 **嵌入层**(Embedding Layer)的模块,核心作用是将 **离散的整数索引**(比如单词的编号 0、1、2...)映射为**连续的低维稠密向量**(比如 128 维的向量)。 简单来说: - 输入:一组整数(比如 `[1, 5, 3]`,代表 3 个单词的索引) - 输出:一组对应的稠密向量(比如 3 个 128 维的向量) - 本质:一个可训练的查找表(lookup table),表中的每一行对应一个索引的嵌入向量,训练过程中这些向量会不断优化。 ### 应用场景 - **自然语言处理(NLP)**:将单词/字符的索引映射为词向量(如 Transformer、LSTM 的输入层); - **推荐系统**:将用户 ID、物品 ID 映射为稠密向量,用于后续的相似度计算; - **计算机视觉**:将类别索引(如标签编号)映射为向量,辅助分类任务。 # 语法 ```python 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, device=None, dtype=None) ``` 关键参数: | 参数 | 作用 | |------------------|----------------------------------------------------------------------| | `num_embeddings` | 必选,嵌入词典的大小(即有多少个不同的索引/单词需要映射) | | `embedding_dim` | 必选,每个嵌入向量的维度(比如 128、256,决定向量的表达能力) | | `padding_idx` | 可选,指定填充索引(比如 NLP 中常用 0 作为 padding,该索引的向量训练时不更新) | | `max_norm` | 可选,限制嵌入向量的最大范数(防止向量值过大) | # 属性 `torch.nn.Embedding` 作为 `nn.Module` 的子类,除了继承的通用属性(如 `training`、`_device` 等),最核心的是和嵌入向量直接相关的属性,以下是新手必须掌握的关键属性: | 属性名 | 类型 | 核心作用 | |--------------|---------------------|--------------------------------------------------------------------------| | `weight` | `nn.Parameter` | 嵌入层的权重矩阵(查找表),形状为 `[num_embeddings, embedding_dim]`,可训练(除非手动设置 `requires_grad=False`) | | `num_embeddings` | `int` | 嵌入词典的大小(初始化时传入的参数) | | `embedding_dim` | `int` | 每个嵌入向量的维度(初始化时传入的参数) | | `padding_idx` | `int`/`None` | 填充索引(初始化时传入的参数,若为 `None` 则无填充) | | `max_norm` | `float`/`None` | 嵌入向量的最大范数限制(初始化时传入的参数) | ### 只读属性 vs 可修改属性 - `num_embeddings`、`embedding_dim` 是 **只读属性**(初始化后无法修改),如果要调整词典大小/嵌入维度,只能重新创建 Embedding 层。 - `padding_idx`、`max_norm` 可以修改(如 `embedding.padding_idx = 1`),修改后会影响后续的前向传播。 - `weight` 是可修改的,既可以直接改值,也可以修改其 `requires_grad` 状态。 ### 填充索引的权重特性 如果设置了 `padding_idx`,该索引对应的权重在反向传播时**梯度会被置 0**(即不会更新),保证 padding 向量始终是初始值(默认全 0)。 ```python # 验证 padding_idx=0 的权重梯度 input_idx = torch.tensor([0, 1, 2]) output = embedding(input_idx) output.sum().backward() # 反向传播 print("\npadding_idx=0 的权重梯度:", embedding.weight.grad[0]) # 输出:全 0 print("非 padding 索引 1 的权重梯度:", embedding.weight.grad[1]) # 输出:非 0 ``` # 例子 ### 创建、常用属性 ``` import torch.nn as nn # 创建 Embedding 层 # 词典大小:4(索引 0-4),嵌入维度:3(每个索引映射为 3 维向量),即:权重是4行3列 embedding = nn.Embedding(num_embeddings=4, embedding_dim=3) print(embedding) print("嵌入词典的大小:", embedding.num_embeddings) # 4 print("每个嵌入向量的维度:", embedding.embedding_dim) # 3 print("\n=== 权重矩阵(weight) ===") print("权重weight:", embedding.weight) # 4行3列的张量 # weight 是 nn.Parameter 类型,本质是张量,形状 [num_embeddings, embedding_dim] print("weight 形状:", embedding.weight.shape) # 输出:torch.Size([10, 4]) print("weight 数据类型:", embedding.weight.dtype) # 输出:torch.float32 # 查看索引 1 对应的嵌入向量(权重矩阵的第 1 行) print("索引 1 对应的嵌入向量:", embedding.weight[1]) ``` 执行结果: ``` Embedding(4, 3) 嵌入词典的大小: 4 每个嵌入向量的维度: 3 === 权重矩阵(weight) === 权重weight: Parameter containing: tensor([[ 0.5295, -1.9354, 0.3722], [ 0.6719, -1.4125, -0.0068], [-0.3018, -1.1436, -0.7975], [ 0.3823, -1.0013, 0.4396]], requires_grad=True) weight 形状: torch.Size([4, 3]) weight 数据类型: torch.float32 索引 1 对应的嵌入向量: tensor([ 0.6719, -1.4125, -0.0068], grad_fn=) ``` ### 创建并使用 Embedding 层 ```python import torch import torch.nn as nn # 1. 定义 Embedding 层 # 词典大小:10(索引 0-9),嵌入维度:4(每个索引映射为 4 维向量) embedding = nn.Embedding(num_embeddings=10, embedding_dim=4) # 2. 准备输入(整数索引,形状:[批量大小, 序列长度]) # 比如批量大小为 2,每个序列有 3 个索引 input_indices = torch.tensor([[1, 3, 5], [2, 4, 6]]) # 3. 前向传播(获取嵌入向量) embedded_output = embedding(input_indices) # 输出结果说明 print("输入索引形状:", input_indices.shape) # torch.Size([2, 3]) print("嵌入输出形状:", embedded_output.shape) # torch.Size([2, 3, 4]) print("索引 1 对应的嵌入向量:") print(embedded_output[0, 0]) # 第一行第一个索引(1)的 4 维向量 ``` ### 带 padding_idx 的 Embedding 层 ```python # 指定 padding_idx=0,索引 0 的向量训练时不会更新 embedding = nn.Embedding(num_embeddings=10, embedding_dim=4, padding_idx=0) # 输入包含 padding 索引 0 input_indices = torch.tensor([[0, 1, 3], [0, 0, 2]]) embedded_output = embedding(input_indices) # 验证:padding_idx=0 的向量梯度会被置 0(训练时不更新) embedded_output.sum().backward() # 模拟反向传播 print("嵌入层权重的梯度:") print(embedding.weight.grad) # 输出中,索引 0 对应的行全为 0,其他索引的行有梯度值 ``` # 特性与注意事项 1. **可训练性**:`Embedding` 层的权重(`embedding.weight`)是可训练的参数,会在反向传播中更新,这也是“词向量学习”的核心。 2. **输入要求**:输入必须是 **整数类型的张量**(`torch.long`/`torch.int64`),不能是浮点型。 3. **预训练词向量加载**:实际应用中,可加载预训练的词向量(如 Word2Vec、GloVe)初始化 `Embedding` 层: ```python # 假设 pretrained_embeddings 是形状为 [10, 4] 的预训练向量张量 pretrained_embeddings = torch.randn(10, 4) embedding = nn.Embedding(10, 4) embedding.weight.data = pretrained_embeddings # 加载预训练权重 # 如果不想更新预训练向量,设置 requires_grad=False embedding.weight.requires_grad = False ``` 4. **批量处理**:支持批量输入,输入形状一般为 `[batch_size, seq_len]`,输出形状为 `[batch_size, seq_len, embedding_dim]`。 # 总结 1. `torch.nn.Embedding` 是将 **整数索引** 映射为 **低维稠密向量** 的可训练层,核心是一个查找表; 2. 核心参数是 `num_embeddings`(词典大小)和 `embedding_dim`(向量维度),`padding_idx` 是 NLP 中常用的实用参数; 3. 它是 NLP 模型的基础组件,支持加载预训练向量,也可通过训练学习专属的嵌入表示。 原文出处:http://www.malaoshi.top/show_1GW2aoJ5nKFn.html