记得在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.