pytorch Clip_grad_norm_ 工作原理的示例

问题描述 投票:0回答:1

我想要一个简单的例子来说明如何通过clip_grad_norm_进行梯度裁剪。从this帖子中,我发现如果梯度的范数大于阈值,那么它只需取梯度的单位向量并将其与阈值相乘。这就是我尝试过的

v = torch.rand(5)*1000
v_1 = v.clone()
torch.nn.utils.clip_grad_norm_(v_1, max_norm=1.0, norm_type=2)
print(v, v_1)

(tensor([381.2621, 935.3613, 664.9132, 840.0740, 443.0156]),
 tensor([381.2621, 935.3613, 664.9132, 840.0740, 443.0156]))

我以为它会做

v/torch.norm(v, p=2) * 2
这应该给我
tensor([0.2480, 0.6083, 0.4324, 0.5463, 0.2881])

它似乎没有做任何事情。我认为 max_norm 是阈值(pytorch 文档对此不是很清楚。这个帖子也没有太大帮助。

pytorch gradient gradient-exploding
1个回答
1
投票

这是因为

torch.nn.utils.clip_grad_norm
剪切了渐变值(通过
Tensor.grad
访问)而不是值本身。快速使用示例:

v = torch.rand(5) * 1000
v_1 = v.clone()
v.requires_grad_(True)
v_1.requires_grad_(True)

loss = 1/2 * torch.sum(v_1 * v_1 + v * v)
# Here grads of loss w.r.t v and v_1 should be v and v_1 respectively
loss.backward()

# Clip grads of v_1
torch.nn.utils.clip_grad_norm_(v_1, max_norm=1.0, norm_type=2)

print(v.grad)
print(v_1.grad)
print(v.grad / torch.norm(v.grad, p=2))

结果:

tensor([486.8801, 481.7880, 172.6818, 659.4149,  62.8158])  # no clipped
tensor([0.5028, 0.4975, 0.1783, 0.6809, 0.0649])  # clipped!
tensor([0.5028, 0.4975, 0.1783, 0.6809, 0.0649])  # same values
© www.soinside.com 2019 - 2024. All rights reserved.