You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中自定义单算子nn.Module与官方层、Sequential的差异探究

自定义单卷积Module、直接实例化卷积层与nn.Sequential的差异分析

首先,你的model1代码存在致命错误

你定义的conv类里,__init__方法中的conv1是局部变量,既没有注册为Module的可训练参数/子模块,也没有绑定为类属性。当调用model1(input)时,forward方法里的conv1会因找不到变量直接抛出NameError。

正确的model1写法必须调用父类初始化方法,并将conv1设为类属性:

class conv(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1,20,5)
    def forward(self,x):
        return self.conv1(x)
model1 = conv()
model1(input)

修正后,三个模型的核心差异

1. 类型与结构差异

  • model2是直接实例化的Conv2d类,类型为torch.nn.modules.conv.Conv2d,本身就是独立的卷积层模块。
  • 修正后的model1是自定义的nn.Module子类,类型为你定义的conv类,内部封装了一个Conv2d子模块。
  • model3是nn.Sequential容器,类型为torch.nn.modules.container.Sequential,内部按顺序存放了一个Conv2d模块。

2. 功能与行为差异

仅看前向传播计算,三者输出结果完全一致,但其他场景下存在明显区别:

  • 参数访问:
    • model2可直接通过model2.weight访问卷积核参数;
    • model1需通过model1.conv1.weight访问;
    • model3需通过model3[0].weight访问。
  • 模型序列化(保存/加载):
    • 三者都能正常保存加载,但state_dict的键结构不同:
      • model2的键为weight、bias;
      • model1的键为conv1.weight、conv1.bias;
      • model3的键为0.weight、0.bias。
  • 扩展性:
    • model1可随时在__init__或forward中添加自定义逻辑(比如激活函数、分支计算);
    • model2是单一卷积层,无法直接扩展,需额外封装;
    • model3只能按顺序追加模块,仅支持线性执行逻辑。

3. model3能否等同于model1?

仅在单一卷积层的前向计算场景下,二者输出一致,但在参数访问、序列化结构、扩展性上均有差异,不能说"任何场景下等同"。比如后续要修改卷积层参数时,二者的访问路径不同;若需添加新的计算逻辑,model1的修改灵活性远高于model3。


内容的提问来源于stack exchange,提问作者JunKyeong Choi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 00:40:11