梯度下降與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.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM