梯度以及梯度下降法
梯度这一词可能对于一部分人来说比较陌生,因为这里涉及到许多相关的数学知识,所以接下来我就说一下
梯度
梯度是什么
我们还是一如既往的看我们的百度百科给的定义:
一如既往的抽象,我们来看看下面它的定义:
梯度是数学的一个概念,也常用于我们的深度学习,百科给的定义看起来可能有些晦涩难懂,下面是我的一些理解。
我的理解
首先:在单变量的实值函数的情况,梯度只是导数,或者,对于一个线性函数,也就是线的斜率
这个相比很好理解,那对于多元函数呢,假设是一个二元函数,对于其中的一个点,这个点此时的梯度就是一个由该函数对各个变量的偏导数组成的的一个向量,它是有方向的,也就是
梯度的符号通常是一个倒三角,也就是这样:
看到这里有的人或许还是不明白,可能会问:我们在实际使用时应当怎么做?
答案就是,我们只需要计算函数对每个变量的偏导数就好。
也就是我常说的;在深度学习中,我们可以连结一个多元函数对其所有变量的偏导数,以得到该函数的梯度(gradient)向量。
当然有些时候我们也会求梯度的平均值,当然这个视情况而定。
梯度下降法
什么是梯度下降法
我们看百科给的解释:
很抽象,这也是数学的东西。
百科这里,如果你对梯度理解了的话,这里就不抽象了。
梯度下降法计算过程就是:沿着梯度下降的方向求解极小值,我们知道梯度是有方向的(对于多元函数来说),它是一个由偏导数组成的向量,这就相当于我们沿着该方向的逆方向移动。(常用于损失函数上)
举个例子,倘若一个多元函数,有个参数x,其在该位置的梯度也就是偏导数为grad_X,我们设置的步长为Ir=0.01,那么这个过程就是x=x-Ir*grad_x
(步长可以理解为,在该方向上走多少距离,步长一般设一个较小的值,防止错过极小值得到的只是一个局部最小值。)
可能有人疑惑了,真的就是你说的那样么,这样写真的是沿梯度下降的方向么?
我们可以用一个一元函数y=kx试一试,画一下图,这里就不尝试了
为什么我们要沿梯度下降的方向移动?
原因在梯度的定义,梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。
也就是说,咱这么做 快!!
代码示例
利用梯度下降法实现线性回归(y=wx)
首先导入库:
import torch
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import font_manager
然后我们建立数据集(这里建立一个简单的):
x=np.array([0.18,0.1,0.16,0.08,0.09,0.11,0.12,0.17,0.15,0.14,0.13])
y=np.array([0.18,0.1,0.16,0.08,0.09,0.11,0.12,0.17,0.15,0.14,0.13])
接着我们定义梯度计算函数,还有损失函数:
def loss_(w,x,y):#损失函数
return 0.5*np.sum((w*x-y)**2)
def grad_w(w,x,y):
return np.mean((w*x-y)*w)
最后我们训练,并且画图:
for i1 in range(1,bath):
for i2 in range(1,epoches):
a=a+1
grad=grad_w(w,x,y)
w=w-Ir*grad
l=loss_(w,x,y)
print('第{0}次循环: 梯度:{1},权值:{2},损失值:{3}'.format(a,grad,w,l))
lista.append(a)
listw.append(w)
listl.append(l)
listg.append(grad)
font=font_manager.FontProperties(fname="C:\\Users\\ASUS\\Desktop\\Fonts\\STZHONGS.TTF")
plt.plot(listw,listl)
plt.title('参数和损失值的对应关系',fontproperties = font,fontsize = 18)
plt.show()
b2=plt.plot(lista,listg)
plt.title('循环次数和梯度的对应关系',fontproperties = font,fontsize = 18)
plt.show()
完整代码
import torch
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import font_manager
print('利用梯度下降法实现线性回归')
x=np.array([0.18,0.1,0.16,0.08,0.09,0.11,0.12,0.17,0.15,0.14,0.13])
y=np.array([0.18,0.1,0.16,0.08,0.09,0.11,0.12,0.17,0.15,0.14,0.13])
w=10
Ir=0.01
bath=31
epoches=1001
listw=[]
listl=[]
listg=[]
lista=[]
l=0
grad=0
a=0
def loss_(w,x,y):#损失函数
return 0.5*np.sum((w*x-y)**2)
def grad_w(w,x,y):
return np.mean((w*x-y)*w)
for i1 in range(1,bath):
for i2 in range(1,epoches):
a=a+1
grad=grad_w(w,x,y)
w=w-Ir*grad
l=loss_(w,x,y)
print('第{0}次循环: 梯度:{1},权值:{2},损失值:{3}'.format(a,grad,w,l))
lista.append(a)
listw.append(w)
listl.append(l)
listg.append(grad)
font=font_manager.FontProperties(fname="C:\\Users\\ASUS\\Desktop\\Fonts\\STZHONGS.TTF")
plt.plot(listw,listl)
plt.title('参数和损失值的对应关系',fontproperties = font,fontsize = 18)
plt.show()
b2=plt.plot(lista,listg)
plt.title('循环次数和梯度的对应关系',fontproperties = font,fontsize = 18)
plt.show()
运行结果
D:\Anaconda3\envs\pytorch\python.exe D:\learn_pytorch\学习过程\第一周的代码\代码10.py
利用梯度下降法实现线性回归
第1000次循环: 梯度:0.05577848464389928,权值:1.3234963799337245,损失值:0.010302783425885614
第2000次循环: 梯度:0.00994199908135567,权值:1.071282165300862,损失值:0.0005002389310084732
第3000次循环: 梯度:0.002446292789153066,权值:1.0184518015622381,损失值:3.351917116883841e-05
第4000次循环: 梯度:0.0006485600410191944,权值:1.0049577937228458,损失值:2.4198732960015992e-06
第5000次循环: 梯度:0.0001753339015633546,权值:1.0013451548191161,损失值:1.7813951443367964e-07
第6000次循环: 梯度:4.765015244748137e-05,权值:1.0003659288797835,损失值:1.3182843391113165e-08
第7000次循环: 梯度:1.2968282323801346e-05,权值:1.000099616385774,损失值:9.76961123780877e-10
第8000次循环: 梯度:3.530768535048637e-06,权值:1.0000271237126641,损失值:7.242925039610776e-11
第9000次循环: 梯度:9.613951936600926e-07,权值:1.0000073856790013,损失值:5.370275636783282e-12
第10000次循环: 梯度:2.617864389244471e-07,权值:1.0000020111199184,损失值:3.9819119745672656e-13
第11000次循环: 梯度:7.12846052297103e-08,权值:1.0000005476299705,损失值:2.952501565350202e-14
第12000次循环: 梯度:1.941088236775404e-08,权值:1.0000001491203487,损失值:2.1892206793877106e-15
第13000次循环: 梯度:5.285609588069504e-09,权值:1.0000000406056775,损失值:1.6232643192654885e-16
第14000次循环: 梯度:1.4392787853333183e-09,权值:1.0000000110569824,损失值:1.2036187950954985e-17
第15000次循环: 梯度:3.919175576704938e-10,权值:1.0000000030108314,损失值:8.924596266915436e-19
第16000次循环: 梯度:1.0671983003045295e-10,权值:1.0000000008198546,损失值:6.617431186144233e-20
第17000次循环: 梯度:2.905994637494725e-11,权值:1.0000000002232474,损失值:4.906689443748435e-21
第18000次循环: 梯度:7.913219322714584e-12,权值:1.0000000000607918,损失值:3.638361448163776e-22
第19000次循环: 梯度:2.1547725725282304e-12,权值:1.0000000000165536,损失值:2.697748224251698e-23
第20000次循环: 梯度:5.867566533682639e-13,权值:1.0000000000045077,损失值:2.000436550912265e-24
第21000次循环: 梯度:1.599452893364787e-13,权值:1.0000000000012288,损失值:1.4865355468481497e-25
第22000次循环: 梯度:4.4359717919157326e-14,权值:1.0000000000003408,损失值:1.1436529654962079e-26
第23000次循环: 梯度:1.1084567607224383e-14,权值:1.0000000000000853,损失值:7.1576512307671085e-28
第24000次循环: 梯度:1.1084567607224383e-14,权值:1.0000000000000853,损失值:7.1576512307671085e-28
第25000次循环: 梯度:1.1084567607224383e-14,权值:1.0000000000000853,损失值:7.1576512307671085e-28
第26000次循环: 梯度:1.1084567607224383e-14,权值:1.0000000000000853,损失值:7.1576512307671085e-28
第27000次循环: 梯度:1.1084567607224383e-14,权值:1.0000000000000853,损失值:7.1576512307671085e-28
第28000次循环: 梯度:1.1084567607224383e-14,权值:1.0000000000000853,损失值:7.1576512307671085e-28
第29000次循环: 梯度:1.1084567607224383e-14,权值:1.0000000000000853,损失值:7.1576512307671085e-28
第30000次循环: 梯度:1.1084567607224383e-14,权值:1.0000000000000853,损失值:7.1576512307671085e-28
进程已结束,退出代码0