pytorch学习笔记:nn.Module类方法中部分方法详解

前言:
在pytorch卷积层中对卷积核的可视化有些疑问,不知道其中具体的运行过程。考虑到无论是模型还是卷积层,池化层都是继承nn.Module类,本文通过源码了解部分类方法。

1、先随便构建一个Net网络

class Net(nn.Module):
    def __init__(self, num_class=10):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(in_channels=3, out_channels=6, kernel_size=3),
            nn.BatchNorm2d(6),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(in_channels=6, out_channels=9, kernel_size=3),
            nn.BatchNorm2d(9),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )
        self.classifier = nn.Sequential(
            nn.Linear(9 * 8 * 8, 128),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(128, num_class)
        )

    def forward(self, x):
        output = self.features(x)
        output = output.view(output.size()[0], -1)
        output = self.classifier(output)

        return output

查看Net网络具体的方法

# 查看model类的方法
model = Net()
dir(model)

out:

['T_destination',
 '__annotations__',
 '__call__',
 '__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattr__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__setstate__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_apply',
 '_backward_hooks',
 '_buffers',
 '_call_impl',
 '_forward_hooks',
 '_forward_pre_hooks',
 '_get_backward_hooks',
 '_get_name',
 '_is_full_backward_hook',
 '_load_from_state_dict',
 '_load_state_dict_post_hooks',
 '_load_state_dict_pre_hooks',
 '_maybe_warn_non_full_backward_hook',
 '_modules',
 '_named_members',
 '_non_persistent_buffers_set',
 '_parameters',
 '_register_load_state_dict_pre_hook',
 '_register_state_dict_hook',
 '_replicate_for_data_parallel',
 '_save_to_state_dict',
 '_slow_forward',
 '_state_dict_hooks',
 '_version',
 'add_module',
 'apply',
 'bfloat16',
 'buffers',
 'children',
 'classifier',
 'cpu',
 'cuda',
 'double',
 'dump_patches',
 'eval',
 'extra_repr',
 'features',
 'float',
 'forward',
 'get_buffer',
 'get_extra_state',
 'get_parameter',
 'get_submodule',
 'half',
 'ipu',
 'load_state_dict',
 'modules',
 'named_buffers',
 'named_children',
 'named_modules',
 'named_parameters',
 'parameters',
 'register_backward_hook',
 'register_buffer',
 'register_forward_hook',
 'register_forward_pre_hook',
 'register_full_backward_hook',
 'register_load_state_dict_post_hook',
 'register_module',
 'register_parameter',
 'requires_grad_',
 'set_extra_state',
 'share_memory',
 'state_dict',
 'to',
 'to_empty',
 'train',
 'training',
 'type',
 'xpu',
 'zero_grad']

1.0 children()方法:

查看源码:该方法是返回直接子模块上的迭代器。注意,只返回模型直接子模块的迭代器
在这里插入图片描述
例如:

for mod in model.children():
    print(mod)

out:

