【pytorch】weight_norm和spectral_norm

apply_parametrization_normspectral_norm是 PyTorch 中用于对模型参数进行规范化的方法,但它们在实现和使用上有显著的区别。以下是它们的主要区别和对比:

实现方式

weight_norm:

weight_norm 是一种参数重参数化技术,将权重分解为两个部分:方向(v) 和 大小(g)。
具体来说,权重 w 被重参数化为:
w=g⋅
∥v∥
v

其中,g 是标量,表示权重的大小;v 是向量,表示权重的方向。
这种方法通过分离权重的大小和方向,使得优化过程更加稳定。

归一化后的权重向量实际上是 v 的归一化形式,即 v_normalized = v / ||v||,而 weight 的值为 g * v_normalized

spectral_norm:

spectral_norm 是一种基于谱范数的规范化方法,谱范数定义为矩阵 M 的最大奇异值:

在这里插入图片描述

具体来说,谱范数是矩阵 M 作用在单位向量上时的最大放大因子。

作用:通过限制矩阵的最大奇异值,控制矩阵的放大能力,从而提高模型的稳定性和泛化能力

通过幂迭代法(Power Iteration)计算矩阵的最大奇异值。具体步骤如下:
初始化两个向量 u 和 v。
迭代计算:
在这里插入图片描述

最大奇异值 在这里插入图片描述

然后将权重规范化为
在这里插入图片描述

使用场景

weight_norm:

主要用于规范化权重,特别适用于需要控制权重大小的场景。
例如,在某些生成模型或自注意力机制中,权重的大小对模型的稳定性和性能有重要影响。
weight_norm 提供了一种简单且直接的方式来实现权重的规范化。

spectral_norm:

常用于生成对抗网络(GAN)中,通过限制生成器和判别器的最大奇异值,提高模型的稳定性和泛化能力。
优点:能够有效控制矩阵的放大能力,适用于需要限制模型输出范围的场景

代码样例

weight_norm:

import random
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.utils.weight_norm as weight_norm

# 创建一个简单的线性层
linear_layer = nn.Linear(2, 3)

# Override the weights of linear_layer
linear_layer.weight.data = torch.tensor([[0, -2e-2], [0.3, 1.0], [1e-2, 0]], dtype=torch.float32)  # 3x2
linear_layer.bias.data = torch.tensor([-0.3, 0, -2e-2], dtype=torch.float32)  # 3x1

# Apply weight normalization
linear_layer = weight_norm(linear_layer, name='weight')

optimizer = optim.Adam(linear_layer.parameters(), lr=2e-3)

# 打印原始权重
print("################原始权重:################")
print("linear_layer.weight_v: ", linear_layer.weight_v)
print("linear_layer.weight_g: ", linear_layer.weight_g)
print("linear_layer.weight: ", linear_layer.weight)
print("linear_layer.bias: ", linear_layer.bias)

# 前向传播
for i in range(1000):
    input_tensor = torch.randn(10, 2) * random.random() * 10
    output = linear_layer(input_tensor)
    loss = (1 - output.mean())
    optimizer.zero_grad()
    loss.backward()  # 反向传播,触发梯度计算
    optimizer.step()

# 打印规范化后的权重
print("################规范化后的权重:#################")
print("linear_layer.weight_v: ", linear_layer.weight_v)
print("linear_layer.weight_g: ", linear_layer.weight_g)
print("linear_layer.bias: ", linear_layer.bias)

# Optionally, print the effective weight
print("linear_layer.weight (effective): ", linear_layer.weight)

# ... existing code...



# 前向传播
#input_tensor = torch.tensor([[1.0, 2.0]], dtype=torch.float32)  # 1x2
for i in range(1000):
    input_tensor = torch.randn(10, 2)*random.random()*10
    output = linear_layer(input_tensor)
    optimizer.zero_grad()
    (1-output.mean()).backward()  # 反向传播,触发梯度计算
    optimizer.step()  # 更新权重
    output = linear_layer(input_tensor)
    optimizer.zero_grad()
    (1-output.mean()).backward()  # 反向传播,触发梯度计算
    optimizer.step()  # 更新权重


