nn.Sequential和nn.Module区别与选择

本文深入探讨了PyTorch中两种主要的网络构建方式:nn.Sequential和nn.Module的使用方法及区别。通过实例展示了如何利用这两种方式快速搭建神经网络,并分析了它们在灵活性和便捷性上的不同。
部署运行你感兴趣的模型镜像

一、nn.Sequential

torch.nn.Sequential是一个Sequential容器,模块将按照构造函数中传递的顺序添加到模块中。另外,也可以传入一个有序模块。 为了更容易理解,官方给出了一些案例:

# Sequential使用实例

model = nn.Sequential(
          nn.Conv2d(1,20,5),
          nn.ReLU(),
          nn.Conv2d(20,64,5),
          nn.ReLU()
        )

# Sequential with OrderedDict使用实例
model = nn.Sequential(OrderedDict([
          ('conv1', nn.Conv2d(1,20,5)),
          ('relu1', nn.ReLU()),
          ('conv2', nn.Conv2d(20,64,5)),
          ('relu2', nn.ReLU())
        ]))

二、nn.Module

下面我们再用 Module 定义这个模型,下面是使用 Module 的模板



class 网络名字(nn.Module):
    def __init__(self, 一些定义的参数):
        super(网络名字, self).__init__()
        self.layer1 = nn.Linear(num_input, num_hidden)
        self.layer2 = nn.Sequential(...)
        ...

        定义需要用的网络层

    def forward(self, x): # 定义前向传播
        x1 = self.layer1(x)
        x2 = self.layer2(x)
        x = x1 + x2
        ...
        return x


注意的是,Module 里面也可以使用 Sequential,同时 Module 非常灵活,具体体现在 forward 中,如何复杂的操作都能直观的在 forward 里面执行

三、对比

为了方便比较,我们先用普通方法搭建一个神经网络。

