梯度下降算法原理以及其实现

摘要

本文将以通俗易懂的方式介绍梯度下降算法的原理,以及文章的最后会去简要实现梯度下降算法(python代码实现)

基本思想

首先,我们需要了解梯度下降算法的原理,这里我举一个简单的例子:
有一个农夫在山上砍柴,天色将晚,农夫准备从山顶走到山底的家,由于天气原因,可见度很低,他每走一步只能看到很短的一段距离,这里我们想一下,这位农夫怎样才能以最快的时间走到家,这里这位农夫就可以使用梯度下降算法了,答案是他每一步都去走自己附近最陡峭的地方。好,问题解决了,我们继续,那么假设这位农夫具有判断最陡峭方向的能力,那么问题又来了,这位农夫每次沿着这个最陡峭的方向走多大的步子呢?如果步子很大就会错过家门,然而如果步子很小,就很有可能在很短的时间里到不了家,所以每一步的大小也是一个至关重要的问题。
蓝色的点表示农夫的家,红色的点代表农夫
好了,故事讲完了,这里我想说的是,每一次走最陡峭的地方就是梯度下降算法的原理,而每一步的大小又是梯度学习算法中很重要的学习率参数问题,相信读到这里,你的脑子中会记住一些概念了,接下来我们首先利用数学的角度去解释梯度下降算法,可能有些枯燥,但一定坚持读下去。

梯度下降算法的数学原理解释

x 1 = x 0 − α ∗ δ y ( x ) x1= x0 - \alpha * \delta y(x) x1=x0αδy(x)
其中上述公式中的参数分别表示为:
x1:next position 下一步的位置
x0:current position 当前所处的位置
α \alpha α:every step 每一步的步长(也就是上文中的学习率 不能太大,也不能太小)
δ \delta δy(x): direction of the fastest increase 梯度也就是最陡峭位置的方向
这里我们简单举一个例子:
首先我们举一个单变量的函数: y ( x ) = x 2 y(x) = x^2 y(x)=x2 δ ( y ( x ) ) = 2 ∗ x \delta(y(x)) = 2 *x δ(y(x))=2x
我们定初始位置x0 = 1 步长(学习率) α = 0.4 \alpha=0.4 α=0.4
则根据公式 x 1 = x 0 − α ∗ δ y ( x ) x1= x0 - \alpha * \delta y(x) x1=x0αδy(x)有:
x1 = 1
x2 = 0.04
x3= 0.008
x4 = 0,.0016
如图,经过四次的运算,也就是走了四步,基本就抵达了函数的最低点,也就是山底
在这里插入图片描述接下来,我们尝试一个多变量的例子:
z ( x , y ) = x 2 + y 2 z(x,y) = x^2 + y^2 z(x,y)=x2+y2
现在要通过梯度下降法计算这个函数的最小值。我们通过观察就能发现最小值其实就是 (0,0)点。但是接下来,我们会从梯度下降算法开始一步步计算到这个最小值!
我们假设初始的起点为(x,y)=(1,3) 初始的学习率为 α = 0.1 \alpha = 0.1 α=0.1 δ ( z ) = &lt; 2 x , 2 y &gt; \delta(z) = &lt;2x,2y&gt; δ(z)=<2x,2y>
然后进行多次迭代:
guocheng

最后我们尝试用python进行梯度下降算法的实现

场景是一个简单的线性回归的例子,现假设我们有一系列的点,如下图所示:
过程
首先,我们定义一个代价函数,在此我们采用均方误差函数:
在这里插入图片描述此公式中
m是数据集中点的个数
½是一个常量,这样是为了在求梯度的时候,二次方乘下来就和这里的½抵消了,自然就没有多余的常数系数,方便后续的计算,同时对结果不会有影响
y 是数据集中每个点的真实y坐标的值
h 是我们的预测函数,根据每一个输入x,根据Θ 计算得到预测的y值,即在这里插入图片描述我们可以根据代价函数看到,代价函数中的变量有两个,所以是一个多变量的梯度下降问题,求解出代价函数的梯度,也就是分别对两个变量进行微分
在这里插入图片描述
明确了代价函数和梯度,以及预测的函数形式。我们就可以开始编写代码了。

import numpy as np

# Size of the points dataset.
m = 20

# Points x-coordinate and dummy value (x0, x1).
X0 = np.ones((m, 1))
X1 = np.arange(1, m+1).reshape(m, 1)
X = np.hstack((X0, X1))

# Points y-coordinate
y = np.array([
    3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12,
    11, 13, 13, 16, 17, 18, 17, 19, 21
]).reshape(m, 1)

# The Learning Rate alpha.
alpha = 0.01

def error_function(theta, X, y):
    '''Error function J definition.'''
    diff = np.dot(X, theta) - y
    return (1./2*m) * np.dot(np.transpose(diff), diff)

def gradient_function(theta, X, y):
    '''Gradient of the function J definition.'''
    diff = np.dot(X, theta) - y
    return (1./m) * np.dot(np.transpose(X), diff)

def gradient_descent(X, y, alpha):
    '''Perform gradient descent.'''
    theta = np.array([1, 1]).reshape(2, 1)
    gradient = gradient_function(theta, X, y)
    while not np.all(np.absolute(gradient) <= 1e-5):
        theta = theta - alpha * gradient
        gradient = gradient_function(theta, X, y)
    return theta

optimal = gradient_descent(X, y, alpha)
print('optimal:', optimal)
print('error function:', error_function(optimal, X, y)[0,0])

结果如下:
在这里插入图片描述
所拟合的直线如下:
在这里插入图片描述相信,读完这篇文章,你对梯度下降就能理解了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值