pytorch api文档:nn.ModuleList() 存储多个nn.Module的有序列表容器 作者:马育民 • 2026-01-21 08:51 • 阅读:10001 # 介绍 `nn.ModuleList`,是 `nn.Module` 的一个实用工具类,专门用来管理一组神经网络模块(比如多个卷积层、全连接层) ### 作用 `nn.ModuleList` 是 PyTorch 提供的 **有序列表容器**,用于存储多个 `nn.Module` 子类实例(比如 `nn.Linear`、`nn.Conv2d`)。它的核心作用是: - 让 PyTorch 能够**识别并管理列表中的所有模块参数**(这是普通 Python list 做不到的); - 提供有序的、可索引的模块访问方式,适合需要动态创建/管理多个层的场景。 简单来说:普通 `list` 装的层,PyTorch 不认(参数不会被收集);`nn.ModuleList` 装的层,PyTorch 能完整管理(参数可训练、可迁移设备)。 # 例子 ### 基础使用场景(动态创建多层) 创建一个可配置层数的全连接网络,用 `nn.ModuleList` 就能灵活实现: ```python import torch import torch.nn as nn class DynamicNet(nn.Module): def __init__(self, input_size, hidden_sizes, output_size): super(DynamicNet, self).__init__() # 1. 初始化 nn.ModuleList(空列表) self.layers = nn.ModuleList() # 2. 动态添加层到 ModuleList 中 prev_size = input_size for hidden_size in hidden_sizes: # 添加全连接层 self.layers.append(nn.Linear(prev_size, hidden_size)) # 添加激活函数 self.layers.append(nn.ReLU()) prev_size = hidden_size # 添加输出层 self.layers.append(nn.Linear(prev_size, output_size)) def forward(self, x): # 3. 遍历 ModuleList 执行前向传播 for layer in self.layers: x = layer(x) return x # ---------------------- 测试使用 ---------------------- # 创建模型:输入10维,隐藏层[20, 15],输出5维 model = DynamicNet(input_size=10, hidden_sizes=[20, 15], output_size=5) print("模型结构:") print(model) # 查看参数(验证 ModuleList 中的层参数被正确收集) print("\n模型所有可训练参数:") for name, param in model.named_parameters(): print(f"参数名:{name},形状:{param.shape}") # 前向传播测试 input_data = torch.randn(2, 10) # 2个样本,10维特征 output = model(input_data) print("\n输入形状:", input_data.shape) print("输出形状:", output.shape) # 设备迁移(ModuleList 中的层会一起迁移) model = model.to("cpu") # 也可以用 "cuda"(如果有GPU) print("\n模型设备:", next(model.parameters()).device) ``` ### nn.ModuleList vs 普通 Python list 用代码对比,直观看到差异: ```python import torch import torch.nn as nn class TestNet(nn.Module): def __init__(self): super(TestNet, self).__init__() # 用普通 list 存储层 self.normal_list = [nn.Linear(10, 5), nn.ReLU()] # 用 ModuleList 存储层 self.module_list = nn.ModuleList([nn.Linear(5, 2)]) def forward(self, x): for layer in self.normal_list: x = layer(x) for layer in self.module_list: x = layer(x) return x model = TestNet() # 查看模型参数:只有 ModuleList 中的层参数被收集 print("模型参数列表:") for name, param in model.named_parameters(): print(name) # 只输出 "module_list.0.weight" 和 "module_list.0.bias" # 普通 list 中的层参数未被识别,无法参与训练! print("\n普通 list 中的层是否在模型参数中?", "normal_list.0.weight" in [n for n, _ in model.named_parameters()]) # 输出:False ``` # 常用方法 `nn.ModuleList` 支持和普通 list 类似的操作,核心方法如下: | 方法 | 作用 | |------|------| | `append(module)` | 向列表末尾添加一个模块(最常用) | | `extend(modules)` | 批量添加多个模块(如 `module_list.extend([nn.ReLU(), nn.Dropout()])`) | | `insert(idx, module)` | 在指定索引位置插入模块 | | `__getitem__(idx)` | 通过索引访问模块(如 `self.layers[0]`) | | `__len__()` | 获取列表长度(如 `len(self.layers)`) | # 使用场景 ### 适合场景 - 动态创建多层(比如根据配置文件的参数决定层数/层维度); - 需要按索引访问特定层(比如 `self.layers[2]` 取出第3层); - 层的数量不固定,需要灵活增删。 ### 不适合场景 - 只需按固定顺序执行层:优先用 `nn.Sequential`(更简洁,如 `nn.Sequential(nn.Linear(10,5), nn.ReLU())`); - 层之间有复杂的分支/跳转逻辑:直接在 `forward` 中手动调用层更清晰。 # 注意事项 - `nn.ModuleList` **只是容器**,不会自动执行前向传播:必须在 `forward` 中手动遍历执行; - 必须在 `__init__` 中初始化 `nn.ModuleList` 并添加模块:如果在 `forward` 中添加,参数不会被收集; - `nn.ModuleList` 中的模块会被 `model.parameters()` 收集,参与梯度更新,这是和普通 list 最核心的区别。 # 总结 1. `nn.ModuleList` 是管理多个 `nn.Module` 的**有序容器**,核心作用是让 PyTorch 识别并管理列表内模块的参数; 2. 它和普通 Python list 的关键区别:`ModuleList` 中的层参数会被收集、可训练,普通 list 不会; 3. 适用场景:动态创建/管理多层、需要按索引访问层;不适用场景:固定顺序执行层(优先用 `nn.Sequential`)。 原文出处:http://www.malaoshi.top/show_1GW2dCKk4ltl.html