梯度下降算法的理解


梯度下降算法(Gradient Descent)是机器学习中最常用的算法之一,从网上看到的关于梯度下降算法的介绍感觉都过于理论化(有好多抽象的数学符号和公式),这篇文章从最简单两个函数问题入手,轻松愉快的理解梯度下降算法,完整代码请见github


基础概述

数学基础:高数会求偏导,知道均方误差损失函数(至少要知道损失函数这个词)

python版本anaconda 4.3.1:Anaconda可以认为是一个python的发行版本,提供了版本管理和包管理的功能,并且已经预装了许多第三方软件包:如pip、zmq、numpy、pandas等。


两个例子理解梯度下降

梯度下降算法的本质就是求导,当输入变量x多于1个时,就是求偏导

导数的几何意义是函数曲线在这一点上的切线斜率(也就是说导数在这一点绝对值越大,曲线就越陡,也可以解释为y对x的变化率的描述或表达);偏导数的几何意义是函数对某个变量的变化率的描述或表达(如果是二元函数z = x2 + y2,z对x的偏导数解释为z在x方向上的变化率)

数学理论部分这么多就足够了,如果想要复习,参考:



例子1:求解y = (x-3) * (x-3) + 3的最小值

先求y对x的导数:

y' = 2 * (x-3)

然后设定两个超参:

步长rate = 0.001

循环次数max_times = 10000

我们的任务是要找到一个x的值,使得y最小,很显然是当x=3时,y是最小的,下面我们用梯度下降算法来完成这个任务(注意,代码是不会像人一样用脑子计算函数的),算法很好解释:让x每次都沿着负梯度方向移动rate*导数的步长,循环max_times次后停止

import numpy as np

x = 2

rate = 0.001

max_times = 10000

def target_func(x):

    """这段函数就是y = (x-3) * (x-3) +3

    """

    y = np.square(x - 3) + 3

    return y

while count < max_times:

    x = x - rate * 2*(x-3)   

    """x的初始值为2(随便写),2*(x-3)是导数y',当x=2时y' = -2,那么就是x要向着-y'的方向移动0.001倍。新的x = 2 - 0.001 * -2 = 2 + 0.002 = 2.002。很好,离我们的目标值3近了一些(其实程序不知道3是最后要得到的目标值,程序也永远不会知道)。第二次循环后x = 2.002 - 0.001 * 2 * (2.002 -3) = 2.002 + 0.0019960000000000004 = 2.003996,离我们的目标值又近了一些。这里0.0019960000000000004只会保留17位的有效数字~

    """

    print (count, "training-----current x is: ",x)

    count = count + 1

print (x, target_func(x))  #最后看个结果

整个梯度下降算法的过程就是x不断的沿着负梯度方向一步一步一步的移动,直到循环完成(循环结束的标识不一定是次数,也可以设计为两次y之间的变化小于某个值,但如果这个值设定不恰当时,就可能造成抖动或提前结束循环)

例子2:根据训练集数据预测目标函数y = 2 * (x1) + (x2) + 3

首先,要处理的是最基本的线性回归问题,目标函数y = 2 * x1 + x2 +3是我们不知道的(计算机是真的不知道这个函数啊),只有一些待训练的数据(数据来源于网络):

x_train = np.array([    [1, 2],    [2, 1],    [2, 3],    [3, 5],    [1, 3],    [4, 2],    [7, 3],    [4, 5],    [11, 3],    [8, 7]    ])

y_train = np.array([7, 8, 10, 14, 8, 13, 20, 16, 28, 26]

我们的任务是找到一个函数去描述上边x1,x2和y之间的对应关系。根据训练数据,假设y和x之间的关系是y = ax1 + bx2 + c(最基本的线性回归模型函数,a,b,c是权重)

这里,就要引入损失函数了,损失函数是评价一个模型好坏程度的函数,通俗的讲就是把当前的权重值带入到模型后得到的预测结果和真实结果之间误差的一个评分函数,训练模型的过程,就是通过算法使得损失函数不断减小。

损失函数我们选用均方误差函数,见下图

引入损失函数后,我们的任务就变成了找到一组对应的权重值,使损失函数最小,是不是已经很像求解y = (x-3)*(x-3) +3最小值的问题了:)

下面我们用梯度下降算法来完成这个任务

import numpy as np

a = np.random.normal()  # 初始化3个权重

b = np.random.normal()

c = np.random.normal()

rate = 0.001  #步长

max_times = 10000  # 循环次数

# 训练集

x_train = np.array([    [1, 2],    [2, 1],    [2, 3],    [3, 5],    [1, 3],    [4, 2],    [7, 3],    [4, 5],    [11, 3],    [8, 7]    ])

y_train = np.array([7, 8, 10, 14, 8, 13, 20, 16, 28, 26])

# 待测试数据

x_test  = np.array([    [1, 4],    [2, 2],    [2, 5],    [5, 3],    [1, 5],    [4, 1]    ])

# 目标函数

def h(x):

    return a*x[0]+b*x[1]+c

for i in range(max_times):

    for x, y in zip(x_train, y_train):

        a = a - rate * (h(x)-y) * x[0]  #代码后边来解释这个

        b = b - rate * (h(x)-y) * x[1]

        c = c - rate * (h(x)-y)

print("a =", a)

print("b =", b)

print("c =", c)

result = [h(xi) for xi in x_train]

print(result)

result = [h(xi) for xi in x_test]

print(result)

下面单独注释一下这行代码

a = a - rate * (h(x)-y) * x[0]

要理解这行代码,就要对损失函数J求偏导了,J对参数a求偏导,见下图(x1就是代码中的x[0],文字表述上用x1,x2看着比较方便),同理,再求J对参数b的偏导,再求J对c的偏导。然后就是a、b、c不断的沿着各自的负梯度方向一步一步一步的移动,直到循环完成。

到此就写完了,不过计算出了y = 2x1 + x2  + 3后,这个东西有啥用呢?

假设x1是房屋面积,x2是开发商的成本,y是房屋价格,那么这个模型就勉强算个房价预测模型了。


github地址

https://github.com/dsgdtc/gradient_descent


结束语

最后给出机器学习求解问题的一般过程,会一一对应到例子2中:

1、数据预处理(给x_train和y_train赋值,实际生产中,拿到的数据并不规范,需要做整理)

2、设计假设函数,也可以叫假设空间(我们认定为线性回归问题,设计了目标函数)

3、设计损失函数(均方误差函数)

4、找算法(随即梯度下降,不同算法适用于不同问题,可能要凭经验或者看论文做选择)

5、根据算法进行训练,观察训练过程(栗子2中的循环,因为示例很简单,并不需要进行参数调节,所以这步基本算是跳过了)

6、用模型做预测(就是预测x_test)

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

推荐阅读更多精彩内容