torch.nn.utils(nn/utils/)

torch.nn.utils包含一些神经网络的实用工具,如RNN处理、梯度裁剪和权重归一化。clip_grad.py提供梯度裁剪功能,防止梯度爆炸;rnn.py处理RNN序列数据;weight_norm.py实现权重归一化,用于正则化防止过拟合。

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

torch.nn.utils(nn/utils/)

1、先看一下utils目录下的文件

这里写图片描述
包括3个文件 init.py, rnn.py, clip_grad.py, weight_norm.py
这里面是一些nn的工具,比如rnn中的序列打包成PackedSequence和解包还原成程度不等序列

2、init.py
     from . import rnn
     from .clip_grad import clip_grad_norm
     from .weight_norm import weight_norm, remove_weight_norm
     #三句分别从当前目录的三个文件当中导入需要的函数或者类
     #下面先看clip_grad.py
3、clip_grad.py
def clip_grad_norm(parameters, max_norm, norm_type=2):
     #修剪可迭代Parameters的梯度范数
     #范数由所有梯度共同计算得到, 把它们看做一个向量。
     #梯度被in-place operation修改。
     #参数:
     #parameters (Iterable[Variable]): 要进行梯度归一化的可迭代的
     #                                 变量Variable
     #max_norm (float or int):              梯度的最大范数
     #norm_type (float or int):             p范数类型'inf' 代表无穷范数.
     #返回值:
     #所有参数的范数 (看成一个向量).
     parameters = list(filter(lambda p: p.grad is not None, parameters))
     max_norm = float(max_norm)
     norm_type = float(norm_type)
     if norm_type == float('inf'):
          total_norm = max(p.grad.data.abs().max() for p in parameters)      #无穷范数||X||inf = max(|Xi|)
     else:
          total_norm = 0
          for p in parameters:
               param_norm = p.grad.data.norm(norm_type)                              
               #tensor.norm(p)   计算p范数
               total_norm += param_norm ** norm_type
          total_norm = total_norm ** (1. / norm_type)                                     
          #||X||p = Σ(Xi ** p) ** (1/p)
     clip_coef = max_norm / (total_norm + 1e-6)                                          
     #防止total_norm等于0
     if clip_coef < 1:
          for p in parameters:
               p.grad.data.mul_(clip_coef)
     return total_norm

这个函数的作用是归一化p范数到max_norm,使得parameters的参数的p范数和为max_norm.默认为2范数,返回值为所有参数梯度的p范数
Gradient Clipping的引入是为了处理gradient explosion或者gradients vanishing的问题。
当在一次迭代中权重的更新过于迅猛的话,很容易导致loss divergence。Gradient Clipping的直观作用就是让权重的更新限制在一个合适的范围。所以经常在一个epoch之后加入clip_grad_norm在max_norm范围内。

4、rnn.py
from collections import namedtuple                         #namedtuple创建一个tuple对象,具备tuple的不变性,可以根据属性来引用。
import torch
from torch.autograd import Variable

PackedSequence_ = namedtuple('Packed
### 关于 `torch.nn.utils.weight_norm` 被弃用并迁移至 `torch.nn.utils.parametrize` 在 PyTorch 的最新版本中,`torch.nn.utils.weight_norm` 已被标记为废弃功能,并建议开发者将其替换为更灵活的实现方式——即通过 `torch.nn.utils.parametrize` 提供的支持[^3]。以下是有关此更改的具体说明及其迁移方法。 #### 原因分析 `weight_norm` 是一种正则化技术,用于分解权重矩阵为缩放因子和平滑方向向量的形式,从而改善优化过程中的梯度流动特性。然而,原始的 `weight_norm` 实现存在一定的局限性,例如无法很好地支持动态调整权重结构或与其他参数化机制集成。因此,PyTorch 推出了新的模块 `parametrize` 来替代它,提供了更加通用和可扩展的功能集[^4]。 #### 迁移指南 为了将现有的基于 `weight_norm` 的代码迁移到新接口上,可以按照以下方式进行操作: 1. **导入必要的库** 需要引入 `torch.nn.utils.parametrize` 和其他辅助工具。 2. **定义自定义参数化类** 创建一个新的类继承自 `torch.nn.Parametrization` 或直接利用现有 API 构建所需的变换逻辑。 3. **注册到目标层** 使用 `.register_parametrization()` 方法绑定该转换器到指定网络层实例之上。 下面给出一段具体的例子演示这一流程: ```python import torch from torch import nn from torch.nn.utils import parametrize class WeightNorm(nn.Module): def __init__(self, weight_shape): super().__init__() self.g = nn.Parameter(torch.ones(weight_shape[:1])) self.v = nn.Parameter(torch.randn(weight_shape)) def forward(self, input_): normalized_weight = self.g * (self.v / torch.norm(self.v)) return torch.matmul(input_, normalized_weight) # Example usage with Linear layer linear_layer = nn.Linear(5, 3) original_weight = linear_layer.weight.data.clone() # Apply the new parameterization scheme. parametrize.register_parametrization(linear_layer, 'weight', WeightNorm(original_weight.shape)) input_tensor = torch.rand((7, 5)) # Batch size of 7 and feature dimensionality of 5 output_tensor = linear_layer(input_tensor) # Forward pass through modified layer. print(output_tensor) ``` 上述脚本展示了如何构建一个简单的权重规范化组件并与标准线性映射相结合的过程[^5]。 #### 总结 随着框架的发展演进,某些早期设计可能不再满足日益增长的需求而被淘汰出局;但是官方通常会提供相应的升级路径帮助用户平稳过渡。对于本次讨论的主题而言,“从旧版 `weight_norm` 到新版 `parametrize`”正是这样一个典型范例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值