梯度下降算法,它主要的实现功能,是一个优化算法,通过给出的实例来不断逼近某个模型。
例如用下山的例子来解释梯度下降算法,我们要最快速的下山,第一个是找到最陡的坡,第二个是迈出适当的步伐。两者结合才能达到最快的速度。
从山顶下山:1.最陡峭 2.适当步伐。
1.如果不是最陡峭的路,那么我们走缓坡,可能会延长路径长度
2.如果不是适当步伐,走少了,我们需要多迈步,走多了,我们需要重新规划路径
如何找到最陡峭的路,利用梯度。
什么是梯度:
函数式子求导,得出的结果,就是梯度,也是变化率。
多元函数时,对每一个变量,分别求导。
来看梯度的百度百科解释:
其实很简单,具备大学高数的基础知识就能理解,即多元微分。
百度百科解释的很明确,这里不多赘述了。
所以说,最陡峭的地方,就是梯度所指方向,当然,在这里指的是其反方向。因为我们要下山,而不是上山。我们按照梯度所指方向,就能够最快速到达最低点。
上述已经基本描述清楚梯度下降讲的是个什么东西,下面通过标准的数学方式来解释:
第一个参数代表下一步的位置
第二个参数代表当前位置
因为是反方向,所以是负号
a代表步长,每迈出一步的距离,如上文所说,不能太大也不能太小
代表梯度
实例测试:
有函数:
其微分为:
起点:
步长设置为 0.1
根据梯度下降公式,我们计算:
下面的各个值为:
此时的值足够小,可以被认为到达山脚下。这个模型只是无限逼近,不会达到最后的最小值0.
同理二元函数也可以达到。
应用场景:
给定许多数据,例如许多坐标,来拟合成一条线性的直线。
应用场景:
感知机(perceptron)为二类分类的线性分类模型。 输入为实例的特征向量,输出为实例的类别, 取+1 和 -1 二值。
什么是感知机:对于神经网络模型来说,如果不采用激活函数,而用线性进行处理,无论中间怎么处理,最后得到的结果还是线性的结果。如果加入激活函数,就可以被用于拟合各种非线性模型中去。
下面这个实例,给出了很多的点,然后根据梯度下降算法来求出拟合的直线。
用代码进行运算:
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 27 15:11:52 2018
@author: zlee
"""
import matplotlib.pyplot as plt
from pylab import plot
import numpy as np
m = 20
X0 = np.ones((m, 1)) #组成一个数组为【i,1】的坐标集合
X1 = np.arange(1, m+1).reshape(m, 1) #arrange根据生成的start与end生成一个ndarray数组,reshape给数组一个新的形状而不改变其数据
X = np.hstack((X0, X1)) # 堆栈数组水平顺序(列)
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):
diff = np.dot(X, theta) - y
return (1./2*m) * np.dot(np.transpose(diff), diff)
'''
代价函数梯度
'''
def gradient_function(theta, X, y):
diff = np.dot(X, theta) - y
return (1./m) * np.dot(np.transpose(X), diff)
'''
梯度下降迭代计算
'''
def gradient_descent(X, y, alpha):
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
#折线图绘制函数
plot(y,'r*')
plt.show()
optimal = gradient_descent(X, y, alpha)
print('optimal:', optimal)
print('error function:', error_function(optimal, X, y)[0,0])
本来的点集合图像为: