loss乘以100等价于learning rate乘以100?

Posted 修炼之路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了loss乘以100等价于learning rate乘以100?相关的知识,希望对你有一定的参考价值。

导读

看到这个问题的时候,可能你会很直观的认为是等价的,其实等不等价这个应该取决于在更新参数时所选择的优化算法

因为无论是缩放loss还是learning rate最终的影响都是对更新参数时偏移量( Δ \\Delta Δ)的影响,而不同的优化算法会导致这个偏移量存在差别,下面我们来讨论一下不同优化算法之间的差别。

SGD

梯度下降优化算法,也是最常见的一种优化算法,公式如下:
θ = θ − η ∗ Δ θ J ( θ ) \\theta = \\theta - \\eta * \\Delta_\\thetaJ(\\theta) θ=θηΔθJ(θ)

  • η \\eta η:学习率
  • Δ θ J ( θ ) \\Delta_\\thetaJ(\\theta) ΔθJ(θ):loss对参数的一阶偏导,所以当我们对loss的尺度进行缩放的时候实际最终都会反应到梯度上面

结论:通过上面的公式不难看出,当loss乘以s时其实就等价于偏导 Δ θ J ( θ ) \\Delta_\\thetaJ(\\theta) ΔθJ(θ)数乘以s,也就等价与学习率 η \\eta η乘以s。所以对于SGD而言,loss乘以s等价于learning rate乘以s。下面我们可以用代码来证明一下

import torch
from torch import nn

#保证每次产生的随机数(输入和输出都相同)
torch.manual_seed(28)

class ExampleModel(nn.Module):
    """定义一个简单的神经网络
    """
    def __init__(self):
        super(ExampleModel, self).__init__()
        self.linear_model = nn.Sequential(
            nn.Linear(10,10),
            nn.ReLU(),
            nn.Linear(10,1),
            nn.Sigmoid()
        )
    def forward(self,x):
        return self.linear_model(x**3+x**2+x)


def print_weight_info(input,label,model,opt,loss_scale):
    """输出网络的参数信息
    :param input: 输入
    :param label: 输出
    :param model: 模型
    :param opt: 优化器
    :param loss_scale: loss变化的尺度
    :return:
    """
    output = model(input)
    loss = (label - output) * loss_scale
    opt.zero_grad()
    loss.backward()
    opt.step()
    print(model.linear_model[0].weight)

model = ExampleModel()


input1 = torch.rand(1,10)
label1 = torch.rand(1,)
lr = 0.01

lr_sgd_opt = torch.optim.SGD(model.parameters(),lr=lr)
#lr设置为0.01,loss的尺度扩大10倍
print_weight_info(input1,label1,model,lr_sgd_opt,10)
#lr设置为0.01*10扩大10倍,loss的尺度不做处理
#lr_scale_sgd_opt = torch.optim.SGD(model.parameters(),lr=lr*10)
#print_weight_info(input1,label1,model,lr_scale_sgd_opt,1)

Momentum SGD

Momentum SGD是基于SGD的基础上做了修改,为了解决海森矩阵的不良条件数随机梯度的方差问题导致训练模型时进入到局部极小值问题而改进的。Momentum SGD梯度的更新过程如下所示:
θ = θ − v t v t = γ ∗ v t − 1 + η ∗ Δ θ J ( θ ) \\beginaligned \\theta &= \\theta - v_t \\\\ v_t &= \\gamma * v_t-1 + \\eta * \\Delta_\\thetaJ(\\theta) \\endaligned θvt=θvt=γvt1+ηΔθJ(θ)

  • γ \\gamma γ:动量参数,一般取0.5、0.9和0.99
  • v t v_t vt :t时刻的梯度

结论:通过上面的公式不难看出,对于Momentum SGD来说和SGD一样,loss乘以s等价于learning rate乘以s。证明代码如下:

import torch
from torch import nn

#保证每次产生的随机数(输入和输出都相同)
torch.manual_seed(28)