# 打印规范化后的权重
print("################规范化后的权重:#################")
print("linear_layer.weight: ", linear_layer.weight)  # 权重的大小
print("linear_layer.bias: ", linear_layer.bias) 
print("linear_layer.weight_v: ", linear_layer.weight_v)  
print("linear_layer.weight_g: ", linear_layer.weight_g) 



输出结果

################原始权重:################
linear_layer.weight_v:  Parameter containing:
tensor([[ 0.0000, -0.0200],
        [ 0.3000,  1.0000],
        [ 0.0100,  0.0000]], requires_grad=True)
linear_layer.weight_g:  Parameter containing:
tensor([[0.0200],
        [1.0440],
        [0.0100]], requires_grad=True)
linear_layer.weight:  tensor([[ 0.0000, -0.0200],
        [ 0.3000,  1.0000],
        [ 0.0100,  0.0000]], grad_fn=<WeightNormInterfaceBackward0>)
linear_layer.bias:  Parameter containing:
tensor([-0.3000,  0.0000, -0.0200], requires_grad=True)
################规范化后的权重:#################
linear_layer.weight_v:  Parameter containing:
tensor([[0.0599, 0.0568],
        [0.4113, 0.8878],
        [0.0544, 0.0556]], requires_grad=True)
linear_layer.weight_g:  Parameter containing:
tensor([[0.1038],
        [1.1324],
        [0.0897]], requires_grad=True)
linear_layer.bias:  Parameter containing:
tensor([1.7000, 2.0000, 1.9800], requires_grad=True)
linear_layer.weight (effective):  tensor([[0.0751, 0.0716],
        [0.4758, 1.0276],
        [0.0625, 0.0643]], grad_fn=<WeightNormInterfaceBackward0>)

spectral_norm:

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.utils.weight_norm as spectral_norm

# 创建一个简单的线性层
linear_layer = nn.Linear(2, 3)
# 覆盖线性层的权重
linear_layer.weight.data = torch.tensor([[0, -2e2], [0.3, 1.0], [1e2, 0]], dtype=torch.float32)  # 3x2
linear_layer.bias.data = torch.tensor([-0.3, 0, -2e2], dtype=torch.float32)  # 3x1

# 应用 weight_norm
linear_layer = spectral_norm(linear_layer, name='weight')

# 定义优化器
optimizer = optim.Adam(linear_layer.parameters(), lr=1e-4)

# 打印原始权重
print("\n################ 原始权重:################\n")
print("linear_layer.weight: ", linear_layer.weight)
print("linear_layer.bias: ", linear_layer.bias)

# 前向传播及训练
for i in range(1000):
    input_tensor = torch.randn(10, 2)
    output = linear_layer(input_tensor)
    loss = (1 - output.mean())  # 损失函数
    optimizer.zero_grad()
    loss.backward()  # 反向传播
    optimizer.step()  # 更新权重

# 打印规范化后的权重
print("\n################ 规范化后的权重:################\n")
print("linear_layer.weight: ", linear_layer.weight)  # 权重的大小
print("linear_layer.bias: ", linear_layer.bias)
print("linear_layer.weight_v: ", linear_layer.weight_v)  
print("linear_layer.weight_g: ", linear_layer.weight_g)

输出结果

################ 原始权重:################

linear_layer.weight:  tensor([[   0.0000, -200.0000],
        [   0.3000,    1.0000],
        [ 100.0000,    0.0000]], grad_fn=<WeightNormInterfaceBackward0>)
linear_layer.bias:  Parameter containing:
tensor([  -0.3000,    0.0000, -200.0000], requires_grad=True)

################ 规范化后的权重:################

linear_layer.weight:  tensor([[-1.7618e-04, -2.0000e+02],
        [ 2.9977e-01,  9.9956e-01],
        [ 1.0000e+02, -3.6516e-04]], grad_fn=<WeightNormInterfaceBackward0>)
linear_layer.bias:  Parameter containing:
tensor([-2.0001e-01,  1.0000e-01, -1.9989e+02], requires_grad=True)
linear_layer.weight_v:  Parameter containing:
tensor([[-2.0177e-04, -2.0001e+02],
        [ 2.9990e-01,  1.0001e+00],
        [ 1.0001e+02, -3.7132e-04]], requires_grad=True)
