gpt4 book ai didi

python - 如何计算参数的谱范数?

转载 作者:行者123 更新时间:2023-12-04 02:41:35 25 4
gpt4 key购买 nike

当我做,

import torch, torch.nn as nn
x = nn.Linear(3, 3)
y = torch.nn.utils.spectral_norm(x)

然后它给出四个不同的权重矩阵,
y.weight_u
tensor([ 0.6534, -0.1644,  0.7390])
y.weight_orig
Parameter containing:
tensor([[ 0.2538, 0.3196, 0.3380],
[ 0.4946, 0.0519, 0.1022],
[-0.5549, -0.0401, 0.1654]], requires_grad=True)
y.weight_v
tensor([-0.3650,  0.2870,  0.8857])
y.weight
tensor([[ 0.5556,  0.6997,  0.7399],
[ 1.0827, 0.1137, 0.2237],
[-1.2149, -0.0878, 0.3622]], grad_fn=<DivBackward0>)

这四个矩阵是如何计算的?

最佳答案

我刚刚读完了关于这种方法的论文,可以找到 on arxiv .如果您有适当的数学背景,我建议您阅读它。有关描述 u 和 v 是什么的幂算法,请参见附录 A。

也就是说,我将在这里进行总结。

首先,您应该知道矩阵的谱范数是最大奇异值。作者建议寻找权重矩阵的谱范数 W ,然后除以 W通过其频谱范数使其接近 1 (该决定的理由在论文中)。

虽然我们可以使用 torch.svd为了找到奇异值的精确估计,他们使用一种称为“幂迭代”的快速(但不精确)方法。长话短说,weight_uweight_v是对应于 W 的最大奇异值的左右奇异向量的粗略近似值。它们很有用,因为相关的奇异值,即 W 的谱范数等于 u.transpose(1,0) @ W @ v如果 uvW 的实际左/右奇异向量.

  • y.weight_orig包含图层中的原始值。
  • y.weight_uy.weight_orig的第一个左奇异向量的近似值.
  • y.weight_vy.weight_orig的第一个右奇异向量的近似值.
  • y.weight是更新后的权重矩阵,即 y.weight_orig除以它的近似谱范数。

  • 我们可以通过显示实际的左右奇异向量几乎平行于 y.weight_u 来验证这些说法。和 y.weight_v
    import torch
    import torch.nn as nn

    # pytorch default is 1
    n_power_iterations = 1

    y = nn.Linear(3,3)
    y = nn.utils.spectral_norm(y, n_power_iterations=n_power_iterations)

    # spectral normalization is performed during forward pre hook for technical reasons, we
    # need to send something through the layer to ensure normalization is applied
    # NOTE: After this is performed, x.weight is changed in place!
    _ = y(torch.randn(1,3))

    # test svd vs. spectral_norm u/v estimates
    u,s,v = torch.svd(y.weight_orig)
    cos_err_u = 1.0 - torch.abs(torch.dot(y.weight_u, u[:, 0])).item()
    cos_err_v = 1.0 - torch.abs(torch.dot(y.weight_v, v[:, 0])).item()
    print('u-estimate cosine error:', cos_err_u)
    print('v-estimate cosine error:', cos_err_v)

    # singular values
    actual_orig_sn = s[0].item()
    approx_orig_sn = (y.weight_u @ y.weight_orig @ y.weight_v).item()
    print('Actual original spectral norm:', actual_orig_sn)
    print('Approximate original spectral norm:', approx_orig_sn)

    # updated weights singular values
    u,s_new,v = torch.svd(y.weight.data, compute_uv=False)
    actual_sn = s_new[0].item()
    print('Actual updated spectral norm:', actual_sn)
    print('Desired updated spectral norm: 1.0')

    这导致
    u-estimate cosine error: 0.00764310359954834
    v-estimate cosine error: 0.034041762351989746
    Actual original spectral norm: 0.8086231350898743
    Approximate original spectral norm: 0.7871124148368835
    Actual updated spectral norm: 1.0273288488388062
    Desired updated spectral norm: 1.0

    增加 n_power_iterations参数将以计算时间为代价提高估计的准确性。

    关于python - 如何计算参数的谱范数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59123577/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com