nn.Module类的讲解

1 介绍torch.nn.Module

  1. 是所有神经网络的base类
  2. 我们所写的网络都要继承这个类
  • 一个简单的Model
    在这里插入图片描述

2 add_module(name, module)方法

  • 往当前模块中,添加子模块
add_module(name, module)
方法: add_module(name, module)
    Adds a child module to the current module.
    将一个子模块添加到当前模块中.
    The module can be accessed as an attribute using the given name.
    通过给定的名字,我们就可以以访问属性的方式来访问该模块.
    Parameters  参数
            name (string) – name of the child module. The child 
            module can be accessed from this module using the 
            given name
			name (字符串) – 子模块的名字. 在当前模块中使用给定的这个name就
			可以访问子模块.
            module (Module) – child module to be added to the module.
            module (模块) – 要添加到当前模块中的子模块.

2.1 代码实现

  • 可以直接运行,这段代码是搬运过来的,贴一下原贴子的连接:

https://blog.csdn.net/m0_46653437/article/details/112649366?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165062788416780366588245%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165062788416780366588245&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-112649366.142v9control,157v4control&utm_term=add_module%EF%BC%88name%2C+module%EF%BC%89&spm=1018.2226.3001.4187

import torch
import torch.nn as nn

torch.manual_seed(seed=20200910)


class Model(torch.nn.Module):
    def __init__(self):
        super(Model,self).__init__()
        self.conv1 = torch.nn.Sequential(  # 输入torch.Size([64, 1, 28, 28])
                torch.nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1),
                torch.nn.ReLU(),  # 输出torch.Size([64, 64, 28, 28])
                torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),  # 输出torch.Size([64, 128, 28, 28])
                torch.nn.ReLU(),
                torch.nn.MaxPool2d(stride=2, kernel_size=2)  # 输出torch.Size([64, 128, 14, 14])
        )

        self.dense = torch.nn.Sequential(  # 输入torch.Size([64, 14*14*128])
                    torch.nn.Linear(14*14*128, 1024),  # 输出torch.Size([64, 1024])
                    torch.nn.ReLU(),
                    torch.nn.Dropout(p=0.5),
                    torch.nn.Linear(1024, 10)  # 输出torch.Size([64, 10])
        )
        self.layer4cxq1 = torch.nn.Conv2d(2, 33, 4, 4)
        self.layer4cxq2 = torch.nn.ReLU()
        self.layer4cxq3 = torch.nn.MaxPool2d(stride=2, kernel_size=2)
        self.layer4cxq4 = torch.nn.Linear(14*14*128, 1024)
        self.layer4cxq5 = torch.nn.Dropout(p=0.8)
        self.attribute4cxq = nn.Parameter(torch.tensor(20200910.0))
        self.attribute4lzq = nn.Parameter(torch.tensor([2.0, 3.0, 4.0, 5.0]))
        self.attribute4hh = nn.Parameter(torch.randn(3, 4, 5, 6))
        self.attribute4wyf = nn.Parameter(torch.randn(7, 8, 9, 10))

    def forward(self, x):  # torch.Size([64, 1, 28, 28])
        x = self.conv1(x)  # 输出torch.Size([64, 128, 14, 14])
        x = x.view(-1, 14*14*128)  # torch.Size([64, 14*14*128])
        x = self.dense(x)  # 输出torch.Size([64, 10])
        return x


print('cuda(GPU)是否可用:', torch.cuda.is_available())
print('torch的版本:', torch.__version__)

model = Model()  #.cuda()

print("测试模型(CPU)".center(100, "-"))
print(type(model))

print("torch.nn.Module.add_module(name, module)方法调用之前".center(100, "-"))
for name, child in model.named_modules():
    print('模块的名字是:', name, '###模块本身是:', child)


print("torch.nn.Module.add_module(name, module)方法调用之后".center(100,"-"))
model.add_module('JUJU', torch.nn.Conv2d(38, 38, 38, 38))
for name, child in model.named_modules():
    print('模块的名字是:', name, '###模块本身是:', child)
