用一颗小球带你搞定梯度下降

导数与梯度下降算法

什么是导数?

如果你不知道什么是导数,最好先去看3BLUE1BROWN大神的视频吧,这个视频的质量非常高 ,看过以后都说好。
微积分合集 传送门

个人总结:

在这里我希望你能建立起来一种直觉,微积分描述的就是X的一个微小变化量对结果Y的影响。
这句话请你一定要牢牢记住,整个微积分的精髓就是这样了。

怎么求函数的最小值?

利用刚才建立起来的直觉,我们去求函数的最小值。
BTW:学过微积分你应该知道通过二阶导数与一阶导数可以获得极值的解析解。然而,大多数深度学习模型并没有解析解,只能通过优化算法有限次迭代模型参数来尽可能降低损失函数的值。这类解叫作数值解(numerical solution)。
如果你没有学过微积分,就当什么都没有发生。

我们先用https://zh.numberempire.com/graphingcalculator.php 来画出函数图像增加你的直观感觉!

image.png

如果此时把一颗小球放在函数图像的曲线上,想想这颗小球如何滚到最低点呢?

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-5, 5 , 30)
y = (x) ** 2
plt.plot(x, y)
plt.xlabel("X")
plt.ylabel("Y")

plt.show()
y = x^2
def fx():
   """把刚才画图的过程定义成一个函数,便于后面调用"""
    x = np.linspace(-5, 5 , 30)
    y = (x) ** 2
    plt.plot(x, y)
    plt.xlabel("X")
    plt.ylabel("Y")
    

我们先想像一个物理画面,一颗小球沿着函数山谷向下滚动,它在什么时间停止不动?
这里我们思考几个问题:

小球的起点在哪里?
小球每次滚动的距离由什么决定?
小球在什么时候停止?

我们把这三个问题,物理化,想象一下

1 小球的起点我们可以设定为函数上的任意一点,只是这个点离最低距离远近,  
  决定了获得最小值的时间,在深度学习中,我们把它称为“收敛”时间。
2 小球每次滚动的距离由两个因素决定一个是小球的重量,一个是函数的“坡度”,
  很显然在重量一致的情况下,坡度越陡峭,它滚动的距离就越远。
3 小球在最低点停止的时候,用数学表示就是上次移动的距离,和这次移动的距离非常小,
  直到这个距离为0的时候,小球就静止了。

我们把上面的物理描述,换成数学语言,伪码一下就是:

|
设定初始点x = -4 #任意一点 。
设定小球的重量 = 0.1 #在深度学习里面通常称为 \eta (读作"eta " ) 。
函数在某一点上的“坡度”也就是该点的导数"derivate" ,它和"\eta"相乘决定了小球本次移动的距离 。
小球上次与本次 在y轴上移动的距离如果小于\epsilon (读作"epsilon" )我们就认为它是静止的 。

有了上面的认知,接下来就是一个循环问题了:

whiel  True:    
    求该点的导数  
    x = x - 移动的距离  
    为了画图,我们可以把x和gradient都记录到列表中  
    最后如果当小球在y方向上的移动距离和上次移动的距离小于 epsilon ,就可以结束循环了

实际的代码如下:

def derivate_x(x):
    return 2*x

def fun_x(x):
    return x**2

x = -4
eta = 0.1
epsilon = 1e-5
x_list = [x]
gradient_list=[]
while True:
    gradient = derivate_x(x)
    last_x = x
    x = x - eta*gradient
    x_list.append(x)
    gradient_list.append(gradient)
    if (abs(fun_x(last_x) - fun_x(x)) < epsilon):
        break
x_list

[-4,
 -3.2,
 -2.56,
 -2.048,
 -1.6384,
 -1.31072,
 -1.0485760000000002,
 -0.8388608000000002,
 -0.6710886400000001,
 -0.5368709120000001,
 -0.4294967296000001,
 -0.3435973836800001,
 -0.27487790694400005,
 -0.21990232555520003,
 -0.17592186044416003,
 -0.140737488355328,
 -0.11258999068426241,
 -0.09007199254740993,
 -0.07205759403792794,
 -0.057646075230342354,
 -0.04611686018427388,
 -0.03689348814741911,
 -0.029514790517935284,
 -0.02361183241434823,
 -0.018889465931478583,
 -0.015111572745182867,
 -0.012089258196146294,
 -0.009671406556917036,
 -0.007737125245533628,
 -0.006189700196426903,
 -0.004951760157141522,
 -0.003961408125713218]
gradient_list
[-8,
 -6.4,
 -5.12,
 -4.096,
 -3.2768,
 -2.62144,
 -2.0971520000000003,
 -1.6777216000000004,
 -1.3421772800000003,
 -1.0737418240000003,
 -0.8589934592000003,
 -0.6871947673600002,
 -0.5497558138880001,
 -0.43980465111040007,
 -0.35184372088832006,
 -0.281474976710656,
 -0.22517998136852482,
 -0.18014398509481985,
 -0.14411518807585588,
 -0.11529215046068471,
 -0.09223372036854777,
 -0.07378697629483821,
 -0.05902958103587057,
 -0.04722366482869646,
 -0.037778931862957166,
 -0.030223145490365734,
 -0.024178516392292588,
 -0.01934281311383407,
 -0.015474250491067256,
 -0.012379400392853806,
 -0.009903520314283045]
