ModuleList可以像常规Python列表一样进行索引。如下所示:
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):
for index, liner in enumerate(self.linears):
x = self.linears[index // 2](x) + liner(x)
return x
ModuleList常用函数有三个:
append(module)函数:将给定的模块附加到列表末尾。
extend(modules)函数:将多个模块追加到列表末尾。
insert(index, module)函数:在列表中的给定索引之前插入给定的模块。
Sequential表示一个连续的容器,模块将按照它们在构造函数中传递的顺序添加到容器其中。
Sequential的forward()方法接受任何输入并将其转发到它包含的第一个模块。然后,它将输出顺序“链接”到每个后续模块的输入,最终返回最后一个模块的输出。
Sequential提供的优于手动调用模块序列的价值在于,它允许将整个容器视为单个模块,这样对Sequential执行转换将应用于它存储的每个模块。
使用Sequential可以构建一个短小灵活的网络模型,如下所示。当模型运行的时候,数据首先经过Conv2d(1,20,5)层的处理,然后再进入第一个ReLU层,随着进入nn.Conv2d(20,64,5)层,最后经过第2个ReLU层。
model = nn.Sequential(
nn.Conv2d(1,20,5),
nn.ReLU(),
nn.Conv2d(20,64,5),
nn.ReLU()
)
当然,我们可以使用OrderedDict当做Sequential的参数,下面的代码与上述例子完全等效:
model = nn.Sequential(OrderedDict([
("conv1", nn.Conv2d(1,20,5)),
("relu1", nn.ReLU()),
("conv2", nn.Conv2d(20,64,5)),
("relu2", nn.ReLU())
]))
Sequential中的层以级联方式连接,而ModuleList仅仅是存储模块,并没有级联,这是两者的区别所在。