Sequential(
  (0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
  (1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU(inplace=True)
  (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
  (5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (6): ReLU(inplace=True)
  (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
Sequential(
  (0): Linear(in_features=576, out_features=128, bias=True)
  (1): ReLU(inplace=True)
  (2): Dropout(p=0.5, inplace=False)
  (3): Linear(in_features=128, out_features=10, bias=True)
)

可以看到只返回2个自定义的层。

1.1 named_children()方法

查看named_children()的源码如下:大致的意思是会返回子模块上的迭代器,生成模块名称和模块本身。
在这里插入图片描述
使用源码中提供的Example对自定义的Net进行查看:

for name,mod in model.named_children():
    print("输出模块名称:",name)
    print("*"*10)
    print("输出模块:",mod)

out:

输出模块名称: features
**********
输出模块: Sequential(
  (0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
  (1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU(inplace=True)
  (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
  (5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (6): ReLU(inplace=True)
  (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
输出模块名称: classifier
**********
输出模块: Sequential(
  (0): Linear(in_features=576, out_features=128, bias=True)
  (1): ReLU(inplace=True)
  (2): Dropout(p=0.5, inplace=False)
  (3): Linear(in_features=128, out_features=10, bias=True)

可以看到输出的name是Net中定义的self的name,mod对应的是Sequential对象。

1.2 modules()方法

查看modules()源码如下:大致意思是返回网络中所有模块的迭代器,重复的模块只返回一次。
在这里插入图片描述
打印出来看一下该方法的具体返回值:

for idx, m in enumerate(model.modules()):
    print(idx, '->', m)

out:

0 -> Net(
  (features): Sequential(
    (0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
    (1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (2): ReLU(inplace=True)
    (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
    (5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (6): ReLU(inplace=True)
    (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (classifier): Sequential(
    (0): Linear(in_features=576, out_features=128, bias=True)
    (1): ReLU(inplace=True)
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=128, out_features=10, bias=True)
  )
)
1 -> Sequential(
  (0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
  (1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU(inplace=True)
  (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
  (5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (6): ReLU(inplace=True)
  (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
2 -> Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
3 -> BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
4 -> ReLU(inplace=True)
5 -> MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
6 -> Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
7 -> BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
8 -> ReLU(inplace=True)
9 -> MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
10 -> Sequential(
  (0): Linear(in_features=576, out_features=128, bias=True)
  (1): ReLU(inplace=True)
  (2): Dropout(p=0.5, inplace=False)
  (3): Linear(in_features=128, out_features=10, bias=True)
)
11 -> Linear(in_features=576, out_features=128, bias=True)
12 -> ReLU(inplace=True)
13 -> Dropout(p=0.5, inplace=False)
14 -> Linear(in_features=128, out_features=10, bias=True)

可以看到该方打印了Net中的所有模块以及其下的子模块,即遍历模型的所有子层,所有子层即指nn.Module子类,在本文的例子中,Net(), features(), classifier(),以及nn.xxx构成的卷积,池化,ReLU, Linear, BN, Dropout等都是nn.Module子类,也就是model.modules()会迭代的遍历它们所有对象。

1.3 named_modules()方法

该方法与modules()的功能一样,返回所有模块以及旗下子模块,不过会多返回一个名称 ,具体如下

for name ,mod in model.named_modules():
    print("打印名称:",name)
    print("*"*20)
    print("打印迭代器:",mod)

out:

打印名称: 
********************
打印迭代器: Net(
  (features): Sequential(
    (0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
    (1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (2): ReLU(inplace=True)
    (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
    (5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (6): ReLU(inplace=True)
    (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (classifier): Sequential(
    (0): Linear(in_features=576, out_features=128, bias=True)
    (1): ReLU(inplace=True)
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=128, out_features=10, bias=True)
  )
)
打印名称: features
********************
打印迭代器: Sequential(
  (0): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
  (1): BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU(inplace=True)
  (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (4): Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
  (5): BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (6): ReLU(inplace=True)
  (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
打印名称: features.0
********************
打印迭代器: Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
打印名称: features.1
********************
打印迭代器: BatchNorm2d(6, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
打印名称: features.2
********************
打印迭代器: ReLU(inplace=True)
打印名称: features.3
********************
打印迭代器: MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
打印名称: features.4
********************
打印迭代器: Conv2d(6, 9, kernel_size=(3, 3), stride=(1, 1))
打印名称: features.5
********************
打印迭代器: BatchNorm2d(9, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
打印名称: features.6
********************
打印迭代器: ReLU(inplace=True)
打印名称: features.7
********************
打印迭代器: MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
打印名称: classifier
********************
打印迭代器: Sequential(
  (0): Linear(in_features=576, out_features=128, bias=True)
  (1): ReLU(inplace=True)
  (2): Dropout(p=0.5, inplace=False)
  (3): Linear(in_features=128, out_features=10, bias=True)
)
打印名称: classifier.0
********************
打印迭代器: Linear(in_features=576, out_features=128, bias=True)
打印名称: classifier.1
********************
打印迭代器: ReLU(inplace=True)
打印名称: classifier.2
********************
打印迭代器: Dropout(p=0.5, inplace=False)
打印名称: classifier.3
********************
打印迭代器: Linear(in_features=128, out_features=10, bias=True)

1.4 parameters()参数

查看源码解释:返回模块参数上的迭代器。注意:recurse(bool):如果为True,则生成此模块和所有子模块的参数。
在这里插入图片描述
使用Example例子打印Net中的情况:

for para in model.parameters():
    print(para.shape)

该方法并未打印出是哪个方法的参数。
out:

torch.Size([6, 3, 3, 3])
torch.Size([6])
torch.Size([6])
torch.Size([6])
torch.Size([9, 6, 3, 3])
torch.Size([9])
torch.Size([9])
torch.Size([9])
torch.Size([128, 576])
torch.Size([128])
torch.Size([10, 128])
torch.Size([10])

1.5 named_parameters()

该方法与parameters()方法一致,但是可以打印出具体参数层的名称,看起来更直观一些

for name,para in model.named_parameters():
    print("name:",name)
    print("para.shape:",para.shape)

out>>
name: features.0.weight
para.shape: torch.Size([6, 3, 3, 3])
name: features.0.bias
para.shape: torch.Size([6])
name: features.1.weight
para.shape: torch.Size([6])
name: features.1.bias
para.shape: torch.Size([6])
name: features.4.weight
para.shape: torch.Size([9, 6, 3, 3])
name: features.4.bias
para.shape: torch.Size([9])
name: features.5.weight
para.shape: torch.Size([9])
name: features.5.bias
para.shape: torch.Size([9])
name: classifier.0.weight
para.shape: torch.Size([128, 576])
name: classifier.0.bias
para.shape: torch.Size([128])
name: classifier.3.weight
para.shape: torch.Size([10, 128])
name: classifier.3.bias
para.shape: torch.Size([10])

1.6 state_dict()

该方法返回包含模块整体状态的字典,包括参数信息,参数名称。
以构建的Net作为实例展示如下:

# 查看其参数名称:
model.state_dict().keys()

out:

odict_keys(['features.0.weight', 'features.0.bias', 'features.1.weight', 'features.1.bias', 'features.1.running_mean', 'features.1.running_var', 'features.1.num_batches_tracked', 'features.4.weight', 'features.4.bias', 'features.5.weight', 'features.5.bias', 'features.5.running_mean', 'features.5.running_var', 'features.5.num_batches_tracked', 'classifier.0.weight', 'classifier.0.bias', 'classifier.3.weight', 'classifier.3.bias'])
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch,`nn.Module`是所有神经网络模块的基。它是一个封装了参数、计算方法以及其他网络组件的,可以用来构建自己的神经网络模型。 每个`nn.Module`子的构造函数都应该调用基的构造函数。在`__init__`方法,我们可以定义网络的各个层、参数和其他组件。我们也可以在`forward`方法定义网络的前向传播过程,即输入数据经过一系列计算后得到输出结果。 `nn.Module`提供了很多实用的方法,例如`parameters`方法可以返回模型所有可训练的参数,`to`方法可以将模型转移到指定的设备上等。 示例代码: ```python import torch import torch.nn as nn class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1) self.relu = nn.ReLU(inplace=True) self.pool = nn.MaxPool2d(kernel_size=2, stride=2) self.fc = nn.Linear(16 * 14 * 14, 10) def forward(self, x): x = self.conv1(x) x = self.relu(x) x = self.pool(x) x = x.view(x.size(0), -1) x = self.fc(x) return x model = MyModel() input = torch.randn(1, 3, 28, 28) output = model(input) ``` 这里我们定义了一个简单的卷积神经网络模型,包括了一个卷积层、一个ReLU激活函数、一个最大池化层和一个全连接层。在`forward`方法,我们定义了输入数据的前向传播过程。我们可以通过调用`parameters`方法打印出模型的所有参数:`print(list(model.parameters()))`。我们还可以使用`to`方法将模型转移到GPU上:`model.to(device)`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值