linear_layer.weight_g:  Parameter containing:
tensor([[200.0006],
        [  1.0435],
        [ 99.9998]], requires_grad=True)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/971182.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

unity学习44:学习Animator 的一个动作捕捉网站,实测好用

目录 1 动作捕捉网站 2 注册和下载 3 比如首页的内容&#xff0c;可以直接下载为fbx模型文件 4 上传并修改 5 在 unity里使用 5.1 下载的fbx文件直接拖入到unity 5.2 动画修改 5.3 游戏里播放 1 动作捕捉网站 一个动作捕捉网站 AI神器集合网站 千面视频动捕 | AI神器…

云原生(五十五) | ECS中自建数据库迁移到RDS

文章目录 ECS中自建数据库迁移到RDS 一、场景说明 二、ECS中自建数据库迁移到RDS实现步骤 三、 创建wordpress数据库 四、登录ECS导出wordpress数据库 五、返回RDS数据库管理控制台 六、开启外网地址并设置白名单 七、获取RDS外网访问地址 八、重新设置wordpress的wp-…

【NLP 22、语言模型 language model】

有时候我也想听听&#xff0c;我在你心里&#xff0c;是什么样子 —— 25.1.12 一、什么是语言模型 语言是灵活的&#xff0c;也是有规律的 了解一门语言的人可以判断一句话是否“合理” 通俗来讲&#xff0c;语言模型用来评价一句话(句子可以看作是字的组合)是否“合理”或…

qt + opengl 给立方体增加阴影

在前几篇文章里面学会了通过opengl实现一个立方体&#xff0c;那么这篇我们来学习光照。 风氏光照模型的主要结构由3个分量组成&#xff1a;环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子&#xff1a; 1 环境光照(Ambient …

【鱼眼镜头12】Scaramuzza的鱼眼相机模型实操,不依赖于具体的相机几何结构,直接从图像数据出发,因此更具灵活性。

文章目录 Scaramuzza相机模型标定效果2、原理和代码代码1、 2D映射到3D&#xff0c;函数输入为2D点坐标OCAM参数代码功能详解2、3D --> 2D 3、总结Scaramuzza 模型的核心思想Scaramuzza 模型的核心思想与 Kannala-Brandt 模型的对比Scaramuzza 模型的独特之处Scaramuzza 的意…

【Linux】【进程】epoll内核实现总结+ET和LT模式内核实现方式

【Linux】【网络】epoll内核实现总结ET和LT模式内核实现方式 1.epoll的工作原理 eventpoll结构 当某一进程调用epoll_create方法时&#xff0c;Linux内核会创建一个eventpoll结构体&#xff0c;这个结构体中有两个成员与epoll的使用方式密切相关. struct eventpoll{..../*红…

android 自定义view时钟显示

一、前言 1、圆形数字显示1到12,有指针,分针,秒针。定时器秒针跳动。 2、使用自定义view,继承view实现。 3、使用attr配置属性。 二、效果图 三、代码实现 属性配置 <?xml version="1.0" encoding="utf-8"?> <resources><decla…

使用 DeepSeek 生成商城流程图

步骤 1.下载 mermaid 2.使用 DeepSeek 生成 mermaid 格式 3.复制内容到 4.保存备用。 结束。

数据结构 day06

数据结构 day06 6. 双向链表6.3. 双向循环链表 7. 树 tree7.1. 特点7.1.1. 什么是树7.1.2. 树的特性7.1.3. 关于树的一些术语 7.2. 二叉树7.2.1. 什么是二叉树7.2.2. 二叉树的性质7.2.3. 满二叉树和完全二叉树的区别7.2.4. 二叉树的遍历&#xff08;画图&#xff09;7.2.5. 二叉…

机械学习基础-5.分类-数据建模与机械智能课程自留

data modeling and machine intelligence - CLASSIFICATION 为什么我们不将回归技术用于分类&#xff1f;贝叶斯分类器&#xff08;The Bayes Classifier&#xff09;逻辑回归&#xff08;Logistic Regression&#xff09;对逻辑回归的更多直观理解逻辑 /sigmoid 函数的导数我们…

音频进阶学习十三——Z变换二(有理z变换、稳定性与反变换)

