梯度下降算法-学习李宏毅老师课程demo

2 梯度下降算法-demo

​ 学习了李宏毅讲授的机器学习算法的第一课——梯度下降算法,以下是梯度下降算法的一个练习demo,由于我自己是python小白,这里有部分我不太明白的python语句我都做了笔记,显得内容比较冗余。

import numpy as np
import matplotlib.pyplot as plt
#matplotlib是基于Python语言的开源项目,旨在为Python提供一个数据绘图包。


# traning data
x_data = [338.,333.,328.,207.,226.,25.,179.,60.,208.,606.] 
y_data = [640.,633.,619.,393.,428.,27.,193.,66.,226.,1591]
#y_data = b + w * x_data

'''
#### 数组的创建与使用
arange(a,b,c) 参数分别表示开始值,结束值,步长
#### 特殊数组
zeros数组:全零数组,元素全为零。
ones数组:全1数组,元素全为1。
empty数组:空数组,元素全近似为0。
#### X, Y = np.meshgrid(x,y)
a = np.array([1,2,3])
b = np.array([7,8])
res = np.meshgrid(a,b)
返回list,有两个元素,第一个元素是X轴的取值,向量a两行,第二个元素是Y轴的取值,向量b三列
返回结果: X=array([ [1,2,3],[1,2,3] ]), Y=array([ [7,7,7],[8,8,8] ])
(1,7)(2,7)(3,7)
(1,8)(2,8)(3,8)
'''

x = np.arange(-200,-100,1)#bias
y = np.arange(-5,5,0.1)#weight
Z = np.zeros((len(x), len(y)))
X, Y = np.meshgrid(x,y)
for i in range(len(x)):
    for j in range(len(y)):
        b = x[i]
        w = y[j]
        Z[j][i] = 0
        for n in range(len(x_data)):
            Z[j][i] = Z[j][i] + (y_data[n] - b - w*x_data[n])**2
        Z[j][i] = Z[j][i]/len(x_data)

b = -120#initial b
w = -4#initial w
lr = 0.00000001 #learning rate
iteration = 100000

#store initial values for plotting.
b_history = [b]
w_history = [w]

#iterations
for i in range(iteration):
    b_grad = 0.0#偏微分
    w_grad = 0.0
    for n in range(len(x_data)):
        b_grad = b_grad - 2.0*(y_data[n] - b - w*x_data[n])*1.0
        w_grad = w_grad - 2.0*(y_data[n] - b - w*x_data[n])*x_data[n]
        
    # update parameters
    b = b - lr * b_grad
    w = w - lr * w_grad
    
    #store parameters for plotting
    b_history.append(b)
    w_history.append(w)
    
'''
#### 隐式创建figure对象
当第一次执行plt.xxx()画图代码时,系统会去判断是否已经有了figure对象,如果没有,系统会自动创建一个figure对象,并且在这个figure之上,自动创建一个axes坐标系(注意:默认创建一个figure对象,一个axes坐标系)。
也就是说,如果我们不设置figure对象,那么一个figure对象上,只能有一个axes坐标系,即我们只能绘制一个图形。
#### matplotlib.pyplot contourf 
函数原型:
​```coutour([X, Y,] Z,[levels], **kwargs)```
是来绘制等高线的,contour和contourf都是画三维等高线图的,不同点在于contour() 是绘制轮廓线,contourf()会填充轮廓。除非另有说明,否则两个版本的函数是相同的。
#### plt.plot
plt.plot()函数的本质就是根据点连接线。根据x(数组或者列表) 和 y(数组或者列表)组成点,然后连接成线。
#### plt.xlim
函数功能:设置x轴的数值显示范围。
调用签名:plt.xlim(xmin, xmax)
xmin:x轴上的最小值
xmax:x轴上的最大值
#### 显示图形
plt.show()或figure.show()如果在pycharm中绘图的话,必须要加这句代码,才能显示。如果在notebook中进行绘图,可以不用加这句代码,而是自动显示。
'''

#plot the figure
plt.contourf(x,y,Z,50,alpha=0.5, cmap=plt.get_cmap('jet'))
#坐标:[-188.4],[2.67],color:线条颜色
plt.plot([-188.4],[2.67],'x', ms=12, markeredgewidth=3, color='orange')
plt.plot(b_history,w_history,'o-', ms=3, lw=1.5, color='black')
plt.xlim(-200,-100)
plt.ylim(-5,5)
#设置横纵坐标的名称以及对应字体格式
plt.xlabel(r'$b$', fontsize =16)
plt.ylabel(r'$w$', fontsize =16)
plt.show()

运行结果:

经过100000次update之后,现在得到的参数离最佳点依旧有很大距离,learning rate太小。

放大learning rate = 0.000001

放大learning rate = 0.00001

learning过大,导致数据超出图

解决办法:

给b,w设置客制化的learning rate,给他们不一样的learning rate.

b = -120#initial b
w = -4#initial w
lr = 1 #learning rate
iteration = 100000

#store initial values for plotting.
b_history = [b]
w_history = [w]

lr_b = 0
lr_w = 0

#iterations
for i in range(iteration):
    b_grad = 0.0#偏微分
    w_grad = 0.0
    for n in range(len(x_data)):
        b_grad = b_grad - 2.0*(y_data[n] - b - w*x_data[n])*1.0
        w_grad = w_grad - 2.0*(y_data[n] - b - w*x_data[n])*x_data[n]
lr_b = lr_b + b_grad ** 2
lr_w = lr_w + w_grad ** 2
    
# update parameters
b = b - lr/np.sqrt(lr_b) * b_grad
w = w - lr/np.sqrt(lr_w) * w_grad

#store parameters for plotting
b_history.append(b)
w_history.append(w)

修改后最终运行结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值