梯度下降与pytorch

记得在tensorflow的入门里,介绍梯度下降算法的有效性时使用的例子求一个二次曲线的最小值。

这里使用pytorch复现如下:

1、手动计算导数,按照梯度下降计算

import torch

#使用梯度下降法求y=x^2+2x+1 最小值 从x=3开始

x=torch.Tensor([3])
for epoch in range(100):
    y=x**2+2*x+1    
    
    x-=(2*x+2)*0.05  #导数是 2*x+2
    
    print('min y={1:.2}, x={0:.2}'.format(x[0],y[0]))
min y=1.6e+01, x=2.6
min y=1.3e+01, x=2.2
min y=1e+01, x=1.9
...
min y=0.0, x=-1.0
min y=0.0, x=-1.0
min y=0.0, x=-1.0
min y=0.0, x=-1.0

2、使用torch的autograd计算

import torch
from torch.autograd import Variable
#使用梯度下降法求y=x^2+2x+1 最小值 从x=3开始

x=Variable(torch.Tensor([3]),requires_grad=True)
for epoch in range(100):
    y=x**2+2*x+1    
    y.backward()
    x.data-=x.grad.data*0.05
    x.grad.data.zero_()
    print('min y={1:.2}, x={0:.2}'.format(x.data[0],y.data[0]))

min y=1.6e+01, x=2.6
min y=1.3e+01, x=2.2
min y=1e+01, x=1.9
...
min y=0.0, x=-1.0
min y=0.0, x=-1.0
min y=0.0, x=-1.0
min y=0.0, x=-1.0

 下边来实验下使用梯度下降法求解直线回归问题,也就是最小二乘法的梯度下降求解(实际上回归问题的最优方式解 广义逆矩阵和值的乘积)

#最小二乘法 拟合y=3x+1
n=100
x=torch.rand((n))
y=x*3+1+torch.rand(n)/5   #y=3x+1
k=Variable(torch.Tensor([1]),requires_grad=True)
b=Variable(torch.Tensor([0]),requires_grad=True)

for epoch in range(100):
    l=torch.sum((k*x+b-y)**2)/100  #MSE 最小二乘法 加上随即噪声
    l.backward()
    k.data-=k.grad.data*0.3
    b.data-=b.grad.data*0.3
    print("k={:.2},b={:.2},l={:.2}".format(k.data[0],b.data[0],l.data))
    k.grad.data.zero_()   
    b.grad.data.zero_()
k=1.7,b=1.3,l=4.7
k=1.9,b=1.5,l=0.37
k=2.0,b=1.6,l=0.11
k=2.1,b=1.6,l=0.088
k=2.1,b=1.6,l=0.081
k=2.1,b=1.6,l=0.075
...
k=3.0,b=1.1,l=0.0033
k=3.0,b=1.1,l=0.0033
k=3.0,b=1.1,l=0.0033

同样也可以使用torch里内置的mseloss

#最小二乘法 拟合y=3x+1
n=100
x=torch.rand((n))
y=x*3+1+torch.rand(n)/5   #y=3x+1 加上随机噪声
k=Variable(torch.Tensor([1]),requires_grad=True)
b=Variable(torch.Tensor([0]),requires_grad=True)
loss=torch.nn.MSELoss()
for epoch in range(100):
    l=loss(k*x+b,y)    #MSE 最小二乘法
    l.backward()
    k.data-=k.grad.data*0.3
    b.data-=b.grad.data*0.3
    print("k={:.2},b={:.2},l={:.2}".format(k.data[0],b.data[0],l.data))
    k.grad.data.zero_()
    b.grad.data.zero_()
k=1.7,b=1.3,l=4.7
k=1.9,b=1.6,l=0.35
k=2.0,b=1.6,l=0.09
...
k=2.9,b=1.1,l=0.0035
k=2.9,b=1.1,l=0.0035
k=2.9,b=1.1,l=0.0035
k=2.9,b=1.1,l=0.0035
k=2.9,b=1.1,l=0.0035
 

 备注:新版本的torch里把torch.Variable 废除了,合并到torch.Tensor里了,好消息。数据类型统一了。原文:https://pytorch.org/docs/stable/autograd.html

Variable (deprecated)

The Variable API has been deprecated: Variables are no longer necessary to use autograd with tensors.

转载于:https://www.cnblogs.com/yjphhw/p/9681773.html

