权重归一化weight_norm

1. 权重归一化原理

对于网络中一神经元,其输入为 x,输出为 y,计算过程为
y = ϕ ( ω ∗ x + b ) y=\phi(\omega *x+b) y=ϕ(ωx+b)
ω \omega ω为与该神经元连接的权重,通过损失函数与梯度下降对网络进行优化的过程就是求解最优 ω \omega ω的过程。将 ω \omega ω的长度与方向解耦,可以将 ω \omega ω表示为
ω = g v ∣ ∣ v ∣ ∣ , \omega = g\frac{v}{||v||}, ω=gvv,
其中 g g g为标量,其大小等于 ω \omega ω的模长, v ∣ ∣ v ∣ ∣ \frac{v}{||v||} vv为与 ω \omega ω同方向的单位向量,此时,原先训练过程中 ω \omega ω的学习转化为 g g g v v v的学习。假设损失函数以 L L L表示,则 L L L g g g v v v的梯度可以分别表示为,
∇ g L = ∇ g ω ∗ ( ∇ ω L ) T = ∇ ω L ∗ v T ∣ ∣ v ∣ ∣ \nabla_gL=\nabla_g \omega * (\nabla_\omega L)^T = \frac{\nabla_\omega L*v^T}{||v||} gL=gω(ωL)T=vωLvT
∇ v L = ∇ v ω ∗ ∇ ω L = ∂ g ∗ v ∣ ∣ v ∣ ∣ ∂ v ∗ ∇ ω L = g ∗ ∣ ∣ v ∣ ∣ ∣ ∣ v ∣ ∣ 2 ∗ ∇ ω L − g ∗ v ∗ ∂ ∣ ∣ v ∣ ∣ ∂ v ∣ ∣ v ∣ ∣ 2 ∗ ∇ ω L \nabla_vL = \nabla_v\omega*\nabla_\omega L=\frac{\partial \frac{g*v}{||v||}}{\partial v}*\nabla_\omega L=\frac{g*||v||}{||v||^2}*\nabla_\omega L-\frac{g*v*\frac{\partial||v||}{\partial v}}{||v||^2}*\nabla_\omega L vL=vωωL=vvgvωL=v2gvωLv2gvvvωL
因为
∂ ∣ ∣ v ∣ ∣ ∂ v = ∂ ( v T ∗ v ) 0.5 ∂ v = 0.5 ∗ ( v T ∗ v ) − 0.5 ∗ ∂ ( v T ∗ v ) ∂ v = v ∣ ∣ v ∣ ∣ , \frac{\partial||v||}{\partial v}=\frac{\partial (v^T*v)^{0.5}}{\partial v}=0.5*(v^T*v)^{-0.5}*\frac{\partial (v^T*v)}{\partial v}=\frac{v}{||v||}, vv=v(vTv)0.5=0.5(vTv)0.5v(vTv)=vv,
所以
∇ g L = g ∣ ∣ v ∣ ∣ ∗ ∇ ω L − g ∗ ∇ g L ∣ ∣ v ∣ ∣ 2 ∗ v = g ∣ ∣ v ∣ ∣ ∗ M ω ∗ ∇ ω L , \nabla_gL = \frac{g}{||v||}*\nabla_\omega L-\frac{g*\nabla_g L}{||v||^2}*v=\frac{g}{||v||}*M_\omega*\nabla_\omega L, gL=vgωLv2ggLv=vgMωωL,
其中 M ω = I − ω ∗ ω T ∣ ∣ ω ∣ ∣ 2 M_\omega=I-\frac{\omega*\omega^T}{||\omega||^2} Mω=Iω2ωωT,与向量点乘可以投影任意向量至 ω \omega ω的补空间,相对于原先的 ∇ ω L \nabla_\omega L ωL ∇ v L \nabla_v L vL进行了 g ∣ ∣ v ∣ ∣ \frac{g}{||v||} vg的缩放以及 M ω M_\omega Mω的投影,两者对优化过程都起到作用。

2. Pytorch中weight normalization的使用

import torch
import torch.nn as nn

net = nn.Linear(200,10)
net.weight.data

nn.utils.weight_norm(net, name='weight')

net.weight_g.size(),net.weight_v.size()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
weight_norm()是一个用于PyTorch中的函数,它可以对模型中的权重进行归一化处理。使用方法如下: 1. 导入weight_norm函数:from torch.nn.utils import weight_norm 2. 在定义模型的时候,对需要进行归一化处理的权重添加weight_norm函数,例如: class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.conv1 = weight_norm(nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)) self.conv2 = weight_norm(nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)) self.fc1 = weight_norm(nn.Linear(128 * 32 * 32, 1024)) self.fc2 = weight_norm(nn.Linear(1024, 10)) 3. 在训练模型的时候,对模型中的权重进行归一化处理,例如: model = MyModel() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) criterion = nn.CrossEntropyLoss() for epoch in range(num_epochs): for i, (images, labels) in enumerate(train_loader): images = images.to(device) labels = labels.to(device) optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() # 对模型中的权重进行归一化处理 nn.utils.weight_norm(model.conv1, name='weight') nn.utils.weight_norm(model.conv2, name='weight') nn.utils.weight_norm(model.fc1, name='weight') nn.utils.weight_norm(model.fc2, name='weight') 4. 在测试模型的时候,不需要对模型中的权重进行归一化处理,例如: model.eval() with torch.no_grad(): correct = 0 total = 0 for images, labels in test_loader: images = images.to(device) labels = labels.to(device) outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print('Accuracy of the model on the test images: {} %'.format(100 * correct / total))

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值