• Gradient Descent


    目录

    1.Assignment

    2. Algorithm

    3. Gradient Descent(Batch)

    Gradient Descent(Batch)

    Code

    4. Stochastic Gradient Descent

    Stochastic Gradient Descent

    Code

    5. Different of Gradient method


    学习内容来自:b站的刘二大人----《PyTorch深度学习实践》

    1.Assignment

    假设我们的Training set 是

    xy(hat)
    12
    24
    36

    建立一个model ,预测输入x = 4的时候,y是多少

    2. Algorithm

    之前的穷举法虽然简单,但是有很多的问题。穷举顾名思义就是通过暴力手段找到所有的情况,然后找出最优解。但是如果训练的模型更加复杂,例如函数不仅仅有斜率,还有更多的w1,w2...等等,那么穷举出的范围将会特别多

    这里也可以用一些别的算法进行优化,比如分治法

    分治法:将大的问题划分为小的问题,然后着重解决小的问题,逐个击破,最终解决大的问题

    例如:函数有两个参数w1,w2。假设通过分析,两个最好的范围是1-100,那么如果根据穷举会有100*100的范围。而分治法的思想是,先取其中几个点,假设w1取10、80,w2取10,80,在这四个点找到最优的解(假设是w1=10,w2=80),然后在这个最优的点在划分,直到找到这个问题的解

    但是这个算法有个问题,就是如果全局范围的最优解是w1=50,w2=50。而我们根据第一次的划分,去w1=10,w2=80的附近去找了。那么,最后找的的解是10,80附近一小块的最优解,从而导致我们的解会陷入局部最优(Local optimal)的问题。

    还可以尝试另一种算法,贪心算法

    贪心算法:求解问题,不去考虑全局的解。只考虑当前情况最好的选择,不从整体考虑,关注局部最优解

    而本章的梯度下降就是根据贪心算法

    3. Gradient Descent(Batch)

    Gradient Descent(Batch)

    简单理解梯度,梯度是个矢量,函数在这个点的方向导数沿着梯度方向取最大值(方向导数是个数),也就是说函数沿着梯度方向变化最快。

    在一元函数中,梯度就是函数的导数,所以函数沿着斜率变化的最快

    在多元函数中,代表偏导数的意思

    那么根据MSE均方差定义的Cost函数,w更新的方向为:

    1. 因为我们是要用梯度下降找到最好的w值,也就是最好的函数。所以应该根据梯度更新w的值,因为cost 成本函数沿着梯度下降的最快

    2. 因为梯度是增加的方向,而我们需要将cost函数的值降低,从而使 模型的预测值和 数据的真实值 误差足够下。所以这里更新的是 负梯度的方向

    3. α 是学习率 learning rate ,代表一次梯度下降走的步长。学习率过大,会发散

    那么根据链式法则chain rule 可知,cost对w的导数为:

    也就是:

    Code

    1. import matplotlib.pyplot as plt
    2. x_data =[1.0,2.0,3.0]
    3. y_data = [2.0,4.0,6.0]
    4. w = 1.0
    5. epoch_list = []
    6. cost_list = []
    7. def forward (x):
    8. return x *w
    9. def cost(xs, ys):
    10. cost = 0
    11. for x, y in zip(xs,ys):
    12. y_pred = forward(x)
    13. cost += (y_pred - y)**2
    14. return cost / len(xs)
    15. def gradient(xs,ys):
    16. grad = 0
    17. for x, y in zip(xs,ys):
    18. grad += 2*x*(x* w - y)
    19. return grad / len(xs)
    20. print ('Predict (before training)',4, forward(4))
    21. for epoch in range(100):
    22. cost_val = cost(x_data,y_data)
    23. grad_val = gradient(x_data,y_data)
    24. w-= 0.01* grad_val
    25. epoch_list.append(epoch)
    26. cost_list.append(cost_val)
    27. print(' Epoch:', epoch,'w=',w, 'loss=', cost_val)
    28. print(' Predict (after training)',4,forward(4))
    29. plt.plot(epoch_list,cost_list)
    30. plt.xlabel('w')
    31. plt.ylabel('Cost')
    32. plt.show()

    代码部分输出为:

    Predict (before training) 4 4.0
     Epoch: 0 w= 1.0933333333333333 loss= 4.666666666666667
     Epoch: 1 w= 1.1779555555555554 loss= 3.8362074074074086
    ....
     Epoch: 36 w= 1.9733582330705144 loss= 0.004029373553099482
     Epoch: 37 w= 1.975844797983933 loss= 0.0033123241439168096
     Epoch: 38 w= 1.9780992835054327 loss= 0.0027228776607060357
    .....
     Epoch: 61 w= 1.9976998600690001 loss= 3.0034471708953996e-05
     Epoch: 62 w= 1.9979145397958935 loss= 2.4689670610172655e-05
     Epoch: 63 w= 1.9981091827482769 loss= 2.0296006560253656e-05
     Epoch: 64 w= 1.9982856590251044 loss= 1.6684219437262796e-05
    ....
     Epoch: 97 w= 1.9999324119941766 loss= 2.593287985380858e-08
     Epoch: 98 w= 1.9999387202080534 loss= 2.131797981222471e-08
     Epoch: 99 w= 1.9999444396553017 loss= 1.752432687141379e-08
     Predict (after training) 4 7.999777758621207
     

    图像结果:

     

    4. Stochastic Gradient Descent

    Stochastic Gradient Descent

    随机梯度下降意思是随机找一个样本进行梯度下降

    而上面的Gradient Descent 梯度下降法 是对整个样本,也就是整个训练集 Cost 进行下降

    区别就是:

    • 假设Cost 函数进入了一个学习高原区(梯度几乎消失的区域),那么因为偏导数为0,就会导致w不进行更新。而SGD是随机选择一个样本,通常来说,单个样本会有噪声,可能会推动梯度下降
    • 整个训练集的梯度下降,将所有的样本求和,计算量大,时间复杂度小
    • SGD针对于单个样本,计算量小,但是时间复杂度会大

    二者的区别大概如图:

    所以,梯度下降是对cost所有样本,SGD是对Loss单个样本

    Code

    1. import matplotlib.pyplot as plt
    2. x_data =[1.0,2.0,3.0]
    3. y_data = [2.0,4.0,6.0]
    4. w = 1.0
    5. epoch_list = []
    6. loss_list = []
    7. def forward (x):
    8. return x *w
    9. def loss(x, y):
    10. y_pred = forward(x)
    11. return (y_pred - y)**2
    12. def gradient(x,y):
    13. return 2*x*(x*w-y)
    14. print ('Predict (before training)',4, forward(4))
    15. for epoch in range(100):
    16. for x,y in zip(x_data,y_data):
    17. grad = gradient(x,y)
    18. w -= 0.01 * grad
    19. print('\tgrad:',x,y,grad)
    20. l = loss(x,y)
    21. print('Progress:', epoch, 'w=', w, 'loss=', l)
    22. loss_list.append(l)
    23. epoch_list.append(epoch)
    24. print('Predict (after training)',4,forward(4))
    25. plt.plot(epoch_list,loss_list)
    26. plt.xlabel('epoch')
    27. plt.ylabel('loss')
    28. plt.show()

     代码输出:

    Predict (before training) 4 4.0
        grad: 1.0 2.0 -2.0
        grad: 2.0 4.0 -7.84
        grad: 3.0 6.0 -16.2288
    Progress: 0 w= 1.260688 loss= 4.919240100095999
        grad: 1.0 2.0 -1.478624
        grad: 2.0 4.0 -5.796206079999999
        grad: 3.0 6.0 -11.998146585599997
    Progress: 1 w= 1.453417766656 loss= 2.688769240265834
        grad: 1.0 2.0 -1.093164466688
        grad: 2.0 4.0 -4.285204709416961
        grad: 3.0 6.0 -8.87037374849311
    Progress: 2 w= 1.5959051959019805 loss= 1.4696334962911515
        grad: 1.0 2.0 -0.8081896081960389
        grad: 2.0 4.0 -3.1681032641284723
        grad: 3.0 6.0 -6.557973756745939
    .....
    Progress: 22 w= 1.9990383027488265 loss= 8.323754426231206e-06
        grad: 1.0 2.0 -0.001923394502346909
        grad: 2.0 4.0 -0.007539706449199102
        grad: 3.0 6.0 -0.01560719234984198
    Progress: 23 w= 1.9992890056818404 loss= 4.549616284094891e-06
        grad: 1.0 2.0 -0.0014219886363191492
        grad: 2.0 4.0 -0.005574195454370212
        grad: 3.0 6.0 -0.011538584590544687
    ....
    Progress: 72 w= 1.999999999734279 loss= 6.354692062078993e-19
        grad: 1.0 2.0 -5.314420015167798e-10
        grad: 2.0 4.0 -2.0832526814729135e-09
        grad: 3.0 6.0 -4.31233715403323e-09
    Progress: 73 w= 1.9999999998035491 loss= 3.4733644793346653e-19
        grad: 1.0 2.0 -3.92901711165905e-10
        grad: 2.0 4.0 -1.5401742103904326e-09
        grad: 3.0 6.0 -3.188159070077745e-09
    Progress: 74 w= 1.9999999998547615 loss= 1.8984796531526204e-19
        grad: 1.0 2.0 -2.9047697580608656e-10
        grad: 2.0 4.0 -1.1386696030513122e-09
        grad: 3.0 6.0 -2.3570478902001923e-09
    .....
    Progress: 97 w= 1.9999999999998603 loss= 1.757455879087579e-25
        grad: 1.0 2.0 -2.793321129956894e-13
        grad: 2.0 4.0 -1.0942358130705543e-12
        grad: 3.0 6.0 -2.2648549702353193e-12
    Progress: 98 w= 1.9999999999998967 loss= 9.608404711682446e-26
        grad: 1.0 2.0 -2.0650148258027912e-13
        grad: 2.0 4.0 -8.100187187665142e-13
        grad: 3.0 6.0 -1.6786572132332367e-12
    Progress: 99 w= 1.9999999999999236 loss= 5.250973729513143e-26
    Predict (after training) 4 7.9999999999996945

    输出图像:

    5. Different of Gradient method

     梯度下降大概可以分为三类:

    • Batch Gradient Descent:针对于所有样本 cost 函数的,batch是 ‘批、捆’ 的意思,一般来说针对于所有的样本的梯度下降,就简称Gradient Descent
    • Stochastic Gradient Descent:针对于单个样本的,即针对loss函数的为随机梯度下降
    • mini-Batch Gradient Descent:二者折中,会有个size的概念,就是将整个样本分成多少分,每个里面的个数就是size

    epoch : 代表将所有的batch ,也就是整个训练集 训练完是一个epoch

    update:将单个batch 训练完,叫做一个更新,更新 权重w

    所以,当size = 整个样本的时候,就是 Batch Gradient Descent

    当size = 1 的时候,就是Stochastic Gradient Descent

    关于其他的补充:

    梯度下降法:计算量很大,但是时间复杂度小

    随机梯度下降法:计算量小,但是时间复杂度会很大。而且没有使用向量化加速

    小批量梯度下降法:二者折中,应用比较普遍

     

  • 相关阅读:
    Dll文件注册器 - 开源研究系列文章 - 个人小作品
    TypeScript学习
    刚体动力学-牛顿欧拉方程(刚体旋转)
    设计模式-命令模式
    java计算机毕业设计口红专卖网站源码+mysql数据库+系统+lw文档+部署
    云计算:未来科技的基石
    “元创新·智生成” 第15届企业数智化学习大会公布嘉宾阵容
    uniapp 之使用 u-upload 组件来实现图片上传
    mysql数据库概述及安装
    nodejs基于微信小程序的书籍销售系统--(ssm+uinapp+Mysql)
  • 原文地址:https://blog.csdn.net/qq_44886601/article/details/125468852