plt.plot(np.array(x_list),fun_x(np.array(x_list)),color='r',marker='*') #绘制x的轨迹

fx()
plt.show()
梯度1

这里思考一下,
为什么小球在后来每次在x轴上移动的距离原来越短?
因为“坡度”越来越平缓了吗!
平缓的数学意思就是gradient越来越小了。

改变eta与epsilon

x = -4
eta = 0.8
epsilon = 1e-2
x_list = [x]
gradient_list=[]
while True:
    gradient = derivate_x(x)
    last_x = x
    x = x - eta*gradient
    x_list.append(x)
    gradient_list.append(gradient)
    if (abs(fun_x(last_x) - fun_x(x)) < epsilon):
        break

plt.plot(np.array(x_list),fun_x(np.array(x_list)),color='r',marker='*')#绘制x的轨迹
fx()
plt.show()
梯度2 .png
gradient_list
[-8,
 4.800000000000001,
 -2.880000000000001,
 1.7280000000000006,
 -1.0368000000000004,
 0.6220800000000004,
 -0.37324800000000025,
 0.22394880000000017]

我们修改了eta的值,还有epsilon的值,对应图像你能想明白为什么这个样子吗?
更改了eta的值,相当于小球在开始有一个很大的重力加速度,一下子滚到了对面的山坡。这个很符合物理直觉。
然后小球继续向下,注意此时的小球在对面的山坡,所以你的导数是一个正数。还记得导数代表的就是斜率吗?如果忘记了也没有关系。

物理意义就是如果斜率为正,代表x变大,y也变大,那x应该往小的方向走,也就是x-eta*gradient。那如果导数为负,就意味着
x变大,y就会变小,所以x应该往大的方向走,x - eta * gradient 此时gradient是一个负数,所以x会变大。

这里大家可以自己去测试一下,如果eta很大,epsilon很小会发生什么?

梯度下降算法

接下来我们放到一个更复杂的环境中,来讨论这个求函数最小值的问题,现在我们把物理场景换到一个小人下山。
图片来源https://www.analyticsvidhya.com/blog/2017/03/introduction-to-gradient-descent-algorithm-along-its-variants/

小人下山

说复杂,是因为此时下山的路有多条,我们稍微简化一下,假设只有x,y两个方向下山的路,你该怎么选择呢?
这相当于你建立了一个x,y,z的坐标系,z代表是海拔高度,z的变化受,x,y影响,也就是当你往x方向走极小距离,会有对z有一个影响,
对照刚才的讲解,你知道如果只有x 你可以表示为x - eta * x_gradient 。同理z也收y的影响,y方向的移动可以表示为y - eta * y_gradient。
那z就是因变量,x,y就是自变量,用函数表示就是z=f(x, y)。

在下图中x被替换成\theta_0,y被替换成\theta_1, z被表示成J(\theta_0, \theta_1)

函数示意图

既然函数中有了两个方向,那此时的\theta_0_gradient就要换个名字叫做\theta_0针对J(\theta_0, \theta_1)的偏导数, 此时的偏导数的物理意义,就是必须指向山的最低点方向,也就是海拔最低的方向。
同理\theta_1_gradient也要改名字为针对J(\theta_0, \theta_1)的偏导数。
你记住他的物理意义就好。
这种物理上沿着山坡下降最快的方向寻找函数最小值的办法,就叫做梯度下降算法。
梯度的定义就是在物理上指向下降速度最快的方向的向量。

它由 \partial \theta_0\partial \theta_1偏导组成。
\theta_0 = \theta_0 - \eta * \cfrac {\partial J(\theta_0, \theta_1) } {{\partial \theta_0}}
\theta_1 = \theta_0 -\eta* \cfrac {\partial J(\theta_0, \theta_1) } {{\partial \theta_1}}

所以就这样,你现在问自己一个问题,在代表多维空间的函数上如何找到最低点呢?
物理上可以通过放一个小球来实现:
1 小球该往那个方向滚,由什么来决定呢?
2 小球在什么时候停下来?停下来的条件是什么?
3 好吧,知道上面两个就够了!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • 前言 梯度下降算法现在变的越来越流行,但是对于使用者来说,它的优化过程变的越来越黑盒。本文我们介绍下不通梯度下降算...
    wendaJ阅读 1,522评论 0 1
  • 改进神经网络的学习方法(下) 权重初始化 创建了神经网络后,我们需要进行权重和偏差的初始化。到现在,我们一直是根据...
    nightwish夜愿阅读 1,842评论 0 0
  • 数学符号及读法大全 常用数学输入符号: ≈ ≡ ≠ = ≤≥ < > ≮ ≯ ∷ ± + - × ÷ / ∫ ∮ ...
    代瑶阅读 13,761评论 0 1
  • 转载自:CSDN极客头条作者:李理 目前就职于环信,即时通讯云平台和全媒体智能客服平台,在环信从事智能客服和智能机...
    wang_shaochun阅读 1,153评论 0 2
  • 【Day10课后实践】这是2018年8月14日“崔律·100天精力和时间管理训练营”第2.2讲的课后实践。<实践事...
    孔雀勇士阅读 141评论 0 0