本节介绍的方法,返回值都是生成器,是一个可迭代变量,用列表推导式取出每一个值。
modules()和children()
- modules()迭代遍历模型所有子层,由浅(根)入深(叶子)返回所有不同级别的层,最大的根就是模型本身。
- children()迭代遍历访问模型最外层,即模型的子层。
举个例子:
m = nn.Sequential(nn.Linear(2,2),
nn.ReLU(),
nn.Sequential(nn.Sigmoid(), nn.ReLU()))
m_modules = [x for x in m.modules()]
print(m_modules)
m.modules()返回的是:
可以看出,m.modules列表共有6个元素,先是整个Sequential,然后遍历Sequential下的linear,relu和子Sequential,最后遍历子Sequential里的sigmoid和relu。因此,modules()是由外而内迭代遍历模型所有子层,包括模型本身。相当于深度优先遍历。
for index, module in enumerate(m.modules()):
print("第{}个元素为:\n {}".format(index,module))
m.children()返回的是:
m_children = [x for x in m.children()]
print(m_children)
m.children()返回三个元素,这三个元素分别是linear, relu和sequential,均是模型m的子层。
for index,children in enumerate(m.children()):
print("第{}个元素为:\n {}".format(index,children))
特例:
#例子1:
l = nn.Linear(2, 2)
net = nn.Sequential(l, l)
for idx, m in enumerate(net.modules()):
print(idx, '->', m)
#结果:
0 -> Sequential(
(0): Linear(in_features=2, out_features=2, bias=True)
(1): Linear(in_features=2, out_features=2, bias=True)
)
1 -> Linear(in_features=2, out_features=2, bias=True)
#例子2:
net1=nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
for idx, m in enumerate(net1.modules()):
print(idx, '->', m)
#结果:
0 -> Sequential(
(0): Linear(in_features=2, out_features=2, bias=True)
(1): Linear(in_features=2, out_features=2, bias=True)
)
1 -> Linear(in_features=2, out_features=2, bias=True)
2 -> Linear(in_features=2, out_features=2, bias=True)
#例子1中的l = nn.Linear(2, 2)是重复的模块,有单独的命名,是类nn.Linear()的一个固定实例,
#而例子2中的nn.Linear(2, 2)不是重复的模块,是看成类nn.Linear()不同的实例了。
named_modules()和named_children()
- named_modules(),返回模型所有子层以及对应层的名字。
- named_children(),返回模型的最外层以及名字。
返回名字的好处,可以按名字通过迭代的方法修改特定的层,如果在模型定义的时候就给每个层起了名字,比如conv1,conv2的形式,那么可以这样处理。
for name, layer in model.named_modules():
if 'conv' in name:
...对layer进行处理
如果,没有返回名字的情形,可以采用isinstance()完成操作。
for layer in model.modules():
if isinstance(layer, nn.Conv2d):
...对layer进行处理
或者
for name, module in self.features.named_children():
if name in ["0", "3", "6"]: # “0”,“3”,“6”是conv在squential中的索引值
outputs.append(x)
parameters()和named_parameters()
- parameters() 迭代地返回模型的所有参数
- named_parameters() 迭代地返回带有名字的参数,会给每个参数加上带有.weight或.bias的名字区分权重和偏置。