发布时间:2022-08-19 12:38
基于上次玩了线性回归的批量梯度下降,我赶紧趁热打铁,写出了随机梯度下降、小批量梯度下降和牛顿法,发现它们真的很好玩。并且对比他们的迭代次数。
话不多说,上代码,如果不清楚我的实验数据以及背景,可查看我的上一篇博客。(96条消息) 线性回归之批量梯度下降代码实例_瞬生461的博客-CSDN博客
下面贴上我的几个下降的函数代码,仅供参考
def gradplus(alpha,nn):#为什么我取名叫做plus呢,因为矩阵运算实在是比普通标量运算快太多了
global theta
for k in range(nn):
theta=theta-alpha/m*np.dot(x.T,h(x)-y)
def grad(alpha,nn):#批量梯度下降
for k in range(nn):
for j in range(theta.shape[0]):
sum=0
for i in range(m):
sum+=(h(x[i,:])-y[i])*x[i][j]
theta[j]=theta[j]-alpha/m*sum
print(theta,k)
def sgd(alpha,nn):#随机梯度下降
for k in range(nn):
for j in range(theta.shape[0]):
for i in range(m):
theta[j]=theta[j]-alpha*(h(x[i,:])-y[i])*x[i][j]
print(theta[j])
def minigd(alpha,nn):#小批量梯度下降
for k in range(nn):
for j in range(theta.shape[0]):
for i in range(m-10):
sum=0
for ii in range(10):
sum+=(h(x[i+ii,:])-y[i+ii])*x[i+ii][j]
print(h(x[i,:]))
theta[j]=theta[j]-alpha/m*sum
牛顿法
def h(x): #函数
return np.dot(x,theta)
def f1():#一阶导数
return np.dot(2*x.T,h(x)-y)
def H():#海森矩阵,我推导过后,发现它是个单位阵
sum=np.eye(theta.shape[0])
sum=np.dot(2*sum,np.dot(x.T,x))
return sum
def newtonmethod():
global theta
k=np.ones((theta.shape[0],1))
while (k>es).all():#k>es为了使得变化量小于某个值
k=np.dot(np.linalg.inv(H()),f1())#inv()求逆矩阵
theta=theta-k
#print('theta',theta)
对比他们的特点:
批量梯度下降迭代次数为1000次左右,学习率0.07,结果稳定。
随机梯度下降迭代次数为10次,学习率为0.03,迭代次数过大时,越过极值。
小批量梯度下降迭代次数为100次,学习率为0.07,上面两种方法折衷。
牛顿法迭代次数大约10次,且不需设置学习率。
综上我们明显看出它们之间的性能差异。我比较喜欢牛顿法,快且稳定。
望批评指正。