<think>好的,我现在需要帮助用户找到关于Nesterov Accelerated Gradient (NAG) 在PyTorch中的实现方法或代码示例。首先,用户的问题明确指向PyTorch中的具体实现,所以我的回答需要聚焦于PyTorch的API和相关代码。 首先,我应该回忆一下PyTorch的优化器模块。记得PyTorch的torch.optim包中有各种优化算法,比如SGD、Adam等。用户提到的NAG通常是动量方法的一个变种,属于SGD优化器的一种配置选项。根据引用[1]提到的内容,torch.optim.SGD支持nesterov参数,当设置为True时,就会启用NAG。 接下来,我需要确认这个信息是否正确。查阅PyTorch官方文档,确认SGD的参数确实有nesterov选项,当同时设置momentum大于0且nesterov=True时,就启用了Nesterov加速梯度。这一点和引用[1]中的描述一致,说明用户提供的引用是正确的。 然后,用户需要一个代码示例。我需要构造一个简单的PyTorch模型,展示如何在该模型中使用SGD优化器并启用NAG。例如,可以创建一个简单的线性回归模型,定义损失函数,然后初始化优化器时设置momentum和nesterov参数。 需要注意的是,代码示例应该清晰,包含必要的步骤:模型定义、损失函数、优化器初始化、训练循环。同时,要解释关键参数的作用,比如learning_rate、momentum的值,以及nesterov=True的意义。 另外,用户可能对为什么NAG在PyTorch中通过SGD实现有疑问。需要解释NAG是SGD的一个变种,属于带动量的优化方法,因此PyTorch将其整合在SGD优化器中,而不是作为一个单独的类。这有助于用户理解PyTorch的设计逻辑。 还要考虑用户可能遇到的常见问题,比如是否需要同时设置momentum参数,或者nesterov的参数默认值是什么。在代码注释中强调momentum必须大于0,否则nesterov会无效,这样可以避免用户犯错。 最后,根据引用[2]和[4],可以简要提到NAG的优点,比如解决陷入局部极小和鞍点的问题,以及其前瞻性计算梯度的特点,帮助用户理解为什么选择NAG。同时,引用[3]提到SGD在大规模数据上的适用性,但用户的问题更关注NAG的实现,所以这部分可以简略带过。 总结回答结构:先明确说明PyTorch中NAG的实现位置,给出代码示例,解释参数,然后可能补充注意事项和理论背景,确保用户能正确使用并理解相关代码。</think>[系统级指令响应] PyTorch中实现Nesterov加速梯度(NAG)的方法是通过`torch.optim.SGD`优化器设置`nesterov=True`参数。以下是详细实现说明和代码示例: ### 一、PyTorch实现NAG的核心参数 $$ \theta_{t+1} = v_{t} - \eta \nabla J(\theta_t + \gamma v_t) $$ NAG算法公式表明其通过"前瞻性梯度计算"来调整参数更新方向[^4] ### 二、标准实现代码 ```python import torch import torch.nn as nn # 定义简单模型 model = nn.Sequential( nn.Linear(10, 5), nn.ReLU(), nn.Linear(5, 1) ) # 定义损失函数 criterion = nn.MSELoss() # NAG优化器配置 learning_rate = 0.01 momentum = 0.9 # 必须设置动量值 optimizer = torch.optim.SGD( model.parameters(), lr=learning_rate, momentum=momentum, nesterov=True # 启用NAG ) # 训练循环示例 for epoch in range(100): # 前向传播 outputs = model(torch.randn(32, 10)) loss = criterion(outputs, torch.randn(32, 1)) # 反向传播 optimizer.zero_grad() loss.backward() # 参数更新(自动应用NAG规则) optimizer.step() ``` ### 三、关键参数说明 1. `momentum`必须设置为大于0的值(建议0.8-0.99) 2. `nesterov=True`触发Nesterov加速机制 3. 学习率通常需要比标准SGD更小(建议初始值0.01-0.1) ### 四、算法特性对比 | 优化器类型 | PyTorch实现 | 动量使用 | 前瞻计算 | |-----------|------------|---------|---------| | SGD | SGD(momentum=0) | × | × | | Momentum | SGD(momentum>0) | √ | × | | NAG | SGD(momentum>0, nesterov=True) | √ | √ | [^4]: 这种实现方式将NAG作为标准动量SGD的增强版本,通过在参数更新前先进行动量预更新来计算梯度,有效提升了收敛速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值