class ExampleModel(nn.Module):
    """定义一个简单的神经网络
    """
    def __init__(self):
        super(ExampleModel, self).__init__()
        self.linear_model = nn.Sequential(
            nn.Linear(10,10),
            nn.ReLU(),
            nn.Linear(10,1),
            nn.Sigmoid()
        )
    def forward(self,x):
        return self.linear_model(x**3+x**2+x)


def print_weight_info(input,label,model,opt,loss_scale):
    """输出网络的参数信息
    :param input: 输入
    :param label: 输出
    :param model: 模型
    :param opt: 优化器
    :param loss_scale: loss变化的尺度
    :return:
    """
    output = model(input)
    loss = (label - output) * loss_scale
    opt.zero_grad()
    loss.backward()
    opt.step()
    print(model.linear_model[0].weight)

model = ExampleModel()


input1 = torch.rand(1,10)
label1 = torch.rand(1,)
lr = 0.01
#设置momentum SGD的动量为0.9
momentum = 0.9

lr_mom_sgd_opt = torch.optim.SGD(model.parameters(),lr=lr,momentum=momentum)
#lr设置为0.01,loss的尺度扩大10倍
print_weight_info(input1,label1,model,lr_mom_sgd_opt,10)
#lr设置为0.01*10扩大10倍,loss的尺度不做处理
# lr_mom_sgd_opt = torch.optim.SGD(model.parameters(),lr=lr*10,momentum=momentum)
# print_weight_info(input1,label1,model,lr_mom_sgd_opt,1)

Adagrad

Adagrad能够自适应的调整不同参数的学习率,根据参数的历史所有梯度平方值总和的平方根来调整学习率的缩放比例,使得稀疏的特征得到大的学习率更新,对于非稀疏的特征得到较小的学习更新,所以该算法适合处理稀疏特征的数据。参数的更新公式如下:
g t , i = Δ θ J ( θ i ) θ t + 1 , i = θ t , i − η G t , i i + ϵ ∗ g t , i \\beginaligned g_t,i &= \\Delta_\\thetaJ(\\theta_i) \\\\ \\theta_t+1,i &= \\theta_t,i - \\frac\\eta\\sqrtG_t,ii + \\epsilon * g_t,i \\endaligned gt,iθt+1,i=ΔθJ(θi)=θt,iGt,ii+ϵ ηgt,i

  • g t , i g_t,i gt,i t t t时刻参数 θ i \\theta_i θi的梯度
  • θ t \\theta_t θt t t t时刻参数 θ \\theta θ的值
  • G t , i i G_t,ii Gt,ii G t G_t Gt是一个对角矩阵,第 i i i行元素 e i i e_ii eii表示的是过去到现在第 i i i个参数 θ i \\theta_i θi的梯度的平方和
  • ϵ \\epsilon ϵ:通常取 e − 8 e^-8 e8,用来避免分母为零的情况

接下来我们来讨论,对loss和learning rate乘以s对参数 θ \\theta θ的更新会有什么影响,先讨论对loss乘以s
θ t + 1 , i = θ t , i − η G t , i i ∗ s 2 + ϵ ∗ g t , i ∗ s = θ t , i − η G t , i i + ϵ / s ∗ g t , i \\theta_t+1,i = \\theta_t,i - \\frac\\eta\\sqrtG_t,ii * s^2 + \\epsilon * g_t,i * s = \\theta_t,i - \\frac\\eta\\sqrtG_t,ii + \\epsilon / s * g_t,i θt+1,i=θt,iGt,iis2 +ϵηgt,i以上是关于loss乘以100等价于learning rate乘以100?的主要内容,如果未能解决你的问题,请参考以下文章

tensorflow:神经网络优化(loss,learning_rate)

降低损失 :学习速率

Tensorflow学习之(学习率)

tensorflow之神经网络实现流程总结

指数衰减学习率

随机梯度下降法实例