『PyTorch』第十四弹_torch.nn.Module类属性

本文深入探讨了PyTorch中nn.Module基类的构造函数及其关键属性,包括_parameters、_modules、_buffers和training的作用与使用方法。通过具体示例展示了如何通过这些属性管理网络参数、子模块和缓存,以及如何控制训练和测试阶段的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

nn.Module基类的构造函数:

def __init__(self):
    self._parameters = OrderedDict()
    self._modules = OrderedDict()
    self._buffers = OrderedDict()
    self._backward_hooks = OrderedDict()
    self._forward_hooks = OrderedDict()
    self.training = True

其中每个属性的解释如下:

_parameters:字典,保存用户直接设置的parameter,self.param1 = nn.Parameter(t.randn(3, 3))会被检测到,在字典中加入一个key为’param’,value为对应parameter的item。而self.submodule = nn.Linear(3, 4)中的parameter则不会存于此。
_modules:子module,通过self.submodel = nn.Linear(3, 4)指定的子module会保存于此。
_buffers:缓存。如batchnorm使用momentum机制,每次前向传播需用到上一次前向传播的结果。
_backward_hooks与_forward_hooks:钩子技术,用来提取中间变量,类似variable的hook。
training:BatchNorm与Dropout层在训练阶段和测试阶段中采取的策略不同,通过判断training值来决定前向传播策略。
上述几个属性中,_parameters、_modules和_buffers这三个字典中的键值,都可以通过self.key方式获得,效果等价于self._parameters[‘key’].

定义一个Module,这个Module即包含自己的Parameters有包含子Module及其Parameters,

import torch as t
from torch import nn
from torch.autograd import Variable as V
 
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        # 等价与self.register_parameter('param1' ,nn.Parameter(t.randn(3, 3)))
        self.param1 = nn.Parameter(t.rand(3, 3))
        self.submodel1 = nn.Linear(3, 4)
    def forward(self, input):
        x = self.param1.mm(input)
        x = self.submodel11(x)
        return x
net = Net()

回到顶部
一、_modules

# 打印网络对象的话会输出子module结构
print(net)

Net(
(submodel1): Linear(in_features=3, out_features=4)
)

._modules输出的也是子module结构,不过数据结构和上面的有所不同

print(net.submodel1)
print(net._modules) # 字典子类

Linear(in_features=3, out_features=4)
OrderedDict([(‘submodel1’, Linear(in_features=3, out_features=4))])

for name, submodel in net.named_modules():
    print(name, submodel)

Net(
(submodel1): Linear(in_features=3, out_features=4)
)
submodel1 Linear(in_features=3, out_features=4)
print(list(net.named_modules())) # named_modules其实是包含了本层的module集合

[(’’, Net(
(submodel1): Linear(in_features=3, out_features=4)
)), (‘submodel1’, Linear(in_features=3, out_features=4))]
回到顶部
二、_parameters

# ._parameters存储的也是这个结构

    print(net.param1)
    print(net._parameters) # 字典子类,仅仅包含直接定义的nn.Parameters参数

Parameter containing:
0.6135 0.8082 0.4519
0.9052 0.5929 0.2810
0.6825 0.4437 0.3874
[torch.FloatTensor of size 3x3]

OrderedDict([(‘param1’, Parameter containing:
0.6135 0.8082 0.4519
0.9052 0.5929 0.2810
0.6825 0.4437 0.3874
[torch.FloatTensor of size 3x3]
)])

for name, param in net.named_parameters():
    print(name, param.size())

param1 torch.Size([3, 3])
submodel1.weight torch.Size([4, 3])
submodel1.bias torch.Size([4])
回到顶部
三、_buffers

bn = nn.BatchNorm1d(2)
input = V(t.rand(3, 2), requires_grad=True)
output = bn(input)
bn._buffers

OrderedDict([(‘running_mean’,
1.00000e-02 *
9.1559
1.9914
[torch.FloatTensor of size 2]), (‘running_var’,
0.9003
0.9019
[torch.FloatTensor of size 2])])
回到顶部
四、training

input = V(t.arange(0, 12).view(3, 4))
model = nn.Dropout()
# 在训练阶段,会有一半左右的数被随机置为0

    model(input)

Variable containing:
0 2 4 0
8 10 0 0
0 18 0 22
[torch.FloatTensor of size 3x4]

model.training  = False
# 在测试阶段,dropout什么都不做
model(input)
Variable containing:

0 1 2 3
4 5 6 7
8 9 10 11
[torch.FloatTensor of size 3x4]
Module.train()、Module.eval() 方法和 Module.training属性的关系

print(net.training, net.submodel1.training)
net.train() # 将本层及子层的training设定为True
net.eval() # 将本层及子层的training设定为False
net.training = True # 注意,对module的设置仅仅影响本层,子module不受影响
net.training, net.submodel1.training

True True
(True, False)

### PyTorch 中 `torch.nn.utils.weight_norm` 的弃用情况 在 PyTorch 的开发历程中,某些功能可能会被标记为过时并最终移除。关于 `torch.nn.utils.weight_norm` 的具体弃用版本信息,在官方文档和社区讨论中并未明确指出其完全废弃的时间点[^1]。然而,可以确认的是,自 PyTorch 1.7 版本起,`weight_norm` 功能已被推荐使用更灵活的替代方案——通过 `nn.Parameter` 或者其他模块化设计来实现权重标准化的效果。 #### 替代方案 对于需要实现类似 `weight_norm` 功能的需求,开发者通常会采用以下几种方式: 1. **手动实现权重规范化** 可以通过定义新的参数并将原始权重分解为其大小和方向部分来模拟 `weight_norm` 的行为。例如: ```python import torch import torch.nn as nn class WeightNormLinear(nn.Module): def __init__(self, in_features, out_features): super(WeightNormLinear, self).__init__() self.weight_v = nn.Parameter(torch.randn(out_features, in_features)) self.weight_g = nn.Parameter(torch.ones(out_features)) self.bias = nn.Parameter(torch.zeros(out_features)) def forward(self, x): weight_normalized = self.weight_g.unsqueeze(-1) * (self.weight_v / torch.norm(self.weight_v, dim=-1, keepdim=True)) return torch.matmul(x, weight_normalized.t()) + self.bias ``` 2. **利用 Spectral Normalization** 如果目标是为了控制模型的 Lipschitz 常数,可以考虑使用谱归一化(Spectral Normalization),它可以通过 `torch.nn.utils.spectral_norm` 实现类似的约束效果[^4]。 3. **基于最新 API 进行重构** 自 PyTorch 高级优化器引入以来,许多旧的功能逐渐被淘汰。因此建议重新评估需求,并尝试借助更高层次的设计模式完成相同的目标。 需要注意的是,尽管目前尚未有确切记录表明某个特定版本正式删除了该函数,但在实际项目维护过程中应尽量避免依赖已标注为 deprecated 的特性[^5]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值