• 李宏毅 Gradient Descent Demo 代码讲解


    何为梯度下降,直白点就是,链式求导法则,不断更新变量值。

    这里讲解的代码为李宏毅老师机器学习课程中 class 4 回归展示 中的代码demo
     

    Loss函数

    python代码如下

    import numpy as np  
    import matplotlib.pyplot as plt  
    
    # y_data = b + w * x_data  
    x_data = [338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]   # 10 个数
    y_data = [640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]  # 10 个数
      
    x = np.arange(-200, -100, 1)     # bias  
    y = np.arange(-5, 5, 0.1)        # weight  
    z = np.zeros((len(x), len(y)))   # zeros函数表示输出的数组为 100行 100列  
    
    #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] 时,对应的 Loss Function 的大小  
                z[j][i] = z[j][i] + (y_data[n] - b - w * x_data[n]) ** 2    
            z[j][i] = z[j][i] / len(x_data)    # 求 loss function 均值 
      
    # y_data = b + w * x_data  
    b = -120              # initial b  
    w = -4                # initial w  
    lr = 0.0000001          # learning rate  
    iteration = 100000    # 迭代运行次数  
      
    # store initial values for plotting  
    b_history = [b]  
    w_history = [w]  
    
    # iterations  
    for i in range(iteration):      # 在 100000 次迭代下,看最后结果  
        b_grad = 0.0                # 对 b_grad 重新赋值为0  
        w_grad = 0.0                # 对 w_grad 重新赋值为0  
        for n in range(len(x_data)):  
            # 此处应该注意的是,求导的是Loss函数,因此对应的变量是w、b,是看w、b在各自的轴上的移动  
            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)  
      
    # plot the figure  
    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()  

    当learning rate 即 lr = 0.0000001时

    当learning rate 即 lr = 0.000001时

    learning rate 即 lr = 0.00001时

    可以看到效果不是很好 所以改变learning rate

    import numpy as np
    import matplotlib.pyplot as plt
    
    # y_data = b + w * x_data
    x_data = [338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]  # 10 个数
    y_data = [640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]  # 10 个数
    
    x = np.arange(-200, -100, 1)  # bias
    y = np.arange(-5, 5, 0.1)  # weight
    z = np.zeros((len(x), len(y)))  # zeros函数表示输出的数组为 100 行 100 列
    
    # 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] 时,对应的 Loss Function 的大小
                z[j][i] = z[j][i] + (y_data[n] - b - w * x_data[n]) ** 2
            z[j][i] = z[j][i] / len(x_data)  # 求 loss function 均值
    
    # ydata = b + w * xdata
    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]
    
    # 个性化 w 和 b 的 learning rate
    lr_b = 0
    lr_w = 0
    
    # iterations
    for i in range(iteration):  # 在 100000 次迭代下,看最后结果
        b_grad = 0.0  # 对 b_grad 重新赋值为0
        w_grad = 0.0  # 对 w_grad 重新赋值为0
        for n in range(len(x_data)):
            # 此处应该注意的是,求导的是L函数,因此对应的变量是w、b,是看w、b在各自的轴上的移动
            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)
    
    # plot the figure
    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()

    结果展示

     

    一些说明:

    np.array np.asarray的区别

    array和asarry都可以将结构数据转换为ndarray类型

    但是主要的区别在于当数据源是ndarray时,array仍会copy出一个副本,占用新的内存,但asarray不会。

    np.meshgrid的作用

    生成网格点坐标矩阵

     
  • 相关阅读:
    python学习笔记 | 国内常用源镜像地址
    python学习笔记 | macOS Big Sur动态壁纸食用指南
    GitHub README.md文本编写指南
    FAT32、NTFS、exFAT有什么区别?
    python模块详解 | unittest(单元测试框架)(持续更新中)
    Linux学习笔记 | 常见错误之账户密码正确但是登录不进去系统
    数学建模学习笔记 | matlab基本命令及用法
    selenium自动化 | 借助百度AI开放平台识别验证码登录职教云
    JAVA集合框架
    JAVA集合框架
  • 原文地址:https://www.cnblogs.com/baobaotql/p/11388837.html
Copyright © 2020-2023  润新知