【问题标题】:Speed of L2 Regularization on PytorchPytorch 上 L2 正则化的速度
【发布时间】:2020-04-15 08:37:31
【问题描述】:

我正在尝试在神经网络中手动实现 L2 正则化及其一些变体。我正在做的事情如下:

for name, param in model.state_dict():
    if 'weight' in name:
        l2_reg += torch.sum(param**2)

loss = cross_entropy(outputs, labels) + 0.0001*l2_reg

这是否等同于在我的优化器中添加“weight_decay = 0.0001”?即:

torch.optim.SGD(model.parameters(), lr=learning_rate , momentum=0.9, weight_decay = 0.0001)

我的问题是我认为它们是等价的,但手动过程比添加“weight_decay = 0.0001”慢了大约 100 倍。这是为什么?我该如何解决?

请注意,我还需要实现我自己的 L2 正则化变体,因此仅添加 'weight_decay = 0.0001' 无济于事。

【问题讨论】:

  • 你确定它们是等价的吗?
  • 不,我不是。我也尝试过使用 torch.norm(param)**2,但它也比在 SGD 函数中添加“weight_decay = lambda”要慢得多。我该如何解决这个问题?

标签: performance neural-network pytorch


【解决方案1】:

您可以查看PyTorch implementation of SGD 以获取该代码的一些提示和基础。

有一些事情可以加快您的自定义正则化。 下面是我们感兴趣的部分的清理版本(有点伪代码,参考原文):

for p in group['params']:
    if p.grad is None:
        continue
    d_p = p.grad.data
    if weight_decay != 0:
        d_p.add_(weight_decay, p.data)

    p.data.add_(-group['lr'], d_p)

return loss

顺便说一句。看来您的实现在数学上是合理的(如果我遗漏了什么,请纠正我)并且相当于 PyTorch,但确实会很慢。

只修改渐变

请注意,您在前向传递期间显式执行正则化。这需要很多时间,或多或少是因为:

  • 获取参数并对其进行迭代
  • 利用2的力量
  • 全部加起来
  • 添加到包含所有先前参数的变量(所有这些都在动态创建图形和创建新节点时)。

pytorch 所做的只是只关注向后传递,因为这就是我们所需要的。这非常方便,因为:

  • 在优化器执行校正期间,无论如何都必须加载和迭代一次参数(在您的情况下,它们被取出两次)
  • 没有2 的力量,因为w**2 的梯度只是2*w2 被进一步省略,L2 通常表示为1/2 * w **2 以使其更简单和更快)李>
  • 不累积和创建额外的图形节点

基本上,这一行:

d_p.add_(weight_decay, p.data)

修改梯度,添加p.data(权重)乘以weight_decay,全部就地完成(注意d_p.add_),这是您执行L2正则化所需要做的所有事情。

最后一行:

p.data.add_(-group['lr'], d_p)

使用标准 SGD 公式(再次就地尽可能快,至少在 Python 级别上)使用梯度更新权重(通过权重衰减修改)。

您自己的实现

如果你想让它更快,我建议你为自己的正则化遵循类似的逻辑。

您可以复制SGDPyTorch 实现,并且只更改这一相关行。如果您在实验中需要它,这也将为您提供 PyTorch 优化器的功能。

对于L1 正则化(|w| 而不是w**2),您必须计算它的导数(对于正数是1,对于负数是-1,对于0 是未定义的(我们不能有,所以它应该是零))。

考虑到这一点,我们可以这样写weight_decay

if weight_decay != 0:
    d_p.add_(weight_decay, torch.sign(p.data))

torch.sign 返回 1 为正值,-1 为负值,0 为...是的,0

希望这会有所帮助,具体实现留给您(如果您有任何问题或麻烦,请在 cmets 中联系我)。

【讨论】:

    猜你喜欢
    • 2017-07-30
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    相关资源
    最近更新 更多