李宏毅 机器学习(2017)学习笔记——1-梯度下降法实例

目录

1. 源代码

2. 代码函数解析

numpy.arange()

numpy.zeros(shape, dtype=float, order=‘C’)

numpy.meshgrid()

matplotlib.pyplot.contourf([X, Y,] Z,[levels], **kwargs)

matplotlib.pyplot.get_cmap()

matplotlib.pyplot.plot((x, y, format_string, **kwargs)

3. 实验结果及改进


    求回归中的参数有很多种方法,这里重点介绍梯度下降法

1. 源代码

import numpy as np
import matplotlib.pyplot as plt

x_data = [338.,333.,328.,207.,226.,25.,179.,60.,208.,606.]
y_data = [640.,633.,619.,393.,428.,27.,193.,66.,226.,1591.]
#ydata = b +w * xdata 使用梯度下降法找出b和w

x = np.arange(-200,-100,1)    #偏置,即b
y = np.arange(-5,5,0.1)    #权重,即w
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]为 b=x[i] 及 w=y[j] 时,对应的损失函数的大小
            Z[j][i] = Z[j][i] + (y_data[n] - b  - w*x_data[n])**2    #对应公式1(损失函数)
        Z[j][i] = Z[j][i]/len(x_data)    #求损失函数的均值

#ydata = b +w * xdata
b = -120    #初始化b的值
w = -4    #初始化w的值
lr = 0.0000001    #初始化学习率
iteration = 10000    #设置迭代次数

#存储绘图的初始值
b_history = [b]
w_history = [w]

#迭代
for i in range(iteration):    #进行10000次迭代并查看最后结果
    b_grad = 0.0    #对b_grad赋初值为0
    w_grad = 0.0    #对w_grad赋初值为0
    for n in range (len(x_data)):
        #分别对损失函数中的w和b求偏导,计算b和w对损失函数的偏微分,查看w、b在各自的轴上的移动 
        b_grad = b_grad - 2.0*(y_data[n] - b -w*x_data[n])*1.0    #对应公式3
        w_grad = w_grad - 2.0*(y_data[n] - b -w*x_data[n])*x_data[n]    #对应公式2
        
    #更新参数
    b = b - lr * b_grad
    w = w - lr * w_grad
    
    #存储用于画图的参数
    b_history.append(b)
    w_history.append(w)
    
#绘制图像
plt.contourf(x,y,Z,50,alpha = 0.5,cmap = plt.get_cmap('jet'))    #绘制等高线图
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()

李宏毅 机器学习(2017)学习笔记——1-梯度下降法实例

2. 代码函数解析

numpy.arange()

    返回一个有起点和终点的固定步长的排列。例如np.arange(0,3,1)的返回值为[0,1,2]。返回值是左闭右开的。

x = np.arange(-200,-100,1)
#函数返回起点是-200,终点是-100,步长为1的排列

    当只有一个参数时,默认起点为0,步长为1。

numpy.zeros(shape, dtype=float, order=‘C’)

    返回来一个给定形状和类型的用0填充的数组;

    参数解析:shape-数组形状     dtype-(可选)数据类型,默认为float64    order-(可选)C代表行优先,F代表列优先

Z = np.zeros((len(x),len(y)))
#返回一个len(x)*len(y)大小的零数组

numpy.meshgrid()

    生成网格点坐标矩阵。

matplotlib.pyplot.contourf([X, Y,] Z,[levels], **kwargs)

    绘制等高线。

    参数解析:levels-(可选)确定轮廓线的数量和位置    alpha-(可选)透明度    cmap-(可选)str或colormap,Colormap用于将数据值(浮点数)从间隔转换为相应Colormap表示的RGBA颜色。用于将数据缩放到间隔中看 

matplotlib.pyplot.get_cmap()

    绘图颜色渐变。

matplotlib.pyplot.plot((x, y, format_string, **kwargs)

    用于画图。

    参数解析:format_string-(可选)控制曲线的格式

    color颜色:'b' 蓝色    'm' 洋红色 magenta    'g' 绿色    'y' 黄色    'r' 红色    'k' 黑色    'w' 白色    'c' 青绿色 cyan    '#008000' RGB某颜色    '0.8' 灰度值字符串

    linestyle风格:'‐' 实线    '‐‐' 破折线    '‐.' 点划线    ':' 虚线    '' ' ' 无线条

    marker标记风格:'.' 点标记    ',' 像素标记(极小点)    'o' 实心圈标记    'v' 倒三角标记    '^' 上三角标记    '>' 右三角标记    '<' 左三角标记

3. 实验结果及改进

    最终代码运行结果如下:

    李宏毅 机器学习(2017)学习笔记——1-梯度下降法实例

    图上的颜色代表不同参数下的损失值,纵轴是w的变化,横轴是b的变化。“×”处是损失值最低的点。

    从b = -120,w = -4处开始更新参数,但是经过十万次迭代后,参数更新值仍距离“×”处很远,所以考虑增大学习率。

    当学习率=0.000001时,结果如下图,此时离最佳点近了一些。但是发生了剧烈的震荡现象。

    李宏毅 机器学习(2017)学习笔记——1-梯度下降法实例

    当学习率=0.00001时,结果如下图,效果并不如之前。

    李宏毅 机器学习(2017)学习笔记——1-梯度下降法实例

    为解决这一问题,需要给b和w设置不同的学习率。

#ydata = b +w * xdata
b = -120    #初始化b的值
w = -4    #初始化w的值
lr = 1    #初始化学习率
iteration = 10000    #设置迭代次数

#存储绘图的初始值
b_history = [b]
w_history = [w]

#分别给b和w设定学习率
lr_b = 0
lr_w = 0

#迭代
for i in range(iteration):    #进行10000次迭代并查看最后结果
    b_grad = 0.0    #对b_grad赋初值为0
    w_grad = 0.0    #对w_grad赋初值为0
    for n in range (len(x_data)):
        #分别对损失函数中的w和b求导,查看w、b在各自的轴上的移动 
        b_grad = b_grad - 2.0*(y_data[n] - b -w*x_data[n])*1.0    #对应公式3
        w_grad = w_grad - 2.0*(y_data[n] - b -w*x_data[n])*x_data[n]    #对应公式2
        
    lr_b = lr_b + b_grad ** 2
    lr_w = lr_w + w_grad **2
    
    #更新参数
    b = b - lr/np.sqrt(lr_b) * b_grad
    w = w - lr/np.sqrt(lr_w) * w_grad
    
    #存储用于画图的参数
    b_history.append(b)
    w_history.append(w)
    
#绘制图像
plt.contourf(x,y,Z,50,alpha = 0.5,cmap = plt.get_cmap('jet'))    #绘制等高线图
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()

    最终的得到的结果如下图所示。此时效果已经远远优于之前的效果。

    李宏毅 机器学习(2017)学习笔记——1-梯度下降法实例

上一篇:五个有趣的Python练手小项目,附代码


下一篇:pyTorch节省显存