cuda(GPU)是否可用: False
torch的版本: 1.11.0+cpu
---------------------------------------------测试模型(CPU)----------------------------------------------
<class '__main__.Model'>
---------------------------torch.nn.Module.add_module(name, module)方法调用之前---------------------------
模块的名字是:  ###模块本身是: Model(
  (conv1): Sequential(
    (0): Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU()
    (2): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU()
    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (dense): Sequential(
    (0): Linear(in_features=25088, out_features=1024, bias=True)
    (1): ReLU()
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=1024, out_features=10, bias=True)
  )
  (layer4cxq1): Conv2d(2, 33, kernel_size=(4, 4), stride=(4, 4))
  (layer4cxq2): ReLU()
  (layer4cxq3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (layer4cxq4): Linear(in_features=25088, out_features=1024, bias=True)
  (layer4cxq5): Dropout(p=0.8, inplace=False)
)
模块的名字是: conv1 ###模块本身是: Sequential(
  (0): Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (1): ReLU()
  (2): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (3): ReLU()
  (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
模块的名字是: conv1.0 ###模块本身是: Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
模块的名字是: conv1.1 ###模块本身是: ReLU()
模块的名字是: conv1.2 ###模块本身是: Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
模块的名字是: conv1.3 ###模块本身是: ReLU()
模块的名字是: conv1.4 ###模块本身是: MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
模块的名字是: dense ###模块本身是: Sequential(
  (0): Linear(in_features=25088, out_features=1024, bias=True)
  (1): ReLU()
  (2): Dropout(p=0.5, inplace=False)
  (3): Linear(in_features=1024, out_features=10, bias=True)
)
模块的名字是: dense.0 ###模块本身是: Linear(in_features=25088, out_features=1024, bias=True)
模块的名字是: dense.1 ###模块本身是: ReLU()
模块的名字是: dense.2 ###模块本身是: Dropout(p=0.5, inplace=False)
模块的名字是: dense.3 ###模块本身是: Linear(in_features=1024, out_features=10, bias=True)
模块的名字是: layer4cxq1 ###模块本身是: Conv2d(2, 33, kernel_size=(4, 4), stride=(4, 4))
模块的名字是: layer4cxq2 ###模块本身是: ReLU()
模块的名字是: layer4cxq3 ###模块本身是: MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
模块的名字是: layer4cxq4 ###模块本身是: Linear(in_features=25088, out_features=1024, bias=True)
模块的名字是: layer4cxq5 ###模块本身是: Dropout(p=0.8, inplace=False)
---------------------------torch.nn.Module.add_module(name, module)方法调用之后---------------------------
模块的名字是:  ###模块本身是: Model(
  (conv1): Sequential(
    (0): Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU()
    (2): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU()
    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (dense): Sequential(
    (0): Linear(in_features=25088, out_features=1024, bias=True)
    (1): ReLU()
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=1024, out_features=10, bias=True)
  )
  (layer4cxq1): Conv2d(2, 33, kernel_size=(4, 4), stride=(4, 4))
  (layer4cxq2): ReLU()
  (layer4cxq3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (layer4cxq4): Linear(in_features=25088, out_features=1024, bias=True)
  (layer4cxq5): Dropout(p=0.8, inplace=False)
  (JUJU): Conv2d(38, 38, kernel_size=(38, 38), stride=(38, 38))
)
模块的名字是: conv1 ###模块本身是: Sequential(
  (0): Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (1): ReLU()
  (2): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
  (3): ReLU()
  (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
模块的名字是: conv1.0 ###模块本身是: Conv2d(1, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
模块的名字是: conv1.1 ###模块本身是: ReLU()
模块的名字是: conv1.2 ###模块本身是: Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
模块的名字是: conv1.3 ###模块本身是: ReLU()
模块的名字是: conv1.4 ###模块本身是: MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
模块的名字是: dense ###模块本身是: Sequential(
  (0): Linear(in_features=25088, out_features=1024, bias=True)
  (1): ReLU()
  (2): Dropout(p=0.5, inplace=False)
  (3): Linear(in_features=1024, out_features=10, bias=True)
)
模块的名字是: dense.0 ###模块本身是: Linear(in_features=25088, out_features=1024, bias=True)
模块的名字是: dense.1 ###模块本身是: ReLU()
模块的名字是: dense.2 ###模块本身是: Dropout(p=0.5, inplace=False)
模块的名字是: dense.3 ###模块本身是: Linear(in_features=1024, out_features=10, bias=True)
模块的名字是: layer4cxq1 ###模块本身是: Conv2d(2, 33, kernel_size=(4, 4), stride=(4, 4))
模块的名字是: layer4cxq2 ###模块本身是: ReLU()
模块的名字是: layer4cxq3 ###模块本身是: MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
模块的名字是: layer4cxq4 ###模块本身是: Linear(in_features=25088, out_features=1024, bias=True)
模块的名字是: layer4cxq5 ###模块本身是: Dropout(p=0.8, inplace=False)
模块的名字是: JUJU ###模块本身是: Conv2d(38, 38, kernel_size=(38, 38), stride=(38, 38))

Process finished with exit code 0

2.2 总结

  • 从最后一行输出可以看到,这里的add_module是确实执行了的,是直接加在init函数之后的,但是并不在forward函数中,forward函数中的网络才是后面模型计算用到的神经网络。

3 apply(fn) 方法

  • 用于随机初始化一个参数的

4 bfloat16()方法

  • 将所有浮点数都转换成bfloat16类型的

5 parameters()

  • torch.nn.Parameter是继承自torch.Tensor的子类,其主要作用是作为nn.

  • Module中的可训练参数使用。它与torch.Tensor的区别就是nn.Parameter会自动被认为是module的可训练参数,即加入到parameter()这个迭代器中去;而module中非nn.Parameter()的普通tensor是不在parameter中的。

  • nn.Parameter的对象的requires_grad属性的默认值是True,即是可被训练的,这与torh.Tensor对象的默认值相反。

  • 在nn.Module类中,pytorch也是使用nn.Parameter来对每一个module的参数进行初始化的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值