![419f3a79e7561abefed9b842bd9ace98.png](https://i-blog.csdnimg.cn/blog_migrate/0f6698b9d1164e94c652c65ae39dcc07.jpeg)
1 引例
本文首发于公众号:月来客栈,欢迎搜索关注!
在前面的介绍中,笔者都是不假思索的直接给出了线性回归的目标函数
根据前面的介绍我们知道,梯度下降算法的目的是用来最小化目标函数,也就是一个求解的工具。当目标函数取到(或接近)最小值时,我们也就求解得到了对应的参数。那什么又是梯度下降(Gradient Descent)呢?如下图所示,假设现在有这么一个山谷并且你此时处于位置A处,问以什么样的方向(角度)往前跳,你才能最快的到达谷底B处呢?
![5b62747364f4ea509e78505589bcda1a.png](https://i-blog.csdnimg.cn/blog_migrate/6083fc73d2371b4c0017384d833907de.jpeg)
现在你大致有三个方向可以选择,沿着X轴的
2 方向导数与梯度
我们在学习一元函数导数的时候老师讲过,
其中
在上图中,已知
![0abf969889373a0950a1f75b120a3a5e.png](https://i-blog.csdnimg.cn/blog_migrate/b3a1c54f3b90574b0f3312c479e3dcb8.jpeg)
通过以上便可以知道,要想每次都能以最快的速度下降,那么每次都得向着梯度的反方向向前跳。
3 梯度下降算法
介绍这么多总算是把梯度这回事儿给说清楚了,那么怎么样用具体的数学表达式进行描述呢?总不能一个劲儿的喊它“跳”对吧。为了方便后面的表述以及将大家带入到一个真实求解的过程中,我们将上图中的字母替换成模型中的表述。现在有一个模型的目标函数为
![40d674c8d82f4de369bb2777bbad124f.png](https://i-blog.csdnimg.cn/blog_migrate/62f188ea0ef298615c8705ed144a61bb.jpeg)
设初始点
![4e48674b09612226e1383d1adff12059.png](https://i-blog.csdnimg.cn/blog_migrate/5395332d256b12b1c4bfc26ded648de5.png)
从上图可以看出,向量
又由于
其中
此时,权重参数便从
至此,我们便详细的完成了一轮梯度下降的计算。如下图所示,当A跳跃到P之后,又可以再次利用梯度下降算法进行跳跃,直到跳到谷底(或附近)。
![9334a5a4e6b694a882adec706b4ac934.png](https://i-blog.csdnimg.cn/blog_migrate/aebd49c8a32b0b8ec9ec4d50f2d565ec.jpeg)
注,此处做几点说明:
- 上面之所以换函数了,是因为先前的稍微有点特殊,不便于更直观的理解梯度下降;
- 之所以说梯度的方向为
没有单位化是因为后面还会在其前面乘以系数
,所以可以不用;
4 跳向谷底实例
我们通过代码来完成上述的所有过程:
def cost_function(w1, w2):
J = w1 ** 2 + w2 ** 2 + 2 * w2 + 5
return J
def compute_gradient(w1, w2):
return [2 * w1, 2 * w2 + 2]
def gradient_descent():
w1, w2 = -2, 3
jump_points = [[w1, w2]]
costs = [cost_function(w1, w2)]
step = 0.1
print("P:({},{})".format(w1, w2), end=' ')
for i in range(20):
gradients = compute_gradient(w1, w2)
w1 = w1 - step * gradients[0]
w2 = w2 - step * gradients[1]
jump_points.append([w1, w2])
costs.append(cost_function(w1, w2))
print("P{}:({},{})".format(i + 1,
round(w1, 3), round(w2, 3)), end=' ')
return jump_points, costs
if __name__ == '__main__':
jump_points, costs = gradient_descent()
plot_surface_and_jump_points(jump_points, costs)
# 部分结果:P:(-2,3) P1:(-1.6,2.2) P2:(-1.28,1.56).....P20:(-0.023,-0.954)
![c92e70eeaf5e479bf41daadcc5791740.png](https://i-blog.csdnimg.cn/blog_migrate/1f6d24e467b6be6a0c124aa23e3b7e8a.jpeg)
在上面通过python编码展示了跳向谷底时每一次的落脚点,且谷底的位置就在(-0.023,-0.95 4)附近。由于篇幅有限完成代码请参考示例代码[3]。在完成线性回归模型的推导后,我们再来完成手动求解模型的示例。
5 总结
上面笔者通过一个跳跃的例子详细给大家介绍了什么是梯度,为什么要沿着梯度的反方向跳跃;以及通过图示导出了梯度下降的更新公式:
在这里笔者又写了一遍是希望大家脑子里一定要记住这个公式,以及它的由来。因为它同时也是求解神经网络的主要工具,也是目前的唯一工具。同时,可以看出,通过梯度下降算法来求解模型参数需要完成的一个核心就是计算参数的梯度。最后,虽然公式介绍完了,但是对于公式中的步长
若有任何疑问,请发邮件至moon-hotel@hotmail.com并附上文章链接,青山不改,绿水长流,月来客栈见!
最后,附上一段梯度下降的视频Demo(温馨提示:视频有声音)[4]
![4c021f3f0eda0500fc1537e42b8d2709.png](https://i-blog.csdnimg.cn/blog_migrate/d593dbb102426e91f4c6990bc11ddd9f.png)
引用
- [1] 方向导数:https://blog.csdn.net/The_lastest/article/details/77898799
- [2] 线性回归:https://nulls.blog.csdn.net/article/details/82556307
- [3] 示例代码: https://github.com/moon-hotel/MachineLearningWithMe
- [4] 视频地址:https://www.youtube.com/watch?v=1_HBTJyWgNA&feature=youtu.be