前言
本文记录在学习pytorch的一些心得
手写线性回归之前我们需要了解一下pytorch的tensor中的requires_grad属性,当requires_grad=True时,它会追踪该张量的全部操作,也就为我们的梯度更新做出了前提
首先我们要知道什么是梯度:梯度也就是一个向量,导数+变化最快的方向(学习的前进方向)
而梯度一般也是和loss相结合使用的
判断模型的好坏就是看loss的大小,越小越好
lossloss=(Ypredict−Ytrue)2=Ytrue⋅log(Ypredict)(回归损失)(分类损失)
而当我们取得第一个loss的使用就要开始想怎么去减小loss的大小
大概可以看这个图
随机选择一个起始点w0,通过调整w0,让loss函数取到最小值
w的更新方法:
- 计算w的梯度(导数)
∇w=2∗0.000001f(w+0.000001)−f(w−0.000001)
- 更新w
w=w−α∇w
其中:
∇w<0,意味着W将增大∇w>0,意味着W将减小
总结:梯度就是多元函数参数的变化趋势(参数学习的方向),只有一个自变量时称为导数
而在神经网络中我们求梯度的方式就是反向传播,具体原理(能力有限解释不清),但是用处就是通过反向传播推导,求得梯度值
下面我们准备写一下一个简单线性回归方程
我们假设定义一个y=3x+0.8的线性函数
import torch import numpy as np import matplotlib.pyplot as plt
rate=0.01
x=torch.rand([500,1])
y_true=3*x+0.8
w=torch.rand([1,1],requires_grad=True)
b=torch.tensor(0,requires_grad=True,dtype=torch.float32)
for i in range(3000): y_predict=torch.matmul(x,w)+b loss=(y_true-y_predict).pow(2).mean() if w.grad is not None: w.grad.data.zero_() if b.grad is not None: b.grad.data.zero_() loss.backward() w.data=w.data-rate*w.grad b.data=b.data-rate*b.grad if i%50==0: print("w={},b={},loss={}".format(w.item(),b.item(),loss))
|
这样迭代3000次后,我们最后得到的w,b就已经十分接近3和0,8了
w=2.9634265899658203,b=0.8195856213569641,loss=0.00010962356464006007
|
这个时候我们进行简单的画图
plt.figure(figsize=(20,8)) plt.scatter(x.numpy().reshape(-1),y_true.numpy().reshape(-1)) y_predict=torch.matmul(x,w)+b plt.plot(x.numpy().reshape(-1),y_predict.detach().numpy().reshape(-1)) plt.show()
|
如图所示:
从图上看出预测的函数基本上和原函数拟合,这就是线性回归的意义,通过梯度下降法,找到梯度下降的方向,然后通过参数的迭代去找到w和b的参数形成预测函数,进行模型验证.
(注:x.backward()
,此时便能够求出导数dxdout后调用x.gard
能够获取导数值也就是梯度值)
api介绍
-
tensor.data
:
-
tensor.numpy()
:
- 当
require_grad=True
不能够直接转换,需要使用tensor.detach().numpy()
,先抽取数据值在进行转换