文章目录 前言一、有理Z变换1.定义2.作用3.LTI系统的传递函数1&#xff09;传递函数的定义2&#xff09;差分方程转换传递函数 二、极点和零点1.有理分式的极点和零点2.稳定性实例 二、逆Z变换1.观察法2.部分分式展开法1&#xff09;定义2&#xff09;举例 3.幂级数法/长除法1&…

centos部署open-webui

提示&#xff1a;本文将简要介绍一下在linux下open-webui的安装过程,安装中未使用虚拟环境。 文章目录 一、open-webui是什么&#xff1f;二、安装流程1.openssl升级2.Python3.11安装3.sqlite安装升级4.pip 下载安装open-webui 总结 一、open-webui是什么&#xff1f; Open W…

DeepSeek R1 32B 本地部署实战

#DeepSeek# DeepSeek是一款基于人工智能的智能助手&#xff0c;专为提升工作效率和信息获取能力而设计。它结合了自然语言处理、机器学习和大数据技术&#xff0c;能够快速理解用户需求并提供精准的答案或解决方案。 DeepSeek的核心功能 智能问答 DeepSeek可以回答各种问题&…

day09_实时类标签/指标

文章目录 day09_实时类标签/指标一、日志数据实时采集2、Flume简介2.3 项目日志数据采集Flume配置2.3.1 涉及的Flume组件和参数2.3.2 Nginx日志采集2.3.3 用户行为日志采集 二、Nginx日志数据统计1、日志格式说明2、数据ETL2.1 日志抽取2.1.1 正则表达式2.1.2 基于Spark实现Ngi…

硬件学习笔记--41 电磁兼容试验-5 射频场感应的传导干扰试验介绍

目录 电磁兼容试验-射频场感应的传导干扰试验介绍 1.试验目的 2.试验方法 3.判定依据及意义 电磁兼容试验-射频场感应的传导干扰试验介绍 驻留时间是在规定频率下影响量施加的持续时间。被试设备&#xff08;EUT&#xff09;在经受扫频频带的电磁影响量或电磁干扰的情况下&a…

告别卡关!XSS挑战之旅全关卡通关思路详解

XSS挑战之旅 XSS测试思路Level1Level2Level3Level4Level5Level6Level7Level8Level9Level10Level11Level12Level13Level14Level15Level16Level17Level18Level19Level20免责声明&#xff1a; XSS测试思路 确定输入输出点&#xff1a; 寻找URL参数、表单输入、HTTP头&#xff08;R…

连锁企业管理系统的五大核心功能

连锁管理系统对于连锁企业的运营和发展至关重要&#xff0c;以下以核货宝连锁管理系统为例&#xff0c;介绍其五大核心功能&#xff1a; 门店管理功能 门店信息管理&#xff1a;核货宝连锁管理系统可集中管理所有门店的详细信息&#xff0c;包括门店地址、联系方式、营业时间、…

【第12章:深度学习与伦理、隐私—12.4 深度学习与伦理、隐私领域的未来挑战与应对策略】

凌晨三点的自动驾驶测试场,AI系统突然在暴雨中做出惊人决策——它选择撞向隔离带而不是紧急变道,因为算法推演发现隔离带后的应急车道站着五个工程师。这个惊悚的伦理困境,揭开了深度学习伦理危机最尖锐的冰山一角。 一、潘多拉魔盒已开:深度学习伦理的四大原罪 1.1 数据原…

深度学习(1)-简单神经网络示例

我们来看一个神经网络的具体实例&#xff1a;使用Python的Keras库来学习手写数字分类。在这个例子中&#xff0c;我们要解决的问题是&#xff0c;将手写数字的灰度图像&#xff08;28像素28像素&#xff09;划分到10个类别中&#xff08;从0到9&#xff09;​。我们将使用MNIST…

腿足机器人之八- 腿足机器人动力学

腿足机器人之八- 腿足机器人动力学 刚体动力学接触动力学与地面交互稳定性判据ZMP(零力矩点)CoM(Center of Mass)捕获点 简化动力学模型双足机器人走路与小跑的动力学对比挑战与前沿技术 腿足机器人的运动学解决“如何到达目标位置”的问题&#xff0c;动力学解决“如何高效稳定…