【PyTorch学习笔记】 模型模块01——Module & Paramete介绍

Module & parameter

Module

Module是所有神经网络的基类,所有的模型必须继承与Module类

1. Module类的基本结构

Module类是PyTorch中最重要的类,它提供了一种方式来创建和管理包含可训练参数的神经网络层。主要特点:

  • 包含可训练参数(Parameter)和持久缓冲区(Buffer)
  • 可以包含其他Module作为子模块
  • 支持GPU加速和分布式训练

Module类使用8个有序字典(OrderedDict)来管理不同类型的属性和功能:

  • _parameters: 存储所有的可训练参数(Parameter对象),这些参数会在反向传播中自动计算梯度
  • _buffers: 存储模型的固定缓冲区,比如BatchNorm层中的running_mean,这些不参与梯度计算
  • _modules: 存储所有的子模块(子层),允许模型具有层次化的结构
  • _non_persistent_buffers_set: 存储非持久化缓冲区的集合,这些缓冲区在模型保存时不会被保存
  • _backward_hooks: 存储反向传播钩子函数,用于自定义梯度计算过程
  • _forward_hooks: 存储前向传播钩子函数,用于监控和修改前向传播过程
  • _forward_pre_hooks: 存储前向传播前的钩子函数,在forward函数调用前执行
  • _state_dict_hooks: 存储状态字典钩子函数,用于自定义状态字典的保存和加载行为

这些有序字典的使用确保了:

  • 参数和缓冲区的有序性和可追踪性
  • 模型结构的层次化管理
  • 灵活的钩子机制以支持自定义行为
  • 高效的状态保存和加载机制

2. 类的继承

创建自定义神经网络模型时,需要继承nn.Module类:

import torch.nn as nn

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        # 初始化层和参数
        
    def forward(self, x):
        # 定义前向传播
        return x

3. 重要方法

  • init(): 初始化模型,定义层和参数
  • forward(): 定义前向传播过程
  • parameters(): 返回模型的所有参数
  • state_dict(): 返回模型的状态字典
  • eval(): 设置为评估模式
  • train(): 设置为训练模式

4. 具体案例:简单的神经网络

下面是一个包含两个隐藏层的简单神经网络示例:

import torch
import torch.nn as nn

class SimpleNet(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleNet, self).__init__()
        # 定义网络层
        self.layer1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.layer2 = nn.Linear(hidden_size, hidden_size)
        self.output = nn.Linear(hidden_size, output_size)
        
    def forward(self, x):
        # 定义前向传播
        x = self.layer1(x)
        x = self.relu(x)
        x = self.layer2(x)
        x = self.relu(x)
        x = self.output(x)
        return x

# 创建模型实例
model = SimpleNet(input_size=10, hidden_size=20, output_size=2)

# 打印模型结构
print(model)

# 获取模型参数
for name, param in model.named_parameters():
    print(f"Layer: {name} | Size: {param.size()}")

运行结果:

详细解释这段代码的调用流程:

  1. 实例化过程
  • 当执行 model = SimpleNet(input_size=10, hidden_size=20, output_size=2) 时:
    • 调用__init__方法
    • 通过super()初始化父类nn.Module
    • 创建三个线性层(layer1, layer2, output)和ReLU激活函数
  1. 前向传播的触发机制
  • 当我们使用model(input)形式调用时,实际上发生了这些步骤:
    • PyTorch会先调用模型的__call__方法(这是从nn.Module继承的)
    • __call__会进行一些准备工作(比如检查训练模式)
    • 然后自动调用我们定义的forward方法
  1. 数据在forward中的流动过程:
  • 输入数据x首先传入layer1进行线性变换(10维→20维)
  • 经过ReLU激活函数处理
  • 进入layer2进行第二次线性变换(20维→20维)
  • 再次经过ReLU激活函数
  • 最后通过output层(20维→2维)得到最终输出

这种设计模式使得模型的使用非常简洁,用户只需要关注forward中的逻辑实现,而不需要关心底层的调用机制。

5.构建网络的步骤

到这里一个模型的搭建就很清晰了,构建自己的网络只需要三步:

  1. 写一个类继承于Module

  2. init函数中把需要的网络层创建好

  3. forward函数中把模型如何搭建的规则写好

Parameter

parameter,即参数,它是Module中非常重要的一个对象,继承与Tensor,但是与常规的Tensor不一样,这个参数表示模型的权重和偏置,是可以通过反向传播算法去不断更新的。Module中对于参数是采用_parameters 进行管理的,并且提供相应的api可以对module内所有参数进行调用与读取。

1. Parameter对象的基本概念

Parameter是PyTorch中专门用于存储和管理可训练参数的类,它具有以下特点:

  • 继承自torch.Tensor,具有张量的所有特性
  • 默认requires_grad=True,表示该参数需要计算梯度
  • 会自动被添加到模型的参数列表中,便于统一管理

2. Parameter的创建和使用

有两种方式创建Parameter:

  • 直接使用nn.Parameter()创建
  • 通过nn.Module中的register_parameter()方法注册
import torch
import torch.nn as nn

class CustomLayer(nn.Module):
    def __init__(self, in_features, out_features):
        super(CustomLayer, self).__init__()
        
        # 方式1:直接创建Parameter
        self.weight = nn.Parameter(torch.randn(in_features, out_features))
        self.bias = nn.Parameter(torch.zeros(out_features))
        
        # 方式2:使用register_parameter注册
        self.register_parameter('custom_param', 
                              nn.Parameter(torch.ones(out_features)))
    
    def forward(self, x):
        return torch.mm(x, self.weight) + self.bias + self.custom_param

# 创建实例
layer = CustomLayer(3, 2)

# 查看所有参数
for name, param in layer.named_parameters():
    print(f"Parameter name: {name}")
    print(f"Parameter shape: {param.shape}")
    print(f"Requires grad: {param.requires_grad}")
    print("---")

3. Parameter的特性和管理

  • 自动梯度计算: Parameter默认会跟踪梯度,用于反向传播
  • 参数管理: 可以通过模型的parameters()或named_parameters()方法访问
  • 状态保存: 会被自动包含在模型的state_dict中
  • 设备迁移: 使用model.to(device)时会自动转移到指定设备

4. Parameter与普通Tensor的区别

以下是Parameter和普通Tensor的主要区别:

特性ParameterTensor
梯度计算默认需要梯度默认不需要梯度
模型参数管理自动加入参数组不会被模型追踪
保存和加载自动包含在state_dict中需要手动处理

5. 实践建议

  • 需要训练和更新的参数应该使用Parameter
  • 模型中的权重和偏置通常都是Parameter
  • 固定的常量或临时变量使用普通Tensor即可
  • 使用parameters()方法进行优化器参数设置

这是一个使用parameters()方法设置优化器参数的例子:

import torch
import torch.nn as nn
import torch.optim as optim

# 定义模型
model = SimpleNet(input_size=10, hidden_size=20, output_size=2)

# 创建优化器,将模型的所有参数传入
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 或者也可以指定特定参数的学习率
optimizer = optim.SGD([
    {'params': model.layer1.parameters(), 'lr': 0.01},
    {'params': model.layer2.parameters(), 'lr': 0.001}
], lr=0.001)

通过model.parameters()方法,优化器可以自动获取并管理模型中所有需要更新的参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

越轨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值