This commit is contained in:
e2hang
2025-09-09 15:56:55 +08:00
parent a5fdeaf70e
commit a8d78878fc
15 changed files with 2265 additions and 0 deletions

View File

@@ -0,0 +1,295 @@
`torch.nn.functional` 是 PyTorch 中提供神经网络相关功能的模块,包含了大量的函数,用于实现卷积、池化、激活函数、损失函数、归一化等操作。这些函数是 `torch.nn` 模块的函数式接口,通常用于定义神经网络的 `forward` 方法中,尤其是当不需要管理参数(如权重和偏置)时。以下是对 `torch.nn.functional` 模块中主要方法的全面讲解,基于 PyTorch 2.8 官方文档()以及相关信息。由于方法数量庞大,我将按类别组织并简要讲解每个方法的功能、输入输出和典型用途,尽量清晰简洁。如果需要更详细的讲解或代码示例,请告诉我![](https://docs.pytorch.org/docs/2.8/nn.functional.html)
---
### 1. 卷积函数 (Convolution Functions)
这些函数用于执行卷积操作,常用于处理图像、时间序列等数据。
- **`conv1d`**: 一维卷积,应用于序列数据(如时间序列)。
- **输入**: input (N, C_in, L_in), weight (C_out, C_in, kernel_size)
- **输出**: (N, C_out, L_out)
- **用途**: 特征提取,如音频信号处理。
- **参数**: stride, padding, dilation, groups 等控制卷积行为。
- **`conv2d`**: 二维卷积,适用于图像数据。
- **输入**: input (N, C_in, H, W), weight (C_out, C_in, kH, kW)
- **输出**: (N, C_out, H_out, W_out)
- **用途**: 图像特征提取,如边缘检测。
- **`conv3d`**: 三维卷积,适用于视频或体视显微镜数据。
- **输入**: input (N, C_in, D, H, W), weight (C_out, C_in, kD, kH, kW)
- **输出**: (N, C_out, D_out, H_out, W_out)
- **用途**: 视频处理或 3D 图像分析。
- **`conv_transpose1d` / `conv_transpose2d` / `conv_transpose3d`**: 转置卷积(有时称为“反卷积”),用于上采样。
- **输入**: 类似普通卷积,但 weight 维度相反。
- **输出**: 更大的特征图。
- **用途**: 生成模型、图像分割中的上采样。
- **`unfold`**: 从输入张量中提取滑动局部块。
- **输入**: input (N, C, *), kernel_size, stride, padding 等
- **输出**: (N, C * prod(kernel_size), L)
- **用途**: 实现自定义卷积或池化操作。
- **`fold`**: 将滑动局部块组合成大张量,与 `unfold` 相反。
- **输入**: input (N, C * prod(kernel_size), L), output_size, kernel_size
- **输出**: (N, C, output_size)
- **用途**: 重构特征图。
---
### 2. 池化函数 (Pooling Functions)
池化函数用于下采样,减少空间维度,增强模型的鲁棒性。
- **`avg_pool1d` / `avg_pool2d` / `avg_pool3d`**: 平均池化,计算区域内的平均值。
- **输入**: input (N, C, *), kernel_size, stride
- **输出**: 降维后的张量
- **用途**: 减少特征图尺寸,平滑特征。
- **`max_pool1d` / `max_pool2d` / `max_pool3d`**: 最大池化,提取区域内的最大值。
- **输入**: input (N, C, *), kernel_size, stride, return_indices可选
- **输出**: 降维后的张量,可选返回最大值索引
- **用途**: 提取显著特征,如边缘或纹理。
- **`max_unpool1d` / `max_unpool2d` / `max_unpool3d`**: 最大池化的逆操作,上采样。
- **输入**: input, indices来自 max_pooloutput_size
- **输出**: 恢复的张量
- **用途**: 解码器或生成模型中的上采样。
- **`lp_pool1d` / `lp_pool2d`**: Lp 范数池化,计算区域内的 p 次方均值。
- **输入**: input, norm_type, kernel_size
- **输出**: 降维后的张量
- **用途**: 更灵活的池化方式。
- **`adaptive_avg_pool1d` / `adaptive_avg_pool2d` / `adaptive_avg_pool3d`**: 自适应平均池化,输出固定大小。
- **输入**: input, output_size
- **输出**: 指定大小的张量
- **用途**: 适配不同输入尺寸的模型。
- **`adaptive_max_pool1d` / `adaptive_max_pool2d` / `adaptive_max_pool3d`**: 自适应最大池化。
- **输入/输出**: 类似自适应平均池化
- **用途**: 固定输出尺寸的特征提取。
---
### 3. 激活函数 (Non-linear Activations)
激活函数为神经网络引入非线性,增强表达能力。
- **`relu`**: ReLU 激活f(x) = max(0, x)。
- **输入**: 张量
- **输出**: 相同形状的张量
- **用途**: 常用激活函数,简单高效。
- **`relu6`**: ReLU 的变体,限制输出最大值为 6。
- **用途**: 移动设备模型,控制数值范围。
- **`elu`**: 指数线性单元f(x) = x if x > 0 else alpha * (exp(x) - 1)。
- **用途**: 缓解梯度消失问题。
- **`selu`**: 缩放指数线性单元,需配合特定初始化。
- **用途**: 自归一化网络。
- **`celu`**: 连续指数线性单元,平滑版 ELU。
- **用途**: 更平滑的非线性。
- **`leaky_relu`**: Leaky ReLUf(x) = x if x > 0 else negative_slope * x。
- **用途**: 允许负值梯度,缓解“死亡 ReLU”问题。
- **`prelu`**: 参数化的 ReLUnegative_slope 可学习。
- **用途**: 更灵活的激活。
- **`rrelu`**: 随机 ReLU负斜率在训练时随机。
- **用途**: 正则化,减少过拟合。
- **`glu`**: Gated Linear Unitf(x) = x[:half] * sigmoid(x[half:])。
- **用途**: 门控机制,语言模型常用。
- **`gelu`**: Gaussian Error Linear Unit近似 ReLU 和 Dropout 的组合。
- **用途**: Transformer 模型常用。
- **`sigmoid`**: Sigmoid 激活f(x) = 1 / (1 + exp(-x))。
- **用途**: 二分类输出。
- **`tanh`**: 双曲正切激活f(x) = tanh(x)。
- **用途**: 输出范围 [-1, 1] 的场景。
- **`softmax`**: Softmax 激活,归一化为概率分布。
- **输入**: 张量dim归一化维度
- **输出**: 概率分布
- **用途**: 多分类任务。
- **`log_softmax`**: Log-Softmax计算 softmax 的对数。
- **用途**: 数值稳定性,配合 NLLLoss 使用。
- **`softplus`**: f(x) = log(1 + exp(x)),平滑近似 ReLU。
- **用途**: 正输出场景。
- **`softsign`**: f(x) = x / (1 + |x|)。
- **用途**: 输出范围 [-1, 1],平滑激活。
- **`silu`**: SiLU (Sigmoid Linear Unit)f(x) = x * sigmoid(x)。
- **用途**: Transformer 模型。
- **`mish`**: f(x) = x * tanh(softplus(x))。
- **用途**: 现代网络的平滑激活。
- **`hardswish` / `hardsigmoid` / `hardtanh`**: 硬性激活函数,计算效率高。
- **用途**: 移动设备上的轻量模型。
- **`threshold`**: 阈值激活,小于阈值设为指定值。
- **用途**: 稀疏激活。
---
### 4. 归一化函数 (Normalization Functions)
归一化函数用于稳定训练,加速收敛。
- **`batch_norm`**: 批归一化,基于 mini-batch 统计归一化。
- **输入**: input, running_mean, running_var, weight, bias
- **输出**: 归一化后的张量
- **用途**: 加速训练,减少内部协变量偏移。
- **`instance_norm`**: 实例归一化,基于单个样本归一化。
- **用途**: 风格迁移、图像生成。
- **`layer_norm`**: 层归一化,基于特征维度归一化。
- **用途**: Transformer 和 RNN。
- **`group_norm`**: 组归一化,将通道分组归一化。
- **用途**: 小批量场景。
- **`local_response_norm`**: 局部响应归一化,基于邻域归一化。
- **用途**: 早期卷积网络(如 AlexNet
---
### 5. 线性函数 (Linear Functions)
- **`linear`**: 线性变换y = xW^T + b。
- **输入**: input, weight, bias
- **输出**: 变换后的张量
- **用途**: 全连接层。
- **`bilinear`**: 双线性变换y = x1^T W x2 + b。
- **用途**: 多输入特征交互。
---
### 6. 损失函数 (Loss Functions)
损失函数用于衡量模型预测与真实值之间的差异。
- **`mse_loss`**: 均方误差,适用于回归任务。
- **`l1_loss`**: L1 损失,绝对值误差。
- **`smooth_l1_loss`**: 平滑 L1 损失,结合 MSE 和 L1 的优点。
- **`kl_div`**: KL 散度,衡量分布差异。
- **`cross_entropy`**: 交叉熵损失,适用于分类任务。
- **`nll_loss`**: 负对数似然损失,常与 log_softmax 配合。
- **`hinge_loss`**: Hinge 损失,用于 SVM 式分类。
- **`margin_ranking_loss`**: 排序损失,用于排序任务。
- **`triplet_margin_loss`**: 三元组损失,用于嵌入学习。
- **`ctc_loss`**: 连接主义时序分类损失,用于序列任务。
- **`bce_loss` / `bce_with_logits_loss`**: 二元交叉熵,适用于二分类。
---
### 7. 注意力机制 (Attention Mechanisms)
- **`scaled_dot_product_attention`**: 缩放点积注意力Transformer 的核心组件。
- **输入**: query, key, value, attn_mask可选
- **输出**: 注意力加权后的值
- **用途**: Transformer 模型()。[](https://docs.pytorch.org/tutorials/deep-dive.html)
---
### 8. 其他函数
- **`dropout` / `dropout2d` / `dropout3d`**: Dropout 正则化,随机置零。
- **`embedding`**: 嵌入层,将索引映射为向量。
- **`one_hot`**: 独热编码,整数转独热向量。
- **`pad`**: 张量填充,用于调整尺寸。
- **`interpolate`**: 插值上采样或下采样。
- **`grid_sample`**: 网格采样,用于空间变换。
- **`affine_grid`**: 生成仿射变换的网格。
---
### 注意事项
1. **函数式 vs 模块化**:
- `torch.nn.functional` 提供无状态的函数式接口,适合在 `forward` 方法中调用。相比之下,`torch.nn` 的模块(如 `nn.Conv2d`)会管理参数(如权重和偏置),适合在 `__init__` 中定义()。[](https://discuss.pytorch.org/t/difference-of-methods-between-torch-nn-and-functional/1076)
- 例如,`F.relu` 不保存参数,而 `nn.ReLU` 是模块化的,性能上无明显差异()。[](https://discuss.pytorch.org/t/difference-of-methods-between-torch-nn-and-functional/1076)
2. **使用场景**:
- 卷积、池化、线性变换等常用于卷积神经网络CNN
- 注意力机制和归一化常用于 Transformer 模型。
- 损失函数根据任务类型(如分类、回归、排序)选择。
3. **文档更新**:
- 以上基于 PyTorch 2.8 文档(截至 2024 年 11 月。建议查看最新文档https://pytorch.org/docs/stable/nn.functional.html以获取新增功能或更新。[](https://docs.pytorch.org/docs/2.8/nn.functional.html)
---
### 示例代码
以下是一个简单的 CNN 前向传播示例,展示如何使用 `torch.nn.functional`
```python
import torch
import torch.nn.functional as F
# 输入张量 (batch_size=1, channels=1, height=28, width=28)
x = torch.randn(1, 1, 28, 28)
# 卷积核
weight = torch.randn(6, 1, 5, 5)
bias = torch.randn(6)
# 卷积 + ReLU + 最大池化
x = F.conv2d(x, weight, bias, stride=1, padding=2)
x = F.relu(x)
x = F.max_pool2d(x, kernel_size=2, stride=2)
print(x.shape) # 输出: torch.Size([1, 6, 14, 14])
```
---
如果您需要某类函数的详细讲解、特定方法的代码示例,或想深入某个功能(如注意力机制或损失函数),请告诉我,我可以进一步展开!
是的你的理解非常正确torch.nn.functional通常简写为 F中的方法是纯函数式接口它们只进行计算不管理或记录任何参数如权重或偏置。下面详细解答你的问题并澄清其与神经网络的关系。
1. torch.nn.functional 的本质
纯函数计算torch.nn.functional 提供的是无状态的函数,输入张量后直接执行特定操作(如卷积、激活、池化等),并返回结果。这些函数不会保存任何内部状态或参数。
例如F.conv2d(input, weight, bias) 需要显式传入 input、卷积核 weight 和偏置 bias如果有函数只负责计算卷积操作并返回结果。
不记录参数:与 torch.nn 模块(如 nn.Conv2d不同F 中的函数不会自动管理权重或偏置参数。这些参数需要由用户手动提供或通过其他机制(如 nn.Parameter管理。
与神经网络的关系:虽然 torch.nn.functional 本身不直接构成神经网络,但它提供了构建神经网络所需的核心计算操作。神经网络的实现通常结合 torch.nn.Module管理参数和层结构与 F 的函数(执行具体计算)。
2. torch.nn.functional vs torch.nn
为了更好理解,我们对比一下 torch.nn.functional 和 torch.nn 模块:
特性torch.nn.functionaltorch.nn (如 nn.Conv2d, nn.ReLU)类型函数式接口,无状态模块化接口,有状态参数管理不管理参数,需手动传入权重、偏置等自动管理参数(如权重和偏置)典型用途在 forward 方法中实现具体计算在 __init__ 中定义网络层灵活性更灵活适合自定义操作更封装适合标准网络结构示例F.conv2d(x, weight, bias)self.conv = nn.Conv2d(1, 6, 3)
例子:
使用 torch.nn.Conv2d
pythonimport torch
import torch.nn as nn
conv = nn.Conv2d(1, 6, 3) # 定义卷积层,自动管理 weight 和 bias
x = torch.randn(1, 1, 28, 28)
y = conv(x) # 直接调用,参数由模块管理
使用 torch.nn.functional
pythonimport torch.nn.functional as F
x = torch.randn(1, 1, 28, 28)
weight = torch.randn(6, 1, 3, 3) # 手动定义权重
bias = torch.randn(6) # 手动定义偏置
y = F.conv2d(x, weight, bias) # 显式传入参数
1. 为什么使用 torch.nn.functional
虽然 torch.nn 模块更方便(因为它封装了参数管理),但 F 的函数式接口在以下场景中更有优势:
自定义操作当需要自定义权重计算或动态调整参数时F 提供更大灵活性。例如,可以在每次前向传播中修改权重。
轻量级模型:在不需要持久化参数的场景(如某些实验性模型或推理阶段),直接使用 F 可以减少内存开销。
函数式编程:适合函数式编程风格,便于将操作组合成复杂的计算流程。
特殊场景:如实现自定义激活函数、池化操作,或在 Transformer 中实现注意力

View File

@@ -0,0 +1,359 @@
根据 PyTorch 官方文档(`torch.nn.ModuleList``torch.nn.ModuleDict`,基于 PyTorch 2.8),以下是对这两个类的详细讲解,包括它们的定义、作用以及所有方法的全面说明。`torch.nn.ModuleList``torch.nn.ModuleDict` 是 PyTorch 中用于管理子模块(`nn.Module` 实例)的容器类,类似于 Python 的 `list``dict`,但专为 PyTorch 的模块化设计优化。它们的主要作用是方便在 `nn.Module` 中组织和管理多个子模块,确保这些子模块被正确注册并参与前向传播、参数管理和设备迁移等操作。以下内容基于官方文档和其他可靠来源(如 PyTorch Forums 和 Stack Overflow确保准确且全面。
---
## 1. `torch.nn.ModuleList`
### 1.1 定义与作用
**官方定义**
```python
class torch.nn.ModuleList(modules=None)
```
- **作用**`torch.nn.ModuleList` 是一个容器类,用于以列表形式存储多个 `nn.Module` 实例(子模块)。它类似于 Python 的内置 `list`,但专为 PyTorch 的模块管理设计,存储的子模块会自动注册到父模块中,参与 `parameters()``named_parameters()`、设备迁移(如 `to(device)`)和前向传播。
- **特性**
- **自动注册**:当 `nn.ModuleList` 作为 `nn.Module` 的属性时,其中的子模块会自动被 `model.modules()``model.parameters()` 识别,而普通 Python 列表中的模块不会。
- **动态管理**:支持动态添加或移除子模块,适合需要变长模块列表的场景(如循环神经网络或变长层结构)。
- **用途**:常用于需要动态或顺序管理多个子模块的模型,例如堆叠多个线性层或卷积层。
- **参数**
- `modules`:一个可选的可迭代对象,包含初始的 `nn.Module` 实例。
**示例**
```python
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.ModuleList([nn.Linear(10, 10) for _ in range(3)])
def forward(self, x):
for layer in self.layers:
x = layer(x)
return x
model = MyModel()
print(list(model.modules())) # 输出模型及其子模块
print(list(model.parameters())) # 输出所有线性层的参数
```
### 1.2 方法讲解
`torch.nn.ModuleList` 支持以下方法,主要继承自 Python 的 `list`,并添加了 PyTorch 的模块管理特性。以下是所有方法的详细说明(基于官方文档和实际用法):
1. **`append(module)`**
- **作用**:向 `ModuleList` 末尾添加一个 `nn.Module` 实例。
- **参数**
- `module`:一个 `nn.Module` 实例。
- **返回值**`self``ModuleList` 本身,支持链式调用)。
- **示例**
```python
module_list = nn.ModuleList()
module_list.append(nn.Linear(10, 10))
print(len(module_list)) # 输出 1
print(isinstance(module_list[0], nn.Linear)) # 输出 True
```
- **注意**:添加的模块会自动注册到父模块的参数和模块列表中。
2. **`extend(modules)`**
- **作用**:将一个可迭代对象中的 `nn.Module` 实例追加到 `ModuleList` 末尾。
- **参数**
- `modules`:一个可迭代对象,包含 `nn.Module` 实例。
- **返回值**`self`。
- **示例**
```python
module_list = nn.ModuleList()
module_list.extend([nn.Linear(10, 10), nn.Linear(10, 5)])
print(len(module_list)) # 输出 2
```
- **注意**`extend` 比逐个 `append` 更高效,适合批量添加子模块。
- **Stack Overflow 示例**:合并两个 `ModuleList`
```python
module_list = nn.ModuleList()
module_list.extend(sub_list_1)
module_list.extend(sub_list_2)
# 或者
module_list = nn.ModuleList([*sub_list_1, *sub_list_2])
```
3. **索引操作(如 `__getitem__`, `__setitem__`**
- **作用**:支持像 Python 列表一样的索引访问和赋值操作。
- **参数**
- 索引(整数或切片)。
- **返回值**:指定索引处的 `nn.Module`。
- **示例**
```python
module_list = nn.ModuleList([nn.Linear(10, 10) for _ in range(3)])
print(module_list[0]) # 访问第一个线性层
module_list[0] = nn.Linear(10, 5) # 替换第一个模块
```
- **注意**:赋值时,新值必须是 `nn.Module` 实例。
4. **迭代操作(如 `__iter__`**
- **作用**:支持迭代,允许遍历 `ModuleList` 中的所有子模块。
- **返回值**:迭代器,逐个返回 `nn.Module`。
- **示例**
```python
for module in module_list:
print(module) # 打印每个子模块
```
5. **长度查询(如 `__len__`**
- **作用**:返回 `ModuleList` 中子模块的数量。
- **返回值**:整数。
- **示例**
```python
print(len(module_list)) # 输出子模块数量
```
6. **其他列表操作**
- `ModuleList` 支持 Python 列表的常见方法,如 `pop()`, `clear()`, `insert()`, `remove()` 等,但这些方法在官方文档中未明确列出(基于 Python 的 `list` 实现)。
- **示例**`pop`
```python
module_list = nn.ModuleList([nn.Linear(10, 10) for _ in range(3)])
removed_module = module_list.pop(0) # 移除并返回第一个模块
print(len(module_list)) # 输出 2
```
- **PyTorch Forums 讨论**:有用户询问如何动态移除 `ModuleList` 中的模块,可以使用 `pop(index)` 或重新构造列表:
```python
module_list = nn.ModuleList(module_list[:index] + module_list[index+1:])
```
### 1.3 注意事项
- **与普通 Python 列表的区别**:普通 Python 列表中的 `nn.Module` 不会自动注册到父模块的参数或模块列表中,而 `ModuleList` 会。
- **与 `nn.ParameterList` 的区别**`ModuleList` 存储 `nn.Module`(子模块),而 `nn.ParameterList` 存储 `nn.Parameter`(参数)。
- **动态性**`ModuleList` 适合动态模型(如变长层结构),但频繁操作可能影响性能。
- **优化器集成**`ModuleList` 中的子模块的参数会自动被 `model.parameters()` 包含,优化器会更新这些参数。
---
## 2. `torch.nn.ModuleDict`
### 2.1 定义与作用
**官方定义**
```python
class torch.nn.ModuleDict(modules=None)
```
- **作用**`torch.nn.ModuleDict` 是一个容器类,用于以字典形式存储多个 `nn.Module` 实例。类似于 Python 的内置 `dict`,但专为 PyTorch 的模块管理设计,存储的子模块会自动注册到父模块中。
- **特性**
- **键值存储**:使用字符串键索引子模块,便于按名称访问。
- **自动注册**:子模块会自动被 `model.modules()` 和 `model.parameters()` 识别。
- **用途**:适合需要按名称管理子模块的场景,例如多任务学习或具有语义化模块的复杂模型。
- **参数**
- `modules`:一个可选的可迭代对象,包含键值对(键为字符串,值为 `nn.Module` 实例)。
**示例**
```python
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.ModuleDict({
'layer1': nn.Linear(10, 10),
'layer2': nn.Linear(10, 5)
})
def forward(self, x):
x = self.layers['layer1'](x)
x = self.layers['layer2'](x)
return x
model = MyModel()
print(list(model.modules())) # 输出模型及其子模块
```
### 2.2 方法讲解
`torch.nn.ModuleDict` 支持以下方法,主要继承自 Python 的 `dict`,并添加了 PyTorch 的模块管理特性。以下是所有方法的详细说明:
1. **`__setitem__(key, module)`**
- **作用**:向 `ModuleDict` 添加或更新一个键值对。
- **参数**
- `key`:字符串,子模块的名称。
- `module``nn.Module` 实例。
- **示例**
```python
module_dict = nn.ModuleDict()
module_dict['layer1'] = nn.Linear(10, 10)
print(module_dict['layer1']) # 输出线性层
```
2. **`update([other])`**
- **作用**:使用另一个字典或键值对更新 `ModuleDict`。
- **参数**
- `other`:一个字典或键值对的可迭代对象,值必须是 `nn.Module`。
- **示例**
```python
module_dict = nn.ModuleDict()
module_dict.update({'layer1': nn.Linear(10, 10), 'layer2': nn.Linear(10, 5)})
print(len(module_dict)) # 输出 2
```
3. **索引操作(如 `__getitem__`**
- **作用**:通过键访问 `ModuleDict` 中的子模块。
- **参数**
- 键(字符串)。
- **返回值**:对应的 `nn.Module`。
- **示例**
```python
print(module_dict['layer1']) # 访问 layer1 模块
```
4. **迭代操作(如 `__iter__`, `keys()`, `values()`, `items()`**
- **作用**:支持迭代键、值或键值对。
- **返回值**
- `keys()`:返回所有键的迭代器。
- `values()`:返回所有 `nn.Module` 的迭代器。
- `items()`:返回键值对的迭代器。
- **示例**
```python
for key, module in module_dict.items():
print(f"Key: {key}, Module: {module}")
```
5. **长度查询(如 `__len__`**
- **作用**:返回 `ModuleDict` 中子模块的数量。
- **返回值**:整数。
- **示例**
```python
print(len(module_dict)) # 输出子模块数量
```
6. **其他字典操作**
- `ModuleDict` 支持 Python 字典的常见方法,如 `pop(key)`, `clear()`, `popitem()`, `get(key, default=None)` 等。
- **示例**`pop`
```python
module_dict = nn.ModuleDict({'layer1': nn.Linear(10, 10), 'layer2': nn.Linear(10, 5)})
removed_module = module_dict.pop('layer1') # 移除并返回 layer1
print(len(module_dict)) # 输出 1
```
### 2.3 注意事项
- **与普通 Python 字典的区别**:普通 Python 字典中的 `nn.Module` 不会自动注册到父模块,而 `ModuleDict` 会。
- **与 `nn.ParameterDict` 的区别**`ModuleDict` 存储 `nn.Module`,而 `nn.ParameterDict` 存储 `nn.Parameter`。
- **键的唯一性**`ModuleDict` 的键必须是字符串,且不能重复。
- **优化器集成**`ModuleDict` 中的子模块的参数会自动被 `model.parameters()` 包含。
---
## 3. 比较与使用场景
| 特性 | `ModuleList` | `ModuleDict` |
|---------------------|-------------------------------------------|-------------------------------------------|
| **存储方式** | 列表(按索引访问) | 字典(按键访问) |
| **访问方式** | 索引(`module_list[0]` | 键(`module_dict['key']` |
| **主要方法** | `append`, `extend`, `pop`, 索引操作 | `update`, `pop`, `keys`, `values`, `items` |
| **适用场景** | 顺序模块管理(如多层堆叠的神经网络) | 命名模块管理(如多任务模型中的模块) |
| **动态性** | 适合动态添加/移除模块 | 适合按名称管理模块 |
**选择建议**
- 如果子模块需要按顺序调用(如多层网络),使用 `ModuleList`。
- 如果子模块需要按名称访问或具有明确语义(如多任务模型),使用 `ModuleDict`。
---
## 4. 综合示例
以下是一个结合 `ModuleList` 和 `ModuleDict` 的示例,展示它们在模型中的使用:
```python
import torch
import torch.nn as nn
class ComplexModel(nn.Module):
def __init__(self):
super().__init__()
# 使用 ModuleList 存储一组线性层
self.list_layers = nn.ModuleList([nn.Linear(10, 10) for _ in range(2)])
# 使用 ModuleDict 存储命名模块
self.dict_layers = nn.ModuleDict({
'conv': nn.Conv2d(3, 64, kernel_size=3),
'fc': nn.Linear(10, 5)
})
def forward(self, x):
# 使用 ModuleList
for layer in self.list_layers:
x = layer(x)
# 使用 ModuleDict
x = self.dict_layers['fc'](x)
return x
model = ComplexModel()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 打印所有模块
for name, module in model.named_modules():
print(f"Module name: {name}, Module: {module}")
# 动态修改 ModuleList
model.list_layers.append(nn.Linear(10, 10))
# 动态修改 ModuleDict
model.dict_layers['new_fc'] = nn.Linear(5, 2)
```
---
## 5. 常见问题与解答
1. **如何高效合并两个 `ModuleList`**
- 使用 `extend` 方法或解包方式:
```python
module_list = nn.ModuleList()
module_list.extend(sub_list_1)
module_list.extend(sub_list_2)
# 或者
module_list = nn.ModuleList([*sub_list_1, *sub_list_2])
```
2. **如何从 `ModuleList` 删除模块?**
- 使用 `pop(index)` 或重新构造列表:
```python
module_list.pop(0) # 移除第一个模块
# 或者
module_list = nn.ModuleList([module for i, module in enumerate(module_list) if i != 0])
```
3. **如何检查 `ModuleDict` 中的模块?**
- 使用 `keys()`, `values()`, 或 `items()` 遍历:
```python
for key, module in module_dict.items():
print(f"Key: {key}, Module: {module}")
```
4. **如何初始化子模块的参数?**
- 使用 `nn.Module.apply` 或直接遍历:
```python
def init_weights(m):
if isinstance(m, nn.Linear):
nn.init.xavier_uniform_(m.weight)
model.apply(init_weights)
# 或者
for module in module_list:
if isinstance(module, nn.Linear):
nn.init.xavier_uniform_(module.weight)
```
---
## 6. 总结
- **`torch.nn.ModuleList`**
- 方法:`append`, `extend`, `pop`, 索引/迭代操作。
- 特点:类似列表,适合顺序管理子模块,自动注册到父模块。
- 场景:动态模型、多层堆叠网络。
- **`torch.nn.ModuleDict`**
- 方法:`update`, `pop`, `keys`, `values`, `items`, 索引/迭代操作。
- 特点:类似字典,适合按名称管理子模块,自动注册。
- 场景:多任务学习、需要语义化命名的模型。
**参考文献**
- PyTorch 官方文档:`torch.nn.ModuleList` 和 `torch.nn.ModuleDict``docs.pytorch.org`
- Stack Overflow合并 `ModuleList` 的讨论
- PyTorch Forums`ModuleList` 和 `ModuleDict` 的动态操作
如果需要更详细的代码示例、特定方法的实现,或其他相关问题(如与优化器或设备迁移的集成),请告诉我!

View File

@@ -0,0 +1,359 @@
根据 PyTorch 官方文档(`torch.nn.ModuleList``torch.nn.ModuleDict`,基于 PyTorch 2.8),以下是对这两个类的详细讲解,包括它们的定义、作用以及所有方法的全面说明。`torch.nn.ModuleList``torch.nn.ModuleDict` 是 PyTorch 中用于管理子模块(`nn.Module` 实例)的容器类,类似于 Python 的 `list``dict`,但专为 PyTorch 的模块化设计优化。它们的主要作用是方便在 `nn.Module` 中组织和管理多个子模块,确保这些子模块被正确注册并参与前向传播、参数管理和设备迁移等操作。以下内容基于官方文档和其他可靠来源(如 PyTorch Forums 和 Stack Overflow确保准确且全面。
---
## 1. `torch.nn.ModuleList`
### 1.1 定义与作用
**官方定义**
```python
class torch.nn.ModuleList(modules=None)
```
- **作用**`torch.nn.ModuleList` 是一个容器类,用于以列表形式存储多个 `nn.Module` 实例(子模块)。它类似于 Python 的内置 `list`,但专为 PyTorch 的模块管理设计,存储的子模块会自动注册到父模块中,参与 `parameters()``named_parameters()`、设备迁移(如 `to(device)`)和前向传播。
- **特性**
- **自动注册**:当 `nn.ModuleList` 作为 `nn.Module` 的属性时,其中的子模块会自动被 `model.modules()``model.parameters()` 识别,而普通 Python 列表中的模块不会。
- **动态管理**:支持动态添加或移除子模块,适合需要变长模块列表的场景(如循环神经网络或变长层结构)。
- **用途**:常用于需要动态或顺序管理多个子模块的模型,例如堆叠多个线性层或卷积层。
- **参数**
- `modules`:一个可选的可迭代对象,包含初始的 `nn.Module` 实例。
**示例**
```python
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.ModuleList([nn.Linear(10, 10) for _ in range(3)])
def forward(self, x):
for layer in self.layers:
x = layer(x)
return x
model = MyModel()
print(list(model.modules())) # 输出模型及其子模块
print(list(model.parameters())) # 输出所有线性层的参数
```
### 1.2 方法讲解
`torch.nn.ModuleList` 支持以下方法,主要继承自 Python 的 `list`,并添加了 PyTorch 的模块管理特性。以下是所有方法的详细说明(基于官方文档和实际用法):
1. **`append(module)`**
- **作用**:向 `ModuleList` 末尾添加一个 `nn.Module` 实例。
- **参数**
- `module`:一个 `nn.Module` 实例。
- **返回值**`self``ModuleList` 本身,支持链式调用)。
- **示例**
```python
module_list = nn.ModuleList()
module_list.append(nn.Linear(10, 10))
print(len(module_list)) # 输出 1
print(isinstance(module_list[0], nn.Linear)) # 输出 True
```
- **注意**:添加的模块会自动注册到父模块的参数和模块列表中。
2. **`extend(modules)`**
- **作用**:将一个可迭代对象中的 `nn.Module` 实例追加到 `ModuleList` 末尾。
- **参数**
- `modules`:一个可迭代对象,包含 `nn.Module` 实例。
- **返回值**`self`。
- **示例**
```python
module_list = nn.ModuleList()
module_list.extend([nn.Linear(10, 10), nn.Linear(10, 5)])
print(len(module_list)) # 输出 2
```
- **注意**`extend` 比逐个 `append` 更高效,适合批量添加子模块。
- **Stack Overflow 示例**:合并两个 `ModuleList`
```python
module_list = nn.ModuleList()
module_list.extend(sub_list_1)
module_list.extend(sub_list_2)
# 或者
module_list = nn.ModuleList([*sub_list_1, *sub_list_2])
```
3. **索引操作(如 `__getitem__`, `__setitem__`**
- **作用**:支持像 Python 列表一样的索引访问和赋值操作。
- **参数**
- 索引(整数或切片)。
- **返回值**:指定索引处的 `nn.Module`。
- **示例**
```python
module_list = nn.ModuleList([nn.Linear(10, 10) for _ in range(3)])
print(module_list[0]) # 访问第一个线性层
module_list[0] = nn.Linear(10, 5) # 替换第一个模块
```
- **注意**:赋值时,新值必须是 `nn.Module` 实例。
4. **迭代操作(如 `__iter__`**
- **作用**:支持迭代,允许遍历 `ModuleList` 中的所有子模块。
- **返回值**:迭代器,逐个返回 `nn.Module`。
- **示例**
```python
for module in module_list:
print(module) # 打印每个子模块
```
5. **长度查询(如 `__len__`**
- **作用**:返回 `ModuleList` 中子模块的数量。
- **返回值**:整数。
- **示例**
```python
print(len(module_list)) # 输出子模块数量
```
6. **其他列表操作**
- `ModuleList` 支持 Python 列表的常见方法,如 `pop()`, `clear()`, `insert()`, `remove()` 等,但这些方法在官方文档中未明确列出(基于 Python 的 `list` 实现)。
- **示例**`pop`
```python
module_list = nn.ModuleList([nn.Linear(10, 10) for _ in range(3)])
removed_module = module_list.pop(0) # 移除并返回第一个模块
print(len(module_list)) # 输出 2
```
- **PyTorch Forums 讨论**:有用户询问如何动态移除 `ModuleList` 中的模块,可以使用 `pop(index)` 或重新构造列表:
```python
module_list = nn.ModuleList(module_list[:index] + module_list[index+1:])
```
### 1.3 注意事项
- **与普通 Python 列表的区别**:普通 Python 列表中的 `nn.Module` 不会自动注册到父模块的参数或模块列表中,而 `ModuleList` 会。
- **与 `nn.ParameterList` 的区别**`ModuleList` 存储 `nn.Module`(子模块),而 `nn.ParameterList` 存储 `nn.Parameter`(参数)。
- **动态性**`ModuleList` 适合动态模型(如变长层结构),但频繁操作可能影响性能。
- **优化器集成**`ModuleList` 中的子模块的参数会自动被 `model.parameters()` 包含,优化器会更新这些参数。
---
## 2. `torch.nn.ModuleDict`
### 2.1 定义与作用
**官方定义**
```python
class torch.nn.ModuleDict(modules=None)
```
- **作用**`torch.nn.ModuleDict` 是一个容器类,用于以字典形式存储多个 `nn.Module` 实例。类似于 Python 的内置 `dict`,但专为 PyTorch 的模块管理设计,存储的子模块会自动注册到父模块中。
- **特性**
- **键值存储**:使用字符串键索引子模块,便于按名称访问。
- **自动注册**:子模块会自动被 `model.modules()` 和 `model.parameters()` 识别。
- **用途**:适合需要按名称管理子模块的场景,例如多任务学习或具有语义化模块的复杂模型。
- **参数**
- `modules`:一个可选的可迭代对象,包含键值对(键为字符串,值为 `nn.Module` 实例)。
**示例**
```python
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.layers = nn.ModuleDict({
'layer1': nn.Linear(10, 10),
'layer2': nn.Linear(10, 5)
})
def forward(self, x):
x = self.layers['layer1'](x)
x = self.layers['layer2'](x)
return x
model = MyModel()
print(list(model.modules())) # 输出模型及其子模块
```
### 2.2 方法讲解
`torch.nn.ModuleDict` 支持以下方法,主要继承自 Python 的 `dict`,并添加了 PyTorch 的模块管理特性。以下是所有方法的详细说明:
1. **`__setitem__(key, module)`**
- **作用**:向 `ModuleDict` 添加或更新一个键值对。
- **参数**
- `key`:字符串,子模块的名称。
- `module``nn.Module` 实例。
- **示例**
```python
module_dict = nn.ModuleDict()
module_dict['layer1'] = nn.Linear(10, 10)
print(module_dict['layer1']) # 输出线性层
```
2. **`update([other])`**
- **作用**:使用另一个字典或键值对更新 `ModuleDict`。
- **参数**
- `other`:一个字典或键值对的可迭代对象,值必须是 `nn.Module`。
- **示例**
```python
module_dict = nn.ModuleDict()
module_dict.update({'layer1': nn.Linear(10, 10), 'layer2': nn.Linear(10, 5)})
print(len(module_dict)) # 输出 2
```
3. **索引操作(如 `__getitem__`**
- **作用**:通过键访问 `ModuleDict` 中的子模块。
- **参数**
- 键(字符串)。
- **返回值**:对应的 `nn.Module`。
- **示例**
```python
print(module_dict['layer1']) # 访问 layer1 模块
```
4. **迭代操作(如 `__iter__`, `keys()`, `values()`, `items()`**
- **作用**:支持迭代键、值或键值对。
- **返回值**
- `keys()`:返回所有键的迭代器。
- `values()`:返回所有 `nn.Module` 的迭代器。
- `items()`:返回键值对的迭代器。
- **示例**
```python
for key, module in module_dict.items():
print(f"Key: {key}, Module: {module}")
```
5. **长度查询(如 `__len__`**
- **作用**:返回 `ModuleDict` 中子模块的数量。
- **返回值**:整数。
- **示例**
```python
print(len(module_dict)) # 输出子模块数量
```
6. **其他字典操作**
- `ModuleDict` 支持 Python 字典的常见方法,如 `pop(key)`, `clear()`, `popitem()`, `get(key, default=None)` 等。
- **示例**`pop`
```python
module_dict = nn.ModuleDict({'layer1': nn.Linear(10, 10), 'layer2': nn.Linear(10, 5)})
removed_module = module_dict.pop('layer1') # 移除并返回 layer1
print(len(module_dict)) # 输出 1
```
### 2.3 注意事项
- **与普通 Python 字典的区别**:普通 Python 字典中的 `nn.Module` 不会自动注册到父模块,而 `ModuleDict` 会。
- **与 `nn.ParameterDict` 的区别**`ModuleDict` 存储 `nn.Module`,而 `nn.ParameterDict` 存储 `nn.Parameter`。
- **键的唯一性**`ModuleDict` 的键必须是字符串,且不能重复。
- **优化器集成**`ModuleDict` 中的子模块的参数会自动被 `model.parameters()` 包含。
---
## 3. 比较与使用场景
| 特性 | `ModuleList` | `ModuleDict` |
|---------------------|-------------------------------------------|-------------------------------------------|
| **存储方式** | 列表(按索引访问) | 字典(按键访问) |
| **访问方式** | 索引(`module_list[0]` | 键(`module_dict['key']` |
| **主要方法** | `append`, `extend`, `pop`, 索引操作 | `update`, `pop`, `keys`, `values`, `items` |
| **适用场景** | 顺序模块管理(如多层堆叠的神经网络) | 命名模块管理(如多任务模型中的模块) |
| **动态性** | 适合动态添加/移除模块 | 适合按名称管理模块 |
**选择建议**
- 如果子模块需要按顺序调用(如多层网络),使用 `ModuleList`。
- 如果子模块需要按名称访问或具有明确语义(如多任务模型),使用 `ModuleDict`。
---
## 4. 综合示例
以下是一个结合 `ModuleList` 和 `ModuleDict` 的示例,展示它们在模型中的使用:
```python
import torch
import torch.nn as nn
class ComplexModel(nn.Module):
def __init__(self):
super().__init__()
# 使用 ModuleList 存储一组线性层
self.list_layers = nn.ModuleList([nn.Linear(10, 10) for _ in range(2)])
# 使用 ModuleDict 存储命名模块
self.dict_layers = nn.ModuleDict({
'conv': nn.Conv2d(3, 64, kernel_size=3),
'fc': nn.Linear(10, 5)
})
def forward(self, x):
# 使用 ModuleList
for layer in self.list_layers:
x = layer(x)
# 使用 ModuleDict
x = self.dict_layers['fc'](x)
return x
model = ComplexModel()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 打印所有模块
for name, module in model.named_modules():
print(f"Module name: {name}, Module: {module}")
# 动态修改 ModuleList
model.list_layers.append(nn.Linear(10, 10))
# 动态修改 ModuleDict
model.dict_layers['new_fc'] = nn.Linear(5, 2)
```
---
## 5. 常见问题与解答
1. **如何高效合并两个 `ModuleList`**
- 使用 `extend` 方法或解包方式:
```python
module_list = nn.ModuleList()
module_list.extend(sub_list_1)
module_list.extend(sub_list_2)
# 或者
module_list = nn.ModuleList([*sub_list_1, *sub_list_2])
```
2. **如何从 `ModuleList` 删除模块?**
- 使用 `pop(index)` 或重新构造列表:
```python
module_list.pop(0) # 移除第一个模块
# 或者
module_list = nn.ModuleList([module for i, module in enumerate(module_list) if i != 0])
```
3. **如何检查 `ModuleDict` 中的模块?**
- 使用 `keys()`, `values()`, 或 `items()` 遍历:
```python
for key, module in module_dict.items():
print(f"Key: {key}, Module: {module}")
```
4. **如何初始化子模块的参数?**
- 使用 `nn.Module.apply` 或直接遍历:
```python
def init_weights(m):
if isinstance(m, nn.Linear):
nn.init.xavier_uniform_(m.weight)
model.apply(init_weights)
# 或者
for module in module_list:
if isinstance(module, nn.Linear):
nn.init.xavier_uniform_(module.weight)
```
---
## 6. 总结
- **`torch.nn.ModuleList`**
- 方法:`append`, `extend`, `pop`, 索引/迭代操作。
- 特点:类似列表,适合顺序管理子模块,自动注册到父模块。
- 场景:动态模型、多层堆叠网络。
- **`torch.nn.ModuleDict`**
- 方法:`update`, `pop`, `keys`, `values`, `items`, 索引/迭代操作。
- 特点:类似字典,适合按名称管理子模块,自动注册。
- 场景:多任务学习、需要语义化命名的模型。
**参考文献**
- PyTorch 官方文档:`torch.nn.ModuleList` 和 `torch.nn.ModuleDict``docs.pytorch.org`
- Stack Overflow合并 `ModuleList` 的讨论
- PyTorch Forums`ModuleList` 和 `ModuleDict` 的动态操作
如果需要更详细的代码示例、特定方法的实现,或其他相关问题(如与优化器或设备迁移的集成),请告诉我!

View File

@@ -0,0 +1,225 @@
根据 PyTorch 官方文档,`torch.nn.Parameter` 是一个类,继承自 `torch.Tensor`,主要用于表示神经网络模型中的可训练参数。它本身并没有定义许多独立的方法,而是继承了 `torch.Tensor` 的大部分方法,同时具备一些特殊属性,用于与 `torch.nn.Module` 配合管理模型参数。以下是对 `torch.nn.Parameter` 的详细讲解,包括其作用、特性以及与参数管理相关的方法,基于官方文档和其他可靠来源。
---
### 1. `torch.nn.Parameter` 的定义与作用
**官方定义**
```python
class torch.nn.parameter.Parameter(data=None, requires_grad=True)
```
- **作用**`torch.nn.Parameter` 是一种特殊的 `torch.Tensor`,用于表示神经网络模型的可训练参数。当它被赋值给 `torch.nn.Module` 的属性时,会自动注册到模块的参数列表中(通过 `parameters()``named_parameters()` 方法访问),并参与梯度计算和优化。
- **特性**
- **自动注册**:当 `nn.Parameter` 实例被赋值给 `nn.Module` 的属性时,它会自动添加到模块的 `parameters()` 迭代器中,而普通 `torch.Tensor` 不会。
- **默认梯度**`requires_grad` 默认值为 `True`,表示参数需要计算梯度,即使在 `torch.no_grad()` 上下文中也是如此。
- **用途**:常用于定义模型的可训练权重、偏置,或其他需要优化的参数(如 Vision Transformer 中的 positional embedding 或 class token
**参数说明**
- `data`:一个 `torch.Tensor`,表示参数的初始值。
- `requires_grad`:布尔值,指示是否需要计算梯度,默认 `True`
**示例**
```python
import torch
import torch.nn as nn
# 创建一个 Parameter
param = nn.Parameter(torch.randn(3, 3))
print(param) # 输出 Parameter 类型的张量requires_grad=True
# 定义一个简单的模型
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
self.weight = nn.Parameter(torch.randn(3, 3))
def forward(self, x):
return torch.matmul(x, self.weight)
model = MyModel()
print(list(model.parameters())) # 包含 self.weight
```
---
### 2. `torch.nn.Parameter` 的方法
`torch.nn.Parameter` 本身没有定义额外的方法,它继承了 `torch.Tensor` 的所有方法,并通过与 `nn.Module` 的交互提供参数管理的功能。以下是与 `nn.Parameter` 相关的核心方法(主要通过 `nn.Module` 访问)以及 `torch.Tensor` 的常用方法在 `nn.Parameter` 上的应用:
#### 2.1 通过 `nn.Module` 访问 `nn.Parameter` 的方法
这些方法是 `torch.nn.Module` 提供的,用于管理 `nn.Parameter` 实例:
1. **`parameters()`**
- **作用**:返回模型中所有 `nn.Parameter` 实例的迭代器。
- **返回值**`Iterator[Parameter]`,包含所有参数的张量。
- **示例**
```python
for param in model.parameters():
print(param.shape) # 打印每个参数的形状
```
2. **`named_parameters()`**
- **作用**:返回一个迭代器,包含模型中所有 `nn.Parameter` 的名称和对应的参数张量。
- **返回值**`Iterator[Tuple[str, Parameter]]`,每个元素是参数名称和参数的元组。
- **示例**
```python
for name, param in model.named_parameters():
print(f"Parameter name: {name}, Shape: {param.shape}")
```
3. **`_parameters`**
- **作用**`nn.Module` 的属性,是一个 `OrderedDict`,存储模块中直接定义的 `nn.Parameter` 实例。
- **示例**
```python
print(model._parameters) # 输出 OrderedDict包含 weight 参数
```
4. **`apply(fn)`**
- **作用**:递归地将函数 `fn` 应用于模块及其子模块的所有参数,常用于参数初始化。
- **示例**
```python
def init_weights(m):
if isinstance(m, nn.Linear):
m.weight.data.fill_(1.0)
model.apply(init_weights) # 初始化所有参数
```
5. **`cpu()` / `cuda(device_id=None)`**
- **作用**:将所有参数(包括 `nn.Parameter`)移动到 CPU 或指定的 GPU 设备。
- **示例**
```python
model.cuda() # 将模型参数移动到 GPU
```
6. **`to(device)`**
- **作用**将参数移动到指定设备CPU 或 GPU支持更灵活的设备管理。
- **示例**
```python
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
```
7. **`double()` / `float()` / `half()`**
- **作用**:将所有参数转换为指定的数据类型(如双精度、单精度或半精度)。
- **示例**
```python
model.double() # 转换为双精度
```
#### 2.2 继承自 `torch.Tensor` 的方法
`nn.Parameter` 是 `torch.Tensor` 的子类,因此可以使用 `torch.Tensor` 的所有方法。以下是一些常用的方法,特别适用于参数操作:
1. **张量操作**
- `add_()`, `mul_()`, `div_()` 等:原地修改参数值。
- `zero_()`:将参数值置零,常用于重置梯度或参数。
- **示例**
```python
param = nn.Parameter(torch.randn(3, 3))
param.zero_() # 将参数置零
```
2. **梯度相关**
- `grad`:访问参数的梯度(一个 `torch.Tensor`)。
- `zero_grad()`:通过优化器调用,清除参数的梯度。
- **示例**
```python
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
optimizer.zero_grad() # 清除所有参数的梯度
```
3. **形状操作**
- `view()`, `reshape()`:改变参数的形状。
- **示例**
```python
param = nn.Parameter(torch.randn(3, 3))
reshaped_param = param.view(9) # 展平为 1D 张量
```
4. **数学运算**
- `sum()`, `mean()`, `std()` 等:对参数值进行统计计算。
- **示例**
```python
print(param.mean()) # 计算参数的均值
```
5. **克隆与分离**
- `clone()`:创建参数的副本。
- `detach()`:分离参数,创建一个不需要梯度的新张量。
- **示例**
```python
param_clone = param.clone() # 复制参数
param_detached = param.detach() # 分离requires_grad=False
```
#### 2.3 与优化器交互
`nn.Parameter` 的主要用途是与优化器(如 `torch.optim.SGD` 或 `Adam`)一起使用。优化器通过 `model.parameters()` 获取所有 `nn.Parameter` 实例,并更新它们的值。
**示例**
```python
import torch.optim as optim
model = MyModel()
optimizer = optim.SGD(model.parameters(), lr=0.01)
loss_fn = nn.MSELoss()
# 前向传播
x = torch.randn(1, 3)
y = torch.randn(1, 3)
out = model(x)
loss = loss_fn(out, y)
# 反向传播与优化
optimizer.zero_grad()
loss.backward()
optimizer.step() # 更新所有 nn.Parameter
```
---
### 3. 注意事项与常见问题
1. **与普通 Tensor 的区别**
- 普通 `torch.Tensor` 即使设置 `requires_grad=True`,也不会自动添加到 `nn.Module` 的参数列表中。
- `nn.Parameter` 默认 `requires_grad=True`,且会自动注册为模型参数。
2. **初始化参数**
- 可以使用 `torch.nn.init` 模块初始化 `nn.Parameter`。
- **示例**
```python
import torch.nn.init as init
param = nn.Parameter(torch.randn(3, 3))
init.xavier_uniform_(param) # 使用 Xavier 初始化
```
3. **临时状态 vs 参数**
- 如果需要在模型中存储临时状态(如 RNN 的隐藏状态),应使用普通 `torch.Tensor` 或 `nn.Module.register_buffer()`,避免注册为可训练参数。
4. **Vision Transformer 示例**
- 在 Vision Transformer 中,`nn.Parameter` 常用于定义可学习的 `cls_token` 和 `pos_embedding`
```python
class ViT(nn.Module):
def __init__(self, num_patches, dim):
super(ViT, self).__init__()
self.cls_token = nn.Parameter(torch.randn(1, 1, dim))
self.pos_embedding = nn.Parameter(torch.randn(1, num_patches + 1, dim))
```
---
### 4. 总结
`torch.nn.Parameter` 本身没有定义独特的方法,但通过继承 `torch.Tensor` 和与 `nn.Module` 的交互,提供了强大的参数管理功能。核心方法(如 `parameters()`、`named_parameters()`)通过 `nn.Module` 访问,而 `torch.Tensor` 的方法(如 `zero_()`、`view()`)直接应用于 `nn.Parameter` 实例。以下是关键点:
- **自动注册**:赋值给 `nn.Module` 属性时,自动加入参数列表。
- **梯度计算**:默认 `requires_grad=True`,支持优化。
- **灵活操作**:继承 `torch.Tensor` 的所有方法,适用于张量操作。
**参考文献**
- PyTorch 官方文档:`torch.nn.Parameter`[](https://docs.pytorch.org/docs/stable/generated/torch.nn.parameter.Parameter.html)[](https://docs.pytorch.ac.cn/docs/stable/generated/torch.nn.parameter.Parameter.html)
- 极客教程:理解 `torch.nn.Parameter`[](https://geek-docs.com/pytorch/pytorch-questions/21_pytorch_understanding_torchnnparameter.html)
- CSDN 博客:`torch.nn.Parameter` 讲解[](https://blog.csdn.net/weixin_44878336/article/details/124733598)[](https://blog.csdn.net/weixin_44966641/article/details/118730730)
如果需要更详细的代码示例或特定方法的应用场景,请告诉我!

View File

@@ -0,0 +1,359 @@
根据 PyTorch 官方文档(`torch.nn.ParameterList``torch.nn.ParameterDict` 的相关内容),以下是对这两个类的详细讲解,包括它们的定义、作用以及所有方法的全面说明。由于 `torch.nn.ParameterList``torch.nn.ParameterDict` 是专门用于管理 `torch.nn.Parameter` 的容器类,它们的方法相对较少,主要继承自 Python 的列表和字典操作,并与 PyTorch 的模块机制结合使用。以下内容基于官方文档(`PyTorch 2.8`)和其他可靠来源(如 PyTorch Forums 和 Stack Overflow确保准确且全面。
---
## 1. `torch.nn.ParameterList`
### 1.1 定义与作用
**官方定义**
```python
class torch.nn.ParameterList(values=None)
```
- **作用**`torch.nn.ParameterList` 是一个容器类,用于以列表的形式存储 `torch.nn.Parameter` 实例。它类似于 Python 的内置 `list`,但专为 PyTorch 的参数管理设计,存储的 `nn.Parameter` 会被自动注册到 `nn.Module` 的参数列表中,参与梯度计算和优化。
- **特性**
- **自动注册**:当 `nn.ParameterList` 作为 `nn.Module` 的属性时,其中的所有 `nn.Parameter` 会自动被 `model.parameters()` 识别。
- **Tensor 自动转换**:在构造、赋值、`append()``extend()` 时,传入的普通 `torch.Tensor` 会自动转换为 `nn.Parameter`
- **用途**:适用于需要动态管理一组参数的场景,例如在循环网络或变长模型中存储多个权重矩阵。
- **参数**
- `values`:一个可选的可迭代对象,包含初始的 `nn.Parameter``torch.Tensor`
**示例**
```python
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.params = nn.ParameterList([nn.Parameter(torch.randn(2, 2)) for _ in range(3)])
def forward(self, x):
for param in self.params:
x = x @ param # 矩阵乘法
return x
model = MyModel()
print(list(model.parameters())) # 输出 3 个 (2, 2) 的参数张量
```
### 1.2 方法讲解
`torch.nn.ParameterList` 支持以下方法,主要继承自 Python 的 `list`,并添加了 PyTorch 的参数管理特性。以下是所有方法的详细说明(基于官方文档和实际用法):
1. **`append(value)`**
- **作用**:向 `ParameterList` 末尾添加一个值。如果 `value``torch.Tensor`,会自动转换为 `nn.Parameter`
- **参数**
- `value`:要添加的元素(可以是 `nn.Parameter``torch.Tensor`)。
- **返回值**`self``ParameterList` 本身,支持链式调用)。
- **示例**
```python
param_list = nn.ParameterList()
param_list.append(torch.randn(2, 2)) # 自动转换为 nn.Parameter
print(len(param_list)) # 输出 1
print(isinstance(param_list[0], nn.Parameter)) # 输出 True
```
- **注意**:添加的 `nn.Parameter` 会自动注册到模块的参数列表中。
2. **`extend(values)`**
- **作用**:将一个可迭代对象中的值追加到 `ParameterList` 末尾。所有 `torch.Tensor` 会被转换为 `nn.Parameter`。
- **参数**
- `values`:一个可迭代对象,包含 `nn.Parameter` 或 `torch.Tensor`。
- **返回值**`self`。
- **示例**
```python
param_list = nn.ParameterList()
param_list.extend([torch.randn(2, 2), torch.randn(2, 2)])
print(len(param_list)) # 输出 2
```
- **注意**`extend` 比逐个 `append` 更高效,适合批量添加参数。
- **Stack Overflow 示例**:可以使用 `extend` 合并两个 `ParameterList`
```python
plist = nn.ParameterList()
plist.extend(sub_list_1)
plist.extend(sub_list_2)
```
或者使用解包方式:
```python
param_list = nn.ParameterList([*sub_list_1, *sub_list_2])
```
3. **索引操作(如 `__getitem__`, `__setitem__`**
- **作用**:支持像 Python 列表一样的索引访问和赋值操作。
- **参数**
- 索引(整数或切片)。
- **返回值**:指定索引处的 `nn.Parameter`。
- **示例**
```python
param_list = nn.ParameterList([nn.Parameter(torch.randn(2, 2)) for _ in range(3)])
print(param_list[0]) # 访问第一个参数
param_list[0] = nn.Parameter(torch.ones(2, 2)) # 替换第一个参数
```
- **注意**:赋值时,新值必须是 `nn.Parameter` 或 `torch.Tensor`(后者会自动转换为 `nn.Parameter`)。
4. **迭代操作(如 `__iter__`**
- **作用**:支持迭代,允许遍历 `ParameterList` 中的所有参数。
- **返回值**:迭代器,逐个返回 `nn.Parameter`。
- **示例**
```python
for param in param_list:
print(param.shape) # 打印每个参数的形状
```
5. **长度查询(如 `__len__`**
- **作用**:返回 `ParameterList` 中参数的数量。
- **返回值**:整数。
- **示例**
```python
print(len(param_list)) # 输出参数数量
```
6. **其他列表操作**
- `ParameterList` 支持 Python 列表的常见方法,如 `pop()`, `clear()`, `insert()`, `remove()` 等,但这些方法在官方文档中未明确列出(基于 Python 的 `list` 实现)。
- **示例**`pop`
```python
param_list = nn.ParameterList([nn.Parameter(torch.randn(2, 2)) for _ in range(3)])
removed_param = param_list.pop(0) # 移除并返回第一个参数
print(len(param_list)) # 输出 2
```
- **PyTorch Forums 讨论**:有用户询问如何在运行时移除 `ParameterList` 中的元素,可以使用 `pop(index)` 或重新构造列表:
```python
param_list = nn.ParameterList(param_list[:index] + param_list[index+1:])
```
### 1.3 注意事项
- **与 `nn.ModuleList` 的区别**`ParameterList` 存储 `nn.Parameter`,用于参数管理;`nn.ModuleList` 存储 `nn.Module`,用于子模块管理。
- **自动转换**:任何添加到 `ParameterList` 的 `torch.Tensor` 都会被转换为 `nn.Parameter`,确保参数可被优化器识别。
- **动态性**`ParameterList` 适合动态模型(如变长序列模型),但操作频繁可能影响性能。
- **优化器集成**`ParameterList` 中的参数会自动被 `model.parameters()` 包含,优化器会更新这些参数。
---
## 2. `torch.nn.ParameterDict`
### 2.1 定义与作用
**官方定义**
```python
class torch.nn.ParameterDict(parameters=None)
```
- **作用**`torch.nn.ParameterDict` 是一个容器类,用于以字典的形式存储 `torch.nn.Parameter` 实例。它类似于 Python 的内置 `dict`,但专为 PyTorch 参数管理设计,存储的 `nn.Parameter` 会自动注册到 `nn.Module` 的参数列表中。
- **特性**
- **键值存储**:使用字符串键来索引参数,便于按名称访问。
- **自动注册**:与 `ParameterList` 类似,`ParameterDict` 中的参数会被 `model.parameters()` 识别。
- **Tensor 自动转换**:赋值时,`torch.Tensor` 会被转换为 `nn.Parameter`。
- **用途**:适用于需要按名称管理参数的场景,例如在多任务学习或复杂模型中。
- **参数**
- `parameters`:一个可选的可迭代对象,包含键值对(键为字符串,值为 `nn.Parameter` 或 `torch.Tensor`)。
**示例**
```python
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.params = nn.ParameterDict({
'weight1': nn.Parameter(torch.randn(2, 2)),
'weight2': nn.Parameter(torch.randn(2, 2))
})
def forward(self, x):
x = x @ self.params['weight1']
x = x @ self.params['weight2']
return x
model = MyModel()
print(list(model.parameters())) # 输出 2 个 (2, 2) 的参数张量
```
### 2.2 方法讲解
`torch.nn.ParameterDict` 支持以下方法,主要继承自 Python 的 `dict`,并添加了 PyTorch 的参数管理特性。以下是所有方法的详细说明:
1. **`__setitem__(key, value)`**
- **作用**:向 `ParameterDict` 添加或更新一个键值对。如果 `value` 是 `torch.Tensor`,会自动转换为 `nn.Parameter`。
- **参数**
- `key`:字符串,参数的名称。
- `value``nn.Parameter` 或 `torch.Tensor`。
- **示例**
```python
param_dict = nn.ParameterDict()
param_dict['weight'] = torch.randn(2, 2) # 自动转换为 nn.Parameter
print(param_dict['weight']) # 输出 nn.Parameter
```
2. **`update([other])`**
- **作用**:使用另一个字典或键值对更新 `ParameterDict`。输入的 `torch.Tensor` 会被转换为 `nn.Parameter`。
- **参数**
- `other`:一个字典或键值对的可迭代对象。
- **示例**
```python
param_dict = nn.ParameterDict()
param_dict.update({'weight1': torch.randn(2, 2), 'weight2': torch.randn(2, 2)})
print(len(param_dict)) # 输出 2
```
3. **索引操作(如 `__getitem__`**
- **作用**:通过键访问 `ParameterDict` 中的 `nn.Parameter`。
- **参数**
- 键(字符串)。
- **返回值**:对应的 `nn.Parameter`。
- **示例**
```python
print(param_dict['weight1']) # 访问 weight1 参数
```
4. **迭代操作(如 `__iter__`, `keys()`, `values()`, `items()`**
- **作用**:支持迭代键、值或键值对。
- **返回值**
- `keys()`:返回所有键的迭代器。
- `values()`:返回所有 `nn.Parameter` 的迭代器。
- `items()`:返回键值对的迭代器。
- **示例**
```python
for key, param in param_dict.items():
print(f"Key: {key}, Shape: {param.shape}")
```
5. **长度查询(如 `__len__`**
- **作用**:返回 `ParameterDict` 中参数的数量。
- **返回值**:整数。
- **示例**
```python
print(len(param_dict)) # 输出参数数量
```
6. **其他字典操作**
- `ParameterDict` 支持 Python 字典的常见方法,如 `pop(key)`, `clear()`, `popitem()`, `get(key, default=None)` 等。
- **示例**`pop`
```python
param_dict = nn.ParameterDict({'weight1': torch.randn(2, 2), 'weight2': torch.randn(2, 2)})
removed_param = param_dict.pop('weight1') # 移除并返回 weight1
print(len(param_dict)) # 输出 1
```
### 2.3 注意事项
- **与 `nn.ModuleDict` 的区别**`ParameterDict` 存储 `nn.Parameter`,用于参数管理;`nn.ModuleDict` 存储 `nn.Module`,用于子模块管理。
- **键的唯一性**`ParameterDict` 的键必须是字符串,且不能重复。
- **动态管理**:适合需要按名称访问参数的场景,但操作复杂模型时需注意性能开销。
- **优化器集成**`ParameterDict` 中的参数也会被 `model.parameters()` 包含,优化器会自动更新。
---
## 3. 比较与使用场景
| 特性 | `ParameterList` | `ParameterDict` |
|---------------------|--------------------------------------------|--------------------------------------------|
| **存储方式** | 列表(按索引访问) | 字典(按键访问) |
| **访问方式** | 索引(`param_list[0]` | 键(`param_dict['key']` |
| **主要方法** | `append`, `extend`, `pop`, 索引操作 | `update`, `pop`, `keys`, `values`, `items` |
| **适用场景** | 顺序参数管理(如循环网络中的多层权重) | 命名参数管理(如多任务模型中的权重) |
| **动态性** | 适合动态添加/移除参数 | 适合按名称管理参数 |
**选择建议**
- 如果参数需要按顺序访问或动态增减,使用 `ParameterList`。
- 如果需要按名称管理参数或参数具有明确语义,使用 `ParameterDict`。
---
## 4. 综合示例
以下是一个结合 `ParameterList` 和 `ParameterDict` 的示例,展示它们在模型中的使用:
```python
import torch
import torch.nn as nn
class ComplexModel(nn.Module):
def __init__(self):
super().__init__()
# 使用 ParameterList 存储一组权重
self.list_params = nn.ParameterList([nn.Parameter(torch.randn(2, 2)) for _ in range(2)])
# 使用 ParameterDict 存储命名参数
self.dict_params = nn.ParameterDict({
'conv_weight': nn.Parameter(torch.randn(3, 3)),
'fc_weight': nn.Parameter(torch.randn(4, 4))
})
def forward(self, x):
# 使用 ParameterList
for param in self.list_params:
x = x @ param
# 使用 ParameterDict
x = x @ self.dict_params['conv_weight']
x = x @ self.dict_params['fc_weight']
return x
model = ComplexModel()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 打印所有参数
for name, param in model.named_parameters():
print(f"Parameter name: {name}, Shape: {param.shape}")
# 动态修改 ParameterList
model.list_params.append(nn.Parameter(torch.ones(2, 2)))
# 动态修改 ParameterDict
model.dict_params['new_weight'] = nn.Parameter(torch.zeros(4, 4))
```
---
## 5. 常见问题与解答
1. **如何高效合并两个 `ParameterList`**
- 使用 `extend` 方法或解包方式:
```python
param_list = nn.ParameterList()
param_list.extend(sub_list_1)
param_list.extend(sub_list_2)
# 或者
param_list = nn.ParameterList([*sub_list_1, *sub_list_2])
```
2. **如何从 `ParameterList` 删除元素?**
- 使用 `pop(index)` 或重新构造列表:
```python
param_list.pop(0) # 移除第一个参数
# 或者
param_list = nn.ParameterList([param for i, param in enumerate(param_list) if i != 0])
```
3. **如何检查 `ParameterDict` 中的参数?**
- 使用 `keys()`, `values()`, 或 `items()` 遍历:
```python
for key, param in param_dict.items():
print(f"Key: {key}, Parameter: {param}")
```
4. **如何初始化参数?**
- 使用 `torch.nn.init` 或通过 `nn.Module.apply`
```python
import torch.nn.init as init
for param in param_list:
init.xavier_uniform_(param)
for param in param_dict.values():
init.xavier_uniform_(param)
```
---
## 6. 总结
- **`torch.nn.ParameterList`**
- 方法:`append`, `extend`, `pop`, 索引/迭代操作。
- 特点:类似列表,适合顺序管理参数,自动将 `torch.Tensor` 转换为 `nn.Parameter`。
- 场景:动态模型、变长参数列表。
- **`torch.nn.ParameterDict`**
- 方法:`update`, `pop`, `keys`, `values`, `items`, 索引/迭代操作。
- 特点:类似字典,适合按名称管理参数,自动转换 `torch.Tensor`。
- 场景:多任务学习、需要语义化命名的模型。
**参考文献**
- PyTorch 官方文档:`torch.nn.ParameterList` 和 `torch.nn.ParameterDict``docs.pytorch.org`[](https://docs.pytorch.org/docs/stable/generated/torch.nn.ParameterList.html)[](https://docs.pytorch.org/docs/stable/nn.html)
- Stack Overflow合并 `ParameterList` 的讨论[](https://stackoverflow.com/questions/70779631/combining-parameterlist-in-pytorch)
- PyTorch Forums`ParameterList` 的使用和动态操作[](https://discuss.pytorch.org/t/using-nn-parameterlist/86742)
如果需要更详细的代码示例、特定方法的实现,或其他相关问题(如与优化器的集成),请告诉我!

View File

@@ -0,0 +1,359 @@
根据 PyTorch 官方文档(`torch.nn.ParameterList``torch.nn.ParameterDict` 的相关内容),以下是对这两个类的详细讲解,包括它们的定义、作用以及所有方法的全面说明。由于 `torch.nn.ParameterList``torch.nn.ParameterDict` 是专门用于管理 `torch.nn.Parameter` 的容器类,它们的方法相对较少,主要继承自 Python 的列表和字典操作,并与 PyTorch 的模块机制结合使用。以下内容基于官方文档(`PyTorch 2.8`)和其他可靠来源(如 PyTorch Forums 和 Stack Overflow确保准确且全面。
---
## 1. `torch.nn.ParameterList`
### 1.1 定义与作用
**官方定义**
```python
class torch.nn.ParameterList(values=None)
```
- **作用**`torch.nn.ParameterList` 是一个容器类,用于以列表的形式存储 `torch.nn.Parameter` 实例。它类似于 Python 的内置 `list`,但专为 PyTorch 的参数管理设计,存储的 `nn.Parameter` 会被自动注册到 `nn.Module` 的参数列表中,参与梯度计算和优化。
- **特性**
- **自动注册**:当 `nn.ParameterList` 作为 `nn.Module` 的属性时,其中的所有 `nn.Parameter` 会自动被 `model.parameters()` 识别。
- **Tensor 自动转换**:在构造、赋值、`append()``extend()` 时,传入的普通 `torch.Tensor` 会自动转换为 `nn.Parameter`
- **用途**:适用于需要动态管理一组参数的场景,例如在循环网络或变长模型中存储多个权重矩阵。
- **参数**
- `values`:一个可选的可迭代对象,包含初始的 `nn.Parameter``torch.Tensor`
**示例**
```python
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.params = nn.ParameterList([nn.Parameter(torch.randn(2, 2)) for _ in range(3)])
def forward(self, x):
for param in self.params:
x = x @ param # 矩阵乘法
return x
model = MyModel()
print(list(model.parameters())) # 输出 3 个 (2, 2) 的参数张量
```
### 1.2 方法讲解
`torch.nn.ParameterList` 支持以下方法,主要继承自 Python 的 `list`,并添加了 PyTorch 的参数管理特性。以下是所有方法的详细说明(基于官方文档和实际用法):
1. **`append(value)`**
- **作用**:向 `ParameterList` 末尾添加一个值。如果 `value``torch.Tensor`,会自动转换为 `nn.Parameter`
- **参数**
- `value`:要添加的元素(可以是 `nn.Parameter``torch.Tensor`)。
- **返回值**`self``ParameterList` 本身,支持链式调用)。
- **示例**
```python
param_list = nn.ParameterList()
param_list.append(torch.randn(2, 2)) # 自动转换为 nn.Parameter
print(len(param_list)) # 输出 1
print(isinstance(param_list[0], nn.Parameter)) # 输出 True
```
- **注意**:添加的 `nn.Parameter` 会自动注册到模块的参数列表中。
2. **`extend(values)`**
- **作用**:将一个可迭代对象中的值追加到 `ParameterList` 末尾。所有 `torch.Tensor` 会被转换为 `nn.Parameter`。
- **参数**
- `values`:一个可迭代对象,包含 `nn.Parameter` 或 `torch.Tensor`。
- **返回值**`self`。
- **示例**
```python
param_list = nn.ParameterList()
param_list.extend([torch.randn(2, 2), torch.randn(2, 2)])
print(len(param_list)) # 输出 2
```
- **注意**`extend` 比逐个 `append` 更高效,适合批量添加参数。
- **Stack Overflow 示例**:可以使用 `extend` 合并两个 `ParameterList`
```python
plist = nn.ParameterList()
plist.extend(sub_list_1)
plist.extend(sub_list_2)
```
或者使用解包方式:
```python
param_list = nn.ParameterList([*sub_list_1, *sub_list_2])
```
3. **索引操作(如 `__getitem__`, `__setitem__`**
- **作用**:支持像 Python 列表一样的索引访问和赋值操作。
- **参数**
- 索引(整数或切片)。
- **返回值**:指定索引处的 `nn.Parameter`。
- **示例**
```python
param_list = nn.ParameterList([nn.Parameter(torch.randn(2, 2)) for _ in range(3)])
print(param_list[0]) # 访问第一个参数
param_list[0] = nn.Parameter(torch.ones(2, 2)) # 替换第一个参数
```
- **注意**:赋值时,新值必须是 `nn.Parameter` 或 `torch.Tensor`(后者会自动转换为 `nn.Parameter`)。
4. **迭代操作(如 `__iter__`**
- **作用**:支持迭代,允许遍历 `ParameterList` 中的所有参数。
- **返回值**:迭代器,逐个返回 `nn.Parameter`。
- **示例**
```python
for param in param_list:
print(param.shape) # 打印每个参数的形状
```
5. **长度查询(如 `__len__`**
- **作用**:返回 `ParameterList` 中参数的数量。
- **返回值**:整数。
- **示例**
```python
print(len(param_list)) # 输出参数数量
```
6. **其他列表操作**
- `ParameterList` 支持 Python 列表的常见方法,如 `pop()`, `clear()`, `insert()`, `remove()` 等,但这些方法在官方文档中未明确列出(基于 Python 的 `list` 实现)。
- **示例**`pop`
```python
param_list = nn.ParameterList([nn.Parameter(torch.randn(2, 2)) for _ in range(3)])
removed_param = param_list.pop(0) # 移除并返回第一个参数
print(len(param_list)) # 输出 2
```
- **PyTorch Forums 讨论**:有用户询问如何在运行时移除 `ParameterList` 中的元素,可以使用 `pop(index)` 或重新构造列表:
```python
param_list = nn.ParameterList(param_list[:index] + param_list[index+1:])
```
### 1.3 注意事项
- **与 `nn.ModuleList` 的区别**`ParameterList` 存储 `nn.Parameter`,用于参数管理;`nn.ModuleList` 存储 `nn.Module`,用于子模块管理。
- **自动转换**:任何添加到 `ParameterList` 的 `torch.Tensor` 都会被转换为 `nn.Parameter`,确保参数可被优化器识别。
- **动态性**`ParameterList` 适合动态模型(如变长序列模型),但操作频繁可能影响性能。
- **优化器集成**`ParameterList` 中的参数会自动被 `model.parameters()` 包含,优化器会更新这些参数。
---
## 2. `torch.nn.ParameterDict`
### 2.1 定义与作用
**官方定义**
```python
class torch.nn.ParameterDict(parameters=None)
```
- **作用**`torch.nn.ParameterDict` 是一个容器类,用于以字典的形式存储 `torch.nn.Parameter` 实例。它类似于 Python 的内置 `dict`,但专为 PyTorch 参数管理设计,存储的 `nn.Parameter` 会自动注册到 `nn.Module` 的参数列表中。
- **特性**
- **键值存储**:使用字符串键来索引参数,便于按名称访问。
- **自动注册**:与 `ParameterList` 类似,`ParameterDict` 中的参数会被 `model.parameters()` 识别。
- **Tensor 自动转换**:赋值时,`torch.Tensor` 会被转换为 `nn.Parameter`。
- **用途**:适用于需要按名称管理参数的场景,例如在多任务学习或复杂模型中。
- **参数**
- `parameters`:一个可选的可迭代对象,包含键值对(键为字符串,值为 `nn.Parameter` 或 `torch.Tensor`)。
**示例**
```python
class MyModel(nn.Module):
def __init__(self):
super().__init__()
self.params = nn.ParameterDict({
'weight1': nn.Parameter(torch.randn(2, 2)),
'weight2': nn.Parameter(torch.randn(2, 2))
})
def forward(self, x):
x = x @ self.params['weight1']
x = x @ self.params['weight2']
return x
model = MyModel()
print(list(model.parameters())) # 输出 2 个 (2, 2) 的参数张量
```
### 2.2 方法讲解
`torch.nn.ParameterDict` 支持以下方法,主要继承自 Python 的 `dict`,并添加了 PyTorch 的参数管理特性。以下是所有方法的详细说明:
1. **`__setitem__(key, value)`**
- **作用**:向 `ParameterDict` 添加或更新一个键值对。如果 `value` 是 `torch.Tensor`,会自动转换为 `nn.Parameter`。
- **参数**
- `key`:字符串,参数的名称。
- `value``nn.Parameter` 或 `torch.Tensor`。
- **示例**
```python
param_dict = nn.ParameterDict()
param_dict['weight'] = torch.randn(2, 2) # 自动转换为 nn.Parameter
print(param_dict['weight']) # 输出 nn.Parameter
```
2. **`update([other])`**
- **作用**:使用另一个字典或键值对更新 `ParameterDict`。输入的 `torch.Tensor` 会被转换为 `nn.Parameter`。
- **参数**
- `other`:一个字典或键值对的可迭代对象。
- **示例**
```python
param_dict = nn.ParameterDict()
param_dict.update({'weight1': torch.randn(2, 2), 'weight2': torch.randn(2, 2)})
print(len(param_dict)) # 输出 2
```
3. **索引操作(如 `__getitem__`**
- **作用**:通过键访问 `ParameterDict` 中的 `nn.Parameter`。
- **参数**
- 键(字符串)。
- **返回值**:对应的 `nn.Parameter`。
- **示例**
```python
print(param_dict['weight1']) # 访问 weight1 参数
```
4. **迭代操作(如 `__iter__`, `keys()`, `values()`, `items()`**
- **作用**:支持迭代键、值或键值对。
- **返回值**
- `keys()`:返回所有键的迭代器。
- `values()`:返回所有 `nn.Parameter` 的迭代器。
- `items()`:返回键值对的迭代器。
- **示例**
```python
for key, param in param_dict.items():
print(f"Key: {key}, Shape: {param.shape}")
```
5. **长度查询(如 `__len__`**
- **作用**:返回 `ParameterDict` 中参数的数量。
- **返回值**:整数。
- **示例**
```python
print(len(param_dict)) # 输出参数数量
```
6. **其他字典操作**
- `ParameterDict` 支持 Python 字典的常见方法,如 `pop(key)`, `clear()`, `popitem()`, `get(key, default=None)` 等。
- **示例**`pop`
```python
param_dict = nn.ParameterDict({'weight1': torch.randn(2, 2), 'weight2': torch.randn(2, 2)})
removed_param = param_dict.pop('weight1') # 移除并返回 weight1
print(len(param_dict)) # 输出 1
```
### 2.3 注意事项
- **与 `nn.ModuleDict` 的区别**`ParameterDict` 存储 `nn.Parameter`,用于参数管理;`nn.ModuleDict` 存储 `nn.Module`,用于子模块管理。
- **键的唯一性**`ParameterDict` 的键必须是字符串,且不能重复。
- **动态管理**:适合需要按名称访问参数的场景,但操作复杂模型时需注意性能开销。
- **优化器集成**`ParameterDict` 中的参数也会被 `model.parameters()` 包含,优化器会自动更新。
---
## 3. 比较与使用场景
| 特性 | `ParameterList` | `ParameterDict` |
|---------------------|--------------------------------------------|--------------------------------------------|
| **存储方式** | 列表(按索引访问) | 字典(按键访问) |
| **访问方式** | 索引(`param_list[0]` | 键(`param_dict['key']` |
| **主要方法** | `append`, `extend`, `pop`, 索引操作 | `update`, `pop`, `keys`, `values`, `items` |
| **适用场景** | 顺序参数管理(如循环网络中的多层权重) | 命名参数管理(如多任务模型中的权重) |
| **动态性** | 适合动态添加/移除参数 | 适合按名称管理参数 |
**选择建议**
- 如果参数需要按顺序访问或动态增减,使用 `ParameterList`。
- 如果需要按名称管理参数或参数具有明确语义,使用 `ParameterDict`。
---
## 4. 综合示例
以下是一个结合 `ParameterList` 和 `ParameterDict` 的示例,展示它们在模型中的使用:
```python
import torch
import torch.nn as nn
class ComplexModel(nn.Module):
def __init__(self):
super().__init__()
# 使用 ParameterList 存储一组权重
self.list_params = nn.ParameterList([nn.Parameter(torch.randn(2, 2)) for _ in range(2)])
# 使用 ParameterDict 存储命名参数
self.dict_params = nn.ParameterDict({
'conv_weight': nn.Parameter(torch.randn(3, 3)),
'fc_weight': nn.Parameter(torch.randn(4, 4))
})
def forward(self, x):
# 使用 ParameterList
for param in self.list_params:
x = x @ param
# 使用 ParameterDict
x = x @ self.dict_params['conv_weight']
x = x @ self.dict_params['fc_weight']
return x
model = ComplexModel()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 打印所有参数
for name, param in model.named_parameters():
print(f"Parameter name: {name}, Shape: {param.shape}")
# 动态修改 ParameterList
model.list_params.append(nn.Parameter(torch.ones(2, 2)))
# 动态修改 ParameterDict
model.dict_params['new_weight'] = nn.Parameter(torch.zeros(4, 4))
```
---
## 5. 常见问题与解答
1. **如何高效合并两个 `ParameterList`**
- 使用 `extend` 方法或解包方式:
```python
param_list = nn.ParameterList()
param_list.extend(sub_list_1)
param_list.extend(sub_list_2)
# 或者
param_list = nn.ParameterList([*sub_list_1, *sub_list_2])
```
2. **如何从 `ParameterList` 删除元素?**
- 使用 `pop(index)` 或重新构造列表:
```python
param_list.pop(0) # 移除第一个参数
# 或者
param_list = nn.ParameterList([param for i, param in enumerate(param_list) if i != 0])
```
3. **如何检查 `ParameterDict` 中的参数?**
- 使用 `keys()`, `values()`, 或 `items()` 遍历:
```python
for key, param in param_dict.items():
print(f"Key: {key}, Parameter: {param}")
```
4. **如何初始化参数?**
- 使用 `torch.nn.init` 或通过 `nn.Module.apply`
```python
import torch.nn.init as init
for param in param_list:
init.xavier_uniform_(param)
for param in param_dict.values():
init.xavier_uniform_(param)
```
---
## 6. 总结
- **`torch.nn.ParameterList`**
- 方法:`append`, `extend`, `pop`, 索引/迭代操作。
- 特点:类似列表,适合顺序管理参数,自动将 `torch.Tensor` 转换为 `nn.Parameter`。
- 场景:动态模型、变长参数列表。
- **`torch.nn.ParameterDict`**
- 方法:`update`, `pop`, `keys`, `values`, `items`, 索引/迭代操作。
- 特点:类似字典,适合按名称管理参数,自动转换 `torch.Tensor`。
- 场景:多任务学习、需要语义化命名的模型。
**参考文献**
- PyTorch 官方文档:`torch.nn.ParameterList` 和 `torch.nn.ParameterDict``docs.pytorch.org`[](https://docs.pytorch.org/docs/stable/generated/torch.nn.ParameterList.html)[](https://docs.pytorch.org/docs/stable/nn.html)
- Stack Overflow合并 `ParameterList` 的讨论[](https://stackoverflow.com/questions/70779631/combining-parameterlist-in-pytorch)
- PyTorch Forums`ParameterList` 的使用和动态操作[](https://discuss.pytorch.org/t/using-nn-parameterlist/86742)
如果需要更详细的代码示例、特定方法的实现,或其他相关问题(如与优化器的集成),请告诉我!

View File

View File

@@ -0,0 +1,161 @@
### `torch.nn.Conv2d` 类的方法详解
根据 PyTorch 官方文档(`torch.nn.Conv2d`),这是一个实现二维卷积的模块,广泛用于处理图像数据,执行卷积操作 \( y = W * x + b \),其中 \( * \) 表示卷积操作,\( W \) 是卷积核(权重),\( b \) 是偏置(如果启用)。该类继承自 `nn.Module`,因此除了特定方法外,还支持 `nn.Module` 的通用方法(如 `train()``eval()` 等)。文档中明确提到了一些方法,主要包括 `__init__``forward``extra_repr`,此外还涉及权重初始化和一些内部方法(如 `_conv_forward`)。以下详细讲解所有相关方法,基于官方文档和实现逻辑。
以下是每个方法的签名、参数、返回值和详细解释。参数类型基于 Python 标准类型和 PyTorch 张量规范。
---
#### 1. `__init__` 方法(初始化方法)
- **签名**
```python
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros', device=None, dtype=None)
```
- **参数**
- `in_channels`int输入张量的通道数如 RGB 图像为 3
- `out_channels`int输出张量的通道数卷积核数量
- `kernel_size`int 或 tuple卷积核大小单个数如 3 表示 3x3或元组如 (3, 3))。
- `stride`int 或 tuple默认 1卷积步幅控制卷积核移动的步长。
- `padding`int、tuple 或 str默认 0输入的填充量可为单个数、元组或字符串如 'valid' 或 'same',但 'same' 需手动计算)。
- `dilation`int 或 tuple默认 1卷积核元素间距膨胀卷积用于增大感受野。
- `groups`int默认 1分组卷积设置控制输入和输出通道的分组连接。
- `bias`bool默认 True是否添加可学习的偏置。
- `padding_mode`str默认 'zeros'):填充模式,支持 'zeros'、'reflect'、'replicate' 或 'circular'。
- `device`torch.device 或 None默认 None模块的设备CPU 或 GPU
- `dtype`torch.dtype 或 None默认 None模块的数据类型。
- **返回值**:无(构造函数,初始化模块)。
- **解释**
初始化二维卷积层,创建权重张量(形状为 `(out_channels, in_channels/groups, kernel_height, kernel_width)`)和可选的偏置张量(形状为 `(out_channels,)`)。权重使用均匀分布 \(\mathcal{U}(-\sqrt{k}, \sqrt{k})\) 初始化,其中 \( k = \frac{\text{groups}}{\text{in_channels} \cdot \prod \text{kernel_size}} \)。该方法定义了卷积操作的参数,是构建 CNN 的核心。例如,`nn.Conv2d(3, 64, 3)` 创建一个从 3 通道输入到 64 通道输出的 3x3 卷积层。
- **注意**
- 分组卷积(`groups > 1`)将输入和输出通道分组,降低计算量。
- `padding_mode` 影响边界处理,'zeros' 是最常用的。
- 支持 TensorFloat32 加速在支持的硬件上float16 输入可能在某些设备上转为 float32。
---
#### 2. `forward` 方法(前向传播方法)
- **签名**
```python
forward(input)
```
- **参数**
- `input`torch.Tensor输入张量形状为 `(N, C_in, H_in, W_in)`,其中 \( N \) 是批量大小,\( C_in \) 是输入通道数,\( H_in, W_in \) 是输入的高度和宽度。
- **返回值**
torch.Tensor形状为 `(N, C_out, H_out, W_out)`,其中 \( C_out = \text{out_channels} \),输出尺寸 \( H_out, W_out \) 由公式计算:
\[
H_out = \left\lfloor \frac{H_in + 2 \cdot \text{padding}[0] - \text{dilation}[0] \cdot (\text{kernel_size}[0] - 1) - 1}{\text{stride}[0]} \right\rfloor + 1
\]
\[
W_out = \left\lfloor \frac{W_in + 2 \cdot \text{padding}[1] - \text{dilation}[1] \cdot (\text{kernel_size}[1] - 1) - 1}{\text{stride}[1]} \right\rfloor + 1
\]
- **解释**
执行二维卷积操作,对输入张量应用卷积核和偏置(如果启用)。内部调用 F.conv2dPyTorch 的函数式卷积接口),结合权重、偏置和初始化时指定的参数(如步幅、填充等)。这是模型前向传播的核心,隐式调用如 `output = layer(input)`。
**示例**(来自文档):
```python
import torch
import torch.nn as nn
m = nn.Conv2d(16, 33, 3, stride=2) # 16 通道输入33 通道输出3x3 核,步幅 2
input = torch.randn(20, 16, 50, 100) # 批量 2016 通道50x100 尺寸
output = m(input) # 输出形状: (20, 33, 24, 49)(根据公式计算)
```
- **注意**
输入的通道数必须等于 `in_channels`,否则会报错。输出尺寸由卷积参数决定,需仔细检查以避免维度不匹配。
---
#### 3. `extra_repr` 方法(额外字符串表示方法)
- **签名**
```python
extra_repr()
```
- **参数**:无。
- **返回值**str描述模块参数的字符串。
- **解释**
返回一个字符串,表示模块的关键参数,用于增强模块的打印表示。例如,打印 `Conv2d` 层时会显示类似:
```python
Conv2d(16, 33, kernel_size=(3, 3), stride=(2, 2), padding=(0, 0), bias=True)
```
包括 `in_channels`、`out_channels`、`kernel_size`、`stride`、`padding` 等信息。用于调试和模型结构可视化,继承自 `nn.Module` 并在 `Conv2d` 中覆盖以显示特定参数。
- **注意**:此方法不影响计算,仅用于信息展示。
---
#### 4. `_conv_forward` 方法(内部前向传播方法)
- **签名**(推测,文档未明确列出签名):
```python
_conv_forward(input, weight, bias)
```
- **参数**
- `input`torch.Tensor输入张量形状同 `forward` 的输入。
- `weight`torch.Tensor卷积核权重形状为 `(out_channels, in_channels/groups, kernel_height, kernel_width)`。
- `bias`torch.Tensor 或 None偏置张量形状为 `(out_channels,)` 或 None若 `bias=False`)。
- **返回值**
torch.Tensor卷积操作的结果形状同 `forward` 的输出。
- **解释**
这是 `forward` 方法的内部实现,调用 `torch.nn.functional.conv2d` 执行实际的卷积计算。参数包括输入、权重、偏置,以及初始化时设置的 `stride`、`padding`、`dilation`、`groups` 和 `padding_mode`。文档中未直接列出此方法为公共接口,但它是 `forward` 的核心逻辑,公开在实现中以支持自定义扩展。
- **注意**
通常用户无需直接调用此方法,除非需要自定义卷积逻辑(如修改权重或偏置的处理方式)。
---
#### 5. `reset_parameters` 方法(重置参数方法)
- **签名**
```python
reset_parameters()
```
- **参数**:无。
- **返回值**:无。
- **解释**
重置模块的权重和偏置(如果启用)。权重使用均匀分布 \(\mathcal{U}(-\sqrt{k}, \sqrt{k})\) 初始化,其中 \( k = \frac{\text{groups}}{\text{in_channels} \cdot \prod \text{kernel_size}} \)。偏置(若存在)也使用相同分布初始化。此方法在需要重新初始化模型参数时调用,例如在训练实验中重置网络。
- **注意**
调用此方法会覆盖现有参数,需谨慎使用。
---
### 附加说明
- **继承方法**
作为 `nn.Module` 的子类,`Conv2d` 支持所有通用方法,例如:
- `parameters()`:返回可训练参数(权重和偏置)。
- `named_parameters()`:返回带名称的参数。
- `zero_grad()`:清零梯度。
- `to(device)`:移动模块到指定设备。
这些方法非 `Conv2d` 独有,但常用于模型训练和调试。
- **属性**
- `weight`nn.Parameter卷积核权重张量。
- `bias`nn.Parameter 或 None偏置张量若 `bias=True`)。
- 其他属性(如 `stride`、`padding`)存储初始化时的参数。
- **使用提示**
- 输入张量必须是 4D批量、通道、高、宽否则会报错。
- 输出尺寸需根据公式计算,调试时可用 `torch.nn.functional.conv2d` 的文档验证。
- 分组卷积和膨胀卷积是高级特性,需理解其对计算量和感受野的影响。
- `padding_mode` 影响边界处理,'circular' 等模式在特定任务(如周期性数据)中有用。
- **版本相关**
文档未提及特定版本差异,但 PyTorch 2.x 系列优化了卷积性能(如 TensorFloat32 支持。float16 在某些设备(如 ROCm上会转为 float32 计算。
---
### 示例代码(综合应用)
```python
import torch
import torch.nn as nn
# 初始化 Conv2d 层
conv = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=1, padding=1, bias=True)
# 创建输入张量 (批量=1, 通道=3, 高=32, 宽=32)
input = torch.randn(1, 3, 32, 32)
# 前向传播
output = conv(input)
print(output.shape) # 输出: torch.Size([1, 64, 32, 32])(因 padding=1 保持尺寸)
# 查看模块信息
print(conv) # 调用 extra_repr显示参数
# 重置参数
conv.reset_parameters()
```
---
如果需要更详细的数学推导、特定参数组合的示例,或其他 `nn.Module` 方法的讲解,请告诉我!

View File

@@ -0,0 +1,47 @@
### torch.nn.Linear 类的方法详解
根据 PyTorch 官方文档torch.nn.Linear这是一个实现线性变换全连接层的模块数学公式为 \( y = xA^T + b \),其中 \( A \) 是权重矩阵,\( b \) 是偏置(如果启用)。该类继承自 `nn.Module`,因此除了特定方法外,还支持 `nn.Module` 的通用方法(如 `train()``eval()` 等),但这里重点讲解文档中明确提到的所有方法,包括 `__init__``forward``extra_repr`。文档中未提及其他特定方法。
以下是每个方法的详细讲解,包括方法签名、参数、返回值和解释。参数类型基于 Python 标准类型和 PyTorch 张量规范。
#### 1. `__init__` 方法(初始化方法)
- **签名**`torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)`
- **参数**
- `in_features`int每个输入样本的大小输入特征维度
- `out_features`int每个输出样本的大小输出特征维度
- `bias`bool默认 True如果为 `False`,则不学习可加偏置项。
- `device`torch.device 或 None默认 None指定模块的设备如 CPU 或 GPU
- `dtype`torch.dtype 或 None默认 None指定模块的数据类型。
- **返回值**:无(这是构造函数,用于初始化模块)。
- **解释**:该方法初始化线性变换模块。它会创建权重矩阵 \( A \)(形状为 `(out_features, in_features)`)和可选的偏置 \( b \)(形状为 `(out_features,)`)。权重和偏置使用均匀分布 \(\mathcal{U}(-\sqrt{k}, \sqrt{k})\) 初始化,其中 \( k = \frac{1}{\text{in_features}} \)。这是一个核心方法,用于构建层,例如 `nn.Linear(20, 30)` 创建一个从 20 维输入到 30 维输出的层。
- **注意**:模块支持 TensorFloat32在支持的硬件上加速并且在某些 ROCm 设备上float16 输入会转换为 float32 进行计算。
#### 2. `forward` 方法(前向传播方法)
- **签名**`forward(input)`(输入参数名为 `input`,但文档中未显式列出签名,通常推断自描述)。
- **参数**
- `input`torch.Tensor输入张量形状为 `(*, H_in)`,其中 `*` 表示任意数量的维度(包括无维度),`H_in = in_features`(最后一个维度必须匹配 `in_features`)。
- **返回值**torch.Tensor形状为 `(*, H_out)`,其中前面的维度与输入相同,`H_out = out_features`
- **解释**:这是模块的核心前向传播方法。它对输入应用线性变换 \( y = xA^T + b \)(如果 `bias=True`)。权重 \( A \) 和偏置 \( b \) 是可学习的参数,通过反向传播更新。该方法是 PyTorch 模块的标准接口,在模型构建中调用如 `output = layer(input)` 时隐式执行。
- **示例**(来自官方文档):
```python
import torch.nn as nn
m = nn.Linear(20, 30) # 初始化层
input = torch.randn(128, 20) # 批量大小 128特征 20
output = m(input) # 前向传播
print(output.size()) # 输出: torch.Size([128, 30])
```
这展示了批量输入如何转换为输出形状。
#### 3. `extra_repr` 方法(额外字符串表示方法)
- **签名**`extra_repr()`(无参数,继承自 `nn.Module`)。
- **参数**:无。
- **返回值**str一个字符串总结模块的参数。
- **解释**:该方法返回一个字符串,用于增强模块的打印表示(例如,当你 `print(layer)` 时)。它通常包括 `in_features`、`out_features` 和偏置是否启用(如 "Linear(in_features=20, out_features=30, bias=True)")。这是一个辅助方法,帮助调试和可视化模型结构,不是计算核心。
- **注意**:这是 `nn.Module` 的标准方法,在 `Linear` 中被覆盖以包含特定参数。没有额外示例,但打印模块时会自动调用。
### 附加说明
- **继承方法**`torch.nn.Linear` 继承自 `nn.Module`,因此支持所有 `nn.Module` 方法,如 `parameters()`(获取可训练参数)、`named_parameters()`(命名参数迭代)、`zero_grad()`(梯度清零)等。这些不是 `Linear` 特有,而是通用方法。如果需要讲解整个 `nn.Module`,可以进一步查询。
- **属性**:模块有 `weight`(权重张量)和 `bias`(偏置张量,如果启用),这些是 `nn.Parameter` 类型,可通过优化器更新。
- **使用提示**:在构建神经网络时,`Linear` 常用于 MLP 等。确保输入的最后一个维度匹配 `in_features`,否则会报错。文档强调该模块在 float16 输入时的特殊行为(在 ROCm 上转换为 float32以避免精度问题。
如果需要代码示例、数学推导或特定版本的差异,请提供更多细节!

101
Pytorch/nn/viFunc/readme.md Normal file
View File

@@ -0,0 +1,101 @@
好的 👍
`torch.nn` 里面确实包含了很多常用的神经网络模块,你可以把它们理解为深度学习中各种“积木”,主要分为 **层layers**、**容器containers** 和 **正则化/损失函数** 等几个类别。
下面我给你整理一份 **值得学习的网络层/模块清单**(重点是 `nn` 里面和建模相关的):
---
### 🔹 1. 基础层Linear & Embedding
* `nn.Linear` —— 全连接层MLP 基础积木)
* `nn.Bilinear` —— 双线性层
* `nn.Embedding` —— 词嵌入层
* `nn.EmbeddingBag` —— 变体,适合处理词袋模型
---
### 🔹 2. 卷积层Convolution Layers
* `nn.Conv1d` —— 一维卷积(常用于 NLP、语音
* `nn.Conv2d` —— 二维卷积(图像处理最常用)
* `nn.Conv3d` —— 三维卷积(视频、体数据)
* `nn.ConvTranspose1d/2d/3d` —— 反卷积(上采样/生成模型常用)
---
### 🔹 3. 池化层Pooling
* `nn.MaxPool1d/2d/3d` —— 最大池化
* `nn.AvgPool1d/2d/3d` —— 平均池化
* `nn.AdaptiveMaxPool1d/2d/3d` —— 自适应池化(固定输出大小)
* `nn.AdaptiveAvgPool1d/2d/3d` —— 自适应平均池化
---
### 🔹 4. 循环神经网络层RNN 系列)
* `nn.RNN` —— 基础循环网络
* `nn.LSTM` —— 长短期记忆网络
* `nn.GRU` —— 门控循环单元
---
### 🔹 5. Transformer 相关
* `nn.MultiheadAttention` —— 多头注意力机制
* `nn.Transformer` —— 整个 Transformer 模型(包含编码器+解码器)
* `nn.TransformerEncoder` / `nn.TransformerDecoder`
* `nn.TransformerEncoderLayer` / `nn.TransformerDecoderLayer`
---
### 🔹 6. 归一化Normalization
* `nn.BatchNorm1d/2d/3d` —— 批量归一化
* `nn.LayerNorm` —— 层归一化Transformer 常用)
* `nn.GroupNorm` —— 分组归一化
* `nn.InstanceNorm1d/2d/3d` —— 实例归一化(风格迁移常用)
* `nn.LocalResponseNorm` —— 局部响应归一化(早期 CNN
---
### 🔹 7. Dropout & 正则化
* `nn.Dropout` —— 全连接层 Dropout
* `nn.Dropout2d/3d` —— 用于卷积层的 Dropout
* `nn.AlphaDropout` —— 用于 SELU 激活的变体
---
### 🔹 8. 激活函数(很多都在 `torch.nn.functional`,但也有类)
* `nn.ReLU`, `nn.LeakyReLU`, `nn.PReLU`, `nn.RReLU`
* `nn.Sigmoid`, `nn.Tanh`, `nn.ELU`, `nn.CELU`
* `nn.SELU`, `nn.GELU`, `nn.SiLU`=Swish
* `nn.Softmax`, `nn.LogSoftmax`
* `nn.Softplus`, `nn.Softsign`
---
### 🔹 9. 稀疏与其他层
* `nn.SparseLinear`PyTorch 2.5+ 才有)
* `nn.PixelShuffle` —— 超分辨率常用(上采样)
* `nn.Upsample` —— 上采样
* `nn.Unfold / nn.Fold` —— 图像 Patch 提取和恢复
---
### 🔹 10. 容器(搭建网络时用)
* `nn.Sequential` —— 顺序容器
* `nn.ModuleList` —— 模块列表
* `nn.ModuleDict` —— 模块字典
* `nn.ParameterList / ParameterDict` —— 参数容器
---
👉 如果你是初学者,推荐学习路径大概是:
`Linear → Conv → Pool → BatchNorm/LayerNorm → Dropout → RNN/LSTM/GRU → Transformer → MultiheadAttention`
要不要我帮你整理一份 **按“难度/应用领域”分层的学习路线图**(比如入门 → 图像 → NLP → 高级网络)?