class Net(torch.nn.Module):
    def __init__(self, n_feature, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(n_feature, n_hidden)
        self.predict = torch.nn.Linear(n_hidden, n_output)

    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = self.predict(x)
        return x
net1 = Net(1, 10, 1)

net2 = torch.nn.Sequential(
    torch.nn.Linear(1, 10),
    torch.nn.ReLU(),
    torch.nn.Linear(10, 1)
)

打印这两个net

print(net1)
"""
Net (
  (hidden): Linear (1 -> 10)
  (predict): Linear (10 -> 1)
)
"""
print(net2)
"""
Sequential (
  (0): Linear (1 -> 10)
  (1): ReLU ()
  (2): Linear (10 -> 1)
)
"""

我们可以发现,打印torch.nn.Sequential会自动加入激励函数,
在 net1 中, 激励函数实际上是在 forward() 功能中被调用的,没有在init中定义,所以在打印网络结构时不会有激励函数的信息.

解析源码,在torch.nn.Sequential中:

    def forward(self, input):
        for module in self:
            input = module(input)
        return input

可以看到,torch.nn.Sequential的forward只是简单的顺序传播,操作性有限.

总结

  • 使用torch.nn.Module,我们可以根据自己的需求改变传播过程,如RNN等
  • 如果你需要快速构建或者不需要过多的过程,直接使用torch.nn.Sequential即可。

参考:pytorch官方手册

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

<think>嗯,用户想了解PyTorchnn.Sequentialnn.Module区别及用法。首先,我需要回忆这两个模块的基本概念。nn.ModulePyTorch中所有神经网络模块的基类,用户自定义的模型都需要继承它。而nn.Sequential是一个容器,可以按顺序包装多个层。 然后,区别方面,应该从结构、使用场景、灵活性等方面展开。比如,nn.Sequential适合简单的线性堆叠,而nn.Module更适合复杂的结构,比如分支或者需要自定义forward逻辑的情况。引用中的例子显示,nn.Sequential可以直接按顺序添加层,甚至用OrderedDict来命名,而nn.ModuleList则更适合需要动态操作的模块列表。 接下来,用户可能需要具体的用法示例。比如,用nn.Sequential构建一个简单的CNN,而用nn.Module构建一个带有跳跃连接的模型。这时候需要参考引用中的代码示例,比如引用34中的Sequential用法,以及引用1提到的ModuleListSequential区别。 还要注意两者的嵌套使用,比如在nn.Module内部使用多个nn.Sequential来组织子模块。同时,性能方面可能没有太大差异,但代码结构会更清晰。 用户可能的应用场景,比如快速搭建简单网络用Sequential,复杂结构用Module。另外,注意事项中提到Sequential需要严格顺序,而Module更灵活,但需要手动定义forward。 最后,生成相关问题的时候,要覆盖两者的比较、适用情况、嵌套使用、选择依据性能影响等方面,帮助用户深入理解。</think>### PyTorch中`nn.Sequential``nn.Module`的区别及用法解析 #### 一、核心区别 1. **功能定位** - `nn.Module`是PyTorch中所有神经网络模块的**基类**,所有自定义模型必须继承它,并实现`forward`方法[^1][^3]。 - `nn.Sequential`是`nn.Module`的**子类**,专门用于**顺序堆叠多个模块**的容器,无需手动定义`forward`方法[^4]。 2. **灵活性** - `nn.Module`支持**任意网络结构**(如分支、循环、条件判断),可自由定义参数子模块。 - `nn.Sequential`仅适用于**严格线性堆叠**的结构,例如:$Layer_1 \to Layer_2 \to \dots \to Layer_n$[^4]。 #### 二、典型用法对比 ##### 1. `nn.Sequential`的用法 ```python import torch.nn as nn # 直接堆叠模块(自动命名) model = nn.Sequential( nn.Linear(784, 256), nn.ReLU(), nn.Linear(256, 10) ) # 使用OrderedDict命名模块 from collections import OrderedDict model = nn.Sequential(OrderedDict([ ('fc1', nn.Linear(784, 256)), ('act', nn.ReLU()), ('fc2', nn.Linear(256, 10)) ])) ``` - **适用场景**:快速搭建简单网络(如全连接网络、线性CNN)[^4]。 ##### 2. `nn.Module`的用法 ```python class CustomModel(nn.Module): def __init__(self): super().__init__() self.fc1 = nn.Linear(784, 256) self.act = nn.ReLU() self.fc2 = nn.Linear(256, 10) def forward(self, x): x = self.fc1(x) x = self.act(x) return self.fc2(x) ``` - **优势**:支持复杂逻辑(如残差连接、分支结构): ```python class ResidualBlock(nn.Module): def __init__(self): super().__init__() self.fc = nn.Linear(256, 256) self.act = nn.ReLU() def forward(self, x): return x + self.act(self.fc(x)) # 残差连接 ``` #### 三、嵌套使用 1. **`nn.Sequential`嵌套在`nn.Module`中** ```python class ComplexModel(nn.Module): def __init__(self): super().__init__() self.features = nn.Sequential( nn.Conv2d(3, 64, 3), nn.ReLU(), nn.MaxPool2d(2) ) self.classifier = nn.Linear(64*14*14, 10) ``` 2. **`nn.ModuleList``nn.Sequential`的配合** - `nn.ModuleList`用于动态管理子模块(如循环中创建层),而`nn.Sequential`直接定义执行顺序: ```python class DynamicModel(nn.Module): def __init__(self, layers): super().__init__() self.layers = nn.ModuleList([nn.Linear(10,10) for _ in range(layers)]) def forward(self, x): for layer in self.layers: x = layer(x) return x ``` #### 四、性能注意事项 1. **性能差异** - 两者在计算效率上无本质区别,最终都会被编译为计算图。 2. **使用建议** - 优先选择`nn.Sequential`:当网络结构为简单线性堆叠时(代码更简洁)。 - 必须使用`nn.Module`:需要自定义`forward`逻辑或包含复杂结构时。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值