李宏毅-人工智能2017笔记4. Regression Demo

4. Regression Demo

image-20220119181326784

  • NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库

    一般在python中我们会对Numpy进行缩写,import numpy as np,因此后续中的np均指numpy

  • Matplotlib 是 Python 中最受欢迎的数据可视化软件包之一,支持跨平台运行,它是 Python 常用的 2D 绘图库,同时它也提供了一部分 3D 绘图接口。Matplotlib 通常与 NumPy、Pandas 一起使用,是数据分析中不可或缺的重要工具之一。

    Matplotlib 是 Python 中类似 MATLAB 的绘图工具,如果您熟悉 MATLAB,那么可以很快的熟悉它。Matplotlib 提供了一套面向对象绘图的 API,它可以轻松地配合 Python GUI 工具包(比如 PyQt,WxPython、Tkinter)在应用程序中嵌入图形。与此同时,它也支持以脚本的形式在 Python、IPython Shell、Jupyter Notebook 以及 Web 应用的服务器中使用。

  • matplotlib.pyplot是一个有命令风格的函数集合,它看起来和MATLAB很相似。每一个pyplot函数都使一副图像做出些许改变,例如创建一幅图,在图中创建一个绘图区域,在绘图区域中添加一条线等等。在matplotlib.pyplot中,各种状态通过函数调用保存起来,以便于可以随时跟踪像当前图像和绘图区域这样的东西。

    image-20220119191639481

  • x_data为训练数据中宝可梦进化前的cp属性值,y_data为训练数据中宝可梦进化后的战斗力。,二者是y_data=b+wx_data的关系。

    image-20220119195153082

  • np.arange()
    函数返回一个有终点和起点的固定步长的排列,如[1,2,3,4,5],起点是1,终点是6,步长为1。
    参数个数情况: np.arange()函数分为一个参数,两个参数,三个参数三种情况
    1)一个参数时,参数值为终点,起点取默认值0,步长取默认值1。

    例a = np.arange(3) ,默认起点为0,步长为1,输出[0,1,2]

    2)两个参数时,第一个参数为起点,第二个参数为终点,步长取默认值1。

    例a = np.arange(3,9),起点为3,默认步长为1,输出[3,4,5,6,7,8]

    3)三个参数时,第一个参数为起点,第二个参数为终点,第三个参数为步长。其中步长支持小数

    例a = np.arange(0,0.5,0.1),起点为0,步长为0.1,输出[0,0.1,0.2,0.3,0.4]

  • np.zeros()

    函数返回来一个给定形状和类型的用0填充的数组;
    zeros(shape, dtype=float, order=‘C’)
    shape:形状
    dtype:数据类型,可选参数,默认numpy.float64
    order:可选参数,c代表与c语言类似,行优先;F代表列优先

  • np.meshgrid()

    函数用于生成网格采样点矩阵

二维

X, Y = np.meshgrid(x, y)

假设 x, y 分别为 m, n 维向量,则矩阵(数组)X, Y 的 dimension 都是: [公式] 。其中矩阵 X 中的行都为向量 x,矩阵 Y 的列都为向量 y

三维

X, Y, Z = np.meshgrid(x, y, z)

假设 x, y, z 分别为 m, n, l 维向量, 则矩阵(数组)X, Y, Z 的 Dimension 都是 [公式]

image-20220119195728988

  • append()

    函数用来向列表末尾追加元素。

image-20220119195808444

  • contour()用来绘制等高线

https://blog.csdn.net/xuxinrk/article/details/80841879

  • plot()

matlab中二维线画图函数。

https://zhuanlan.zhihu.com/p/258106097

图中’+‘为w,b的最优解位置,黑色即为w,b的变化路线,背景色表示Z(loss)值的大小。

结果:此时路径并未通过b和w最佳值,说明代码还需要优化。

方法一:直接对learning rate进行优化:
设置自适应learning rate(开始时lr大,随后逐渐变小),同时对不同的参数采取不同的lr,也即adagrad方法。

lr增加十倍,改为0.000001 ,此时

image-20220119200036865

lr再增加十倍,改为0.00001,此时

image-20220119200120110

总结,对learning rate进行改进,很难找到恰当的learning rate正确得到最终w和b的最佳值。

方法二:对learning rate进行分类优化:

以下是后半段改进的代码

image-20220119200938515

得到结果:

image-20220119201014009

改进前代码

import numpy as np
import matplotlib.pyplot as plt
x_data=[338.,333.,328.,207.,226.,25.,179.,60.,208.,606.]#进化前cp数组
y_data=[640.,633.,619.,393.,428.,27.,193.,66.,226.,1591.]#进化后战斗力
#假设模型-y_data = b + w * x_data
x = np.arange(-200,-100,1) #bias(b),从-200到-100,以步长为1为间隔返回数组
y = np.arange(-5,5,0.1) #weight(w),从-5到5,以步长为0.1为间隔返回数组
#返回来一个形状为len(x)*len(y)的零数组,存放loss值的矩阵(100*100)
Z = np.zeros((len(x),len(y)))
X, Y = np.meshgrid(x,y)#生成网格点坐标矩阵
#遍历x,y,计算每组的loss function;当b = x[i],w=y[j]时
#loss(f(w,b)) = Σ(y_data[n]-b-w*x_data[n])**2
for i in range(len(x)):
    for j in range(len(y)):
        #利用x,y中所有的元素
        b = x[i]
        w = y[j]
        #初始化loss值,用于累加
        Z[j][i] = 0
        #计算数据对b = x[i],w = y[j]时总的loss值(利用十组样本数据)
        for n in range(len(x_data)):
            Z[j][i] = Z[j][i] + (y_data[n] - b - w*x_data[n])**2
        # 求b = x[i],w = y[j]时的平均loss值
        Z[j][i] = Z[j][i]/len(x_data)
        
