梯度下降与pytorch

时间:2023-03-10 05:57:35
梯度下降与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.