美文网首页
梯度下降法

梯度下降法

作者: 原上的小木屋 | 来源:发表于2020-09-17 18:50 被阅读0次

    机器利用数据学习的过程

    1. 建立模型y=wx+b
    2. 学习模型确定w,b
    3. 预测或识别
    • 在上述三个步骤中,最关键的就是第二步。如何从数据中产生模型是机器学习的主要研究内容

    数据集/样本集

    1. 数据集中的每一条记录称为样本,样本由属性和标记组成
    2. 对有标记的数据集的学习叫做监督学习,监督学习的过程就是对数据的学习。总结出属性/标记之间的映射关系,即为模型。
    3. 模型一般称为假设或学习器,通常用一个估计函数来表示,学习到的模型应该逼近真实存在的规律。这个真实存在的规律称为ground truth,我们将其称为真实

    监督学习:回归与分类

    无监督学习:在样本数据没有标记的情况下,挖掘出数据内部蕴含的关系。如聚类

    1. 聚类:把相似度高的样本聚合在一起,物以类聚、人以群分
    2. 距离:描述了特征值之间的相似度

    半监督学习

    1. 将有监督学习和无监督学习相结合
    2. 综合使用大量的没有标记数据和少量有标记的数据共同进行学习

    一元线性回归:在给定的已知点的基础上,预测出更精准的直线

    y=wx+b模型变量:x模型参数 w:权重;b:偏置值

    如何由给定的样本x和y的值确定模型参数w和b的值

    1. 样本:(x_1,y_1),(x_2,y_2),...,(x_i,y_i),...,(x_n,y_n)
    2. 拟合误差/残差:样本点到直线的竖直距离y_i-\hat{y}_i=y_i-(wx_i+b)
    3. 估计值: \hat{y}_i=wx_i+b
      最佳拟合直线应该使得所有点的残差累计值最小
    4. 残差和最小Loss=\sum^{n}_{i=1}(y_i-\hat{y}_i)=\sum^{n}_{i=1}(y_i-(wx_i+b))
    5. 残差绝对值和最小Loss=\sum^{n}_{i=1}|y_i-\hat{y}_i|=\sum^{n}_{i=1}|y_i-(wx_i+b)|
    6. 残差平方和最小Loss=\frac {1}{2} \sum^{n}_{i=1}(y_i- \hat{y}_i)^2=\frac {1}{2} \sum^{n}_{i=1}(y_i - (wx_i+b))^2平方损失函数,均方差损失函数

    其他损失函数的两个性质

    1. 非负性:保证样本误差不会相互抵消
    2. 一致性:损失函数的值和误差变化一致单调有界并收敛于0

    最小二乘法

    Loss=\frac {1}{2} \sum^{n}_{i=1}(y_i-\hat{y}_i)^2=\frac {1}{2}\sum^{n}_{i=1}(y_i - (wx_i+b))^2

    1. 已知:(x_1,y_1),(x_2,y_2),...,(x_i,y_i),...,(x_n,y_n)
    2. 未知:w,b
      w,b取何值时,Loss取值最小\Longrightarrow求极值问题:极值点的偏导数为零
      \frac {\partial Loss} {\partial w}=\sum^{n}_{i=1}(y_i-b-wx_i)(-x_i)=0, \frac {\partial Loss}{\partial b}=\sum^{n}_{i=1}(y_i-b-wx_i)(-1)=0

    梯度下降法

    1. 解析解根据严格的推导和计算得到,是方程的精确解,可以在任意精度下满足方程
    2. 数值解通过某种近似计算得到的解,能够在给定的精度下满足方程
    3. 一元凸函数求极值
      步长太小,迭代次数多,收敛慢
      步长太大,引起震荡,可能无法收敛
      使用斜率去调节步长步长=\eta\frac {df(x)}{dx},\eta:学习率x^{(k+1)}=x^{(k)}-\eta\frac {df(x)}{dx}
    4. 二元凸函数f(x,y)迭代算法x^{(k+1)}=x^{(k)}-\eta \frac {df(x,y)}{dx},y^{(k+1)}=y^{(k)}-\eta\frac {df(x,y)}{dy}

    对于机器学习算法,只要能够把损失函数描述成凸函数,就一定可以采用梯度下降法,以最快的速度更新权值向量w,找出使损失函数达到最小值点的位置

    • 自动调节步长
    • 自动确定下一次更新的方向
    • 保证收敛性

    使用梯度下降法求解一元线性回归问题

    Loss=\frac {1}{2} \sum^{n}_{i=1}(y_i-\hat{y}_i)^2= \frac {1}{2}\sum^{n}_{i=1}(y_i-(wx_i+b))^2=\sum^{n}_{i=1}(x^{2}_{i}w^2+b^2+2x_i wb-2y_i b-2x_i y_iw+y^{2}_{i})=Aw^2+Bb^2+Cwb+Dw+Eb+F

    • 编程中损失函数经常使用均方差损失函数Loss=\frac {1}{2n} \sum^{n}_{i=1}(y_i-\hat{y}_i)^2=\frac {1}{2n}\sum^{n}_{i=1}(y_i-(wx_i+b))^2
    • 模型参数更新算法w^{(k+1)}=w^{(k)}-\frac {\eta}{n}\sum^{n}_{i=1}x_i(wx_i+b-y_i), b^{(k+1)}=b^{(k)}-\frac {\eta}{n}\sum^{n}_{i=1}(wx_i+b-y_i)

    详细步骤

    1. 加在样本数据x,y
    2. 设置超参数学习率、迭代次数
    3. 设置模型参数初值w_0,b_0
    4. 训练模型w,b
    5. 结果可视化
    import numpy as np
    import matplotlib.pyplot as plt
    x=np.array([137.97,104.50,100.00,124.32,79.20,99.00,124.00,114.00,106.90,138.05,53.75,46.91,68.00,63.02,81.26,86.21])
    y=np.array([145.00,110.00,93.00,116.00,65.32,104.00,118.00,91.00,62.00,133.00,51.00,45.00,78.50,69.65,75.69,95.30])
    learn_rate=0.00001 #学习率
    iter=100 #迭代次数
    display_step=10
    np.random.seed(612)
    # 设置w,b的初始值
    w=np.random.randn()
    b=np.random.randn()
    # 训练模型
    mse=[]
    for i in range(0,iter+1):
        dL_dw=np.mean(x*(w*x+b-y))
        dL_db=np.mean(w*x+b-y)
        
        w=w-learn_rate*dL_dw
        b=b-learn_rate*dL_db
        
        pred=w*x+b
        Loss=np.mean(np.square(y-pred))/2
        
        mse.append(Loss)
        if(i%display_step==0):
            print("i:%i,Loss:%f,w:%f,b:%f" % (i,mse[i],w,b))
        
    
    i:0,Loss:3874.109891,w:0.082574,b:-1.161967
    i:10,Loss:562.192567,w:0.648530,b:-1.156447
    i:20,Loss:148.653167,w:0.848517,b:-1.154463
    i:30,Loss:97.016943,w:0.919184,b:-1.153729
    i:40,Loss:90.569412,w:0.944155,b:-1.153436
    i:50,Loss:89.764324,w:0.952978,b:-1.153299
    i:60,Loss:89.663774,w:0.956096,b:-1.153217
    i:70,Loss:89.651196,w:0.957197,b:-1.153155
    i:80,Loss:89.649602,w:0.957586,b:-1.153099
    i:90,Loss:89.649380,w:0.957723,b:-1.153046
    i:100,Loss:89.649329,w:0.957771,b:-1.152994
    
    plt.rcParams['font.sans-serif']=['SimHei']
    plt.figure()
    plt.scatter(x,y,color='red',label="销售记录")
    plt.scatter(x,pred,color="blue")
    plt.plot(x,pred,color="blue",label="梯度下降法")
    plt.plot(x,0.89*x+5.41,color="green",label="解析法")
    
    plt.xlabel("Area",fontsize=14)
    plt.ylabel("Price",fontsize=14)
    
    plt.legend(loc="upper left")
    plt.show()
    
    output_2_0.png

    梯度下降法求解多元线性回归

    1. 需要对数据进行归一化/标准化:将数据的值限制在一定的范围之内使所有属性处于同一范围、同一数量级下,更快收敛到最优解,提高学习器的精度
    2. 归一化分类线性归一化、标准差归一化、非线性映射归一化
    3. 线性归一化x^*=\frac {x-min}{max-min}、标准差归一化x^*=\frac {x-\mu}{\sigma}、非线性映射归一化:对原始数据的非线性变换指数、对数、正切

    梯度下降法步骤

    1. 确定损失函数
    2. 损失函数求导数计算梯度
    3. 更新模型参数

    tensorflow提供了强大的自动求导机制

    Variable对象

    1. 对tensor对象的进一步封装
    2. 在模型训练过程中自动记录梯度信息,由算法自动优化
    3. 可以被训练的变量
    4. 在机器学习中可以作为模型参数
      tf.Variable(initial_value,dtype)
    5. 将张量封装为可训练变量
    import tensorflow as tf
    
    tf.Variable(3)
    
    <tf.Variable 'Variable:0' shape=() dtype=int32, numpy=3>
    
    x=tf.Variable(tf.constant([[1,2],[3,4]]))
    
    x[0]
    
    <tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 2])>
    
    type(x[0])
    
    tensorflow.python.framework.ops.EagerTensor
    

    tensorflow自动求导机制--G'radientTape

    with GrandientTape() as tape:
       函数表达式
    grad=tape.gradient(函数,自变量)
    
    1. 多元函数求偏导
      tape.gradient(函数,自变量)
    x=tf.Variable(3.)
    with tf.GradientTape() as tape:
        y=x*x
    dy_dx=tape.gradient(y,x)
    
    y,dy_dx
    
    (<tf.Tensor: shape=(), dtype=float32, numpy=9.0>,
     <tf.Tensor: shape=(), dtype=float32, numpy=6.0>)
    

    tensorflow实现梯度下降法

    1. 导入需要的库
    2. 加载数据样本
    3. 设置超参数
    4. 设置模型参数初始值
    5. 训练模型
    import numpy as np
    import tensorflow as tf
    import matplotlib.pyplot as plt
    x=np.array([137.97,104.50,100.00,124.32,79.20,99.00,124.00,114.00,106.90,138.05,53.75,46.91,68.00,63.02,81.26,86.21])
    y=np.array([145.00,110.00,93.00,116.00,65.32,104.00,118.00,91.00,62.00,133.00,51.00,45.00,78.50,69.65,75.69,95.30])
    learn_rate=0.0001 #学习率
    iter=100 #迭代次数
    display_step=10
    np.random.seed(612)
    # 设置w,b的初始值
    np.random.seed(612)
    w=tf.Variable(np.random.randn())
    b=tf.Variable(np.random.randn())
    # 训练模型
    mse=[]
    for i in range(0,iter+1):
        with tf.GradientTape() as tape:
            pred=w*x+b
            Loss=0.5*tf.reduce_mean(tf.square(y-pred))
        mse.append(Loss)
        
        dL_dw,dL_db=tape.gradient(Loss,[w,b])
        
        w.assign_sub(learn_rate*dL_dw)
        b.assign_sub(learn_rate*dL_db)
        
        if(i%display_step==0):
            print("i:%i,Loss:%f,w:%f,b:%f" % (i,mse[i],w,b))
    
    i:0,Loss:4749.374023,w:0.946134,b:-1.153577
    i:10,Loss:89.649315,w:0.957797,b:-1.152948
    i:20,Loss:89.649063,w:0.957792,b:-1.152432
    i:30,Loss:89.648788,w:0.957787,b:-1.151916
    i:40,Loss:89.648529,w:0.957782,b:-1.151399
    i:50,Loss:89.648277,w:0.957777,b:-1.150883
    i:60,Loss:89.647995,w:0.957772,b:-1.150367
    i:70,Loss:89.647720,w:0.957767,b:-1.149851
    i:80,Loss:89.647469,w:0.957762,b:-1.149335
    i:90,Loss:89.647194,w:0.957757,b:-1.148818
    i:100,Loss:89.646942,w:0.957752,b:-1.148302
    

    模型评估

    1. 误差:学习器的预测输出和样本的真实标记之间的差异
    2. 训练误差:训练集上的误差
    3. 泛化误差:在新样本上的误差
    4. 过拟合:学习过度,在训练集上表现很好,在新样本上泛化误差很大
    5. 欠拟合:学习不足,没有学习到样本中的通用的特征

    机器学习的目标:泛化误差小

    训练集和测试集

    1. 训练集:训练模型
    2. 测试集:测试学习器在新样本上的预测或判断能力
    3. 测试误差:用来近似泛化误差

    公共数据集:由研究机构或大型公司创建和维护

    相关文章

      网友评论

          本文标题:梯度下降法

          本文链接:https://www.haomeiwen.com/subject/exlryktx.html