所有神经网络模块的基类。
你的模型也应该继承这个类。
模块还可以包含其他模块,允许将它们嵌套在树结构中。您可以将子模块分配为常规属性:
import torch.nn as nn
import torch.nn.functional as F
class Model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 20, 5)
self.conv2 = nn.Conv2d(20, 20, 5)
def forward(self, x):
x = F.relu(self.conv1(x))
return F.relu(self.conv2(x))
根据上面的示例,必须在对子类进行赋值之前对父类进行 __init__() 调用。
顺序容器。
Sequential 的 forward() 方法接受任何输入并将其转发到它包含的第一个模块(第一个定义的网络,比如nn.Linear)。然后它为每个后续模块按顺序将输出“链接”到输入,最后返回最后一个模块的输出。
Sequential 提供的超过手动调用一系列模块的价值在于它允许将整个容器视为单个模块,这样对 Sequential 执行的转换将应用于它存储的每个模块(每个模块都是顺序的注册子模块)。
Sequential 和 torch.nn.ModuleList 有什么区别? ModuleList 顾名思义——一个用于存储 Module 的列表!另一方面,Sequential 中的层以级联方式连接。
例子:
# Using Sequential to create a small model. When `model` is run, input will first be passed to `Conv2d(1,20,5)`. The output of `Conv2d(1,20,5)` will be used as the input to the first `ReLU`; the output of the first `ReLU` will become the input for `Conv2d(20,64,5)`. Finally, the output of `Conv2d(20,64,5)` will be used as input to the second `ReLU`
# 使用Sequential创建一个小模型。当' model '运行时,输入将首先传递给' Conv2d(1,20,5) ' Conv2d(1,20,5) '的输出将被用作第一个' ReLU '的输入;第一个“ReLU”的输出将成为“Conv2d(20,64,5)”的输入。最后,' Conv2d(20,64,5) '的输出将用作第二个' ReLU '的输入。
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
# Using Sequential with OrderedDict. This is functionally the same as the above code
model = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1,20,5)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(20,64,5)),
('relu2', nn.ReLU())
]))
将子模块保存在列表中。
ModuleList 可以像常规 Python 列表一样进行索引,但它包含的模块已正确注册,并且所有 Module 方法都可见。
参数:modules (iterable, optional): 要添加的可迭代模块
class MyModule(nn.Module):
def __init__(self):
super().__init__()
self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])
def forward(self, x):
# ModuleList can act as an iterable, or be indexed using ints
for i, l in enumerate(self.linears):
x = self.linears[i // 2](x) + l(x)
return x
与torch.nn.Sequential不同的是,这里运行ModuleList的下一个Module时,需要输入上一个module输出的内容,不会自动链接;