#y_data = b + w * x_data
#初始化w,b(随机的初始化,保证w,b在范围内即可)
b = -120 #initial b
w = -4 #initial w
lr = 1  
 #步长,learning rate
iteration = 100000#迭代数

#store initial value for plotting
#用于画图
b_history = [b]
w_history = [w]


#iteration
for i in range(iteration):
    # b_grad,w_grad用于累加,所以初始化为0(≠b,w)
    b_grad = 0.0
    w_grad = 0.0
    for n in range(len(x_data)):
        #损失函数对b的偏微分
        b_grad = b_grad - 2.0 *(y_data[n] - b - w * x_data[n])*(1.0)
        #损失函数对w的偏微分
        w_grad = w_grad - 2.0 *(y_data[n] - b - w * x_data[n])*(x_data[n])
    
    #update parameters
    # 向loss值减小方向移动,更新b,w值
    b = b - lr * b_grad
    w = w - lr * w_grad
    
    #store parameters for plotting
    # 将更新后的b,w值加入列表,绘制等高线
    b_history.append(b)
    w_history.append(w)
    
#plot the figure
# 输入x,y,Z(loss值)生成等高线,按照高度分为50层(颜色代表Z大小)
# 并设置属性--透明度0.5,颜色‘jet’一种过度色
plt.contourf(x,y,Z,50,alpha=0.5,cmap=plt.get_cmap('jet'))
# markeredgewidth设置标记的宽度,‘+’表示标记的形状
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')
# 限制x,y坐标范围
plt.xlim(-200,-100)
plt.ylim(-5,5)
# 设置坐标标签及其属性
plt.xlabel(r'$b$',fontsize=16)
plt.ylabel(r'$w$',fontsize=16)
#显示最终w,b的最佳值:2.4834016183794727 -123.6921749751593
plt.show()         
    

改进后代码

import numpy as np
import matplotlib.pyplot as plt
x_data=[338.,333.,328.,207.,226.,25.,179.,60.,208.,606.]#进化前cp数组
y_data=[640.,633.,619.,393.,428.,27.,193.,66.,226.,1591.]#进化后战斗力
#假设模型-y_data = b + w * x_data
x = np.arange(-200,-100,1) #bias(b),从-200到-100,以步长为1为间隔返回数组
y = np.arange(-5,5,0.1) #weight(w),从-5到5,以步长为0.1为间隔返回数组
#返回来一个形状为len(x)*len(y)的零数组,存放loss值的矩阵(100*100)
Z = np.zeros((len(x),len(y)))
X, Y = np.meshgrid(x,y)#生成网格点坐标矩阵
#遍历x,y,计算每组的loss function;当b = x[i],w=y[j]时
#loss(f(w,b)) = Σ(y_data[n]-b-w*x_data[n])**2
for i in range(len(x)):
    for j in range(len(y)):
        #利用x,y中所有的元素
        b = x[i]
        w = y[j]
        #初始化loss值,用于累加
        Z[j][i] = 0
        #计算数据对b = x[i],w = y[j]时总的loss值(利用十组样本数据)
        for n in range(len(x_data)):
            Z[j][i] = Z[j][i] + (y_data[n] - b - w*x_data[n])**2
        # 求b = x[i],w = y[j]时的平均loss值
        Z[j][i] = Z[j][i]/len(x_data)
        
#y_data = b + w * x_data
#初始化w,b(随机的初始化,保证w,b在范围内即可)
b = -120 #initial b
w = -4 #initial w
lr = 1  
 #步长,learning rate
iteration = 100000#迭代数

#改进,对lr进行分类
lr_b=0.0
lr_w=0.0

#store initial value for plotting
#用于画图
b_history = [b]
w_history = [w]


#iteration
for i in range(iteration):
    # b_grad,w_grad用于累加,所以初始化为0(≠b,w)
    b_grad = 0.0
    w_grad = 0.0
    for n in range(len(x_data)):
        #损失函数对b的偏微分
        b_grad = b_grad - 2.0 *(y_data[n] - b - w * x_data[n])*(1.0)
        #损失函数对w的偏微分
        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
    # 向loss值减小方向移动,更新b,w值
    b = b - lr/np.sqrt(lr_b) * b_grad
    w = w - lr/np.sqrt(lr_w) * w_grad
    
    #store parameters for plotting
    # 将更新后的b,w值加入列表,绘制等高线
    b_history.append(b)
    w_history.append(w)
    
#plot the figure
# 输入x,y,Z(loss值)生成等高线,按照高度分为50层(颜色代表Z大小)
# 并设置属性--透明度0.5,颜色‘jet’一种过度色
plt.contourf(x,y,Z,50,alpha=0.5,cmap=plt.get_cmap('jet'))
# markeredgewidth设置标记的宽度,‘+’表示标记的形状
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')
# 限制x,y坐标范围
plt.xlim(-200,-100)
plt.ylim(-5,5)
# 设置坐标标签及其属性
plt.xlabel(r'$b$',fontsize=16)
plt.ylabel(r'$w$',fontsize=16)
#显示最终w,b的最佳值:2.4834016183794727 -123.6921749751593
plt.show()         
    
posted @   L-Yeeky  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示