梯度下降学习算法与pthon代码实现

来源:互联网 发布:手机淘宝达人登录入口 编辑:程序博客网 时间:2024/06/01 07:12

梯度下降学习算法的基本原理
一,梯度下降学习算法的公式推导
关于梯度学习算法的公式推导,吴恩达教授的斯坦福公开课(可以在网易公开课上获取视频资源)讲得比较清楚,借用该推导过程:
假设做一个房屋价值的评估系统,影响房屋价格的因素有很多,比如说面积、房间的数量(几室几厅)、地段、朝向等等,这些影响房屋价值的变量被称为特征(feature),特征在机器学习中是一个很重要的概念,有很多的论文专门探讨这个东西。为了简单,假设我们的房屋只受面积影响。
假设有一个房屋销售的数据如下:

面积(m^2)  销售价钱(万元)123            250150            32087              160102            220

以面积为x轴,价格为y轴作图,可以得到散点图,当然我们可以根据高中学习的方法去手动求解拟合回归直线的方程,从而获得房屋价格与面积的关系公式,但是如果用机器学习算法来自动拟合回归方程该如何实现呢?
拟合曲线

我们把上面的这四个数据称为训练集,数据集的数目为n

机器学习

首先猜测模型公式为一般公式

计算拟合回归曲线的常量参数,可以计算训练集的各个点到该拟合曲线的方差,当方差最小的时候,我们可以认为该回归曲线正是所求的曲线方程,根据方差和公式,可以有:

方差和

公式中θ表示公式常量,m表示训练集的第m个数据,1/2是为了待会计算方便加上去的。如何调整θ以使得J(θ)取得最小值有很多方法,其中有最小二乘法(min square),这里使用梯度下降法。

梯度下降法是按下面的流程进行的:

1)首先对θ赋值,这个值可以是随机的,也可以让θ是一个全零的向量。

2)改变θ的值,使得J(θ)按梯度下降的方向进行减少。

对该函数求导

求导

迭代赋值,式子中α是人为输入的参数,用来控制收敛步伐大小,可以通过判断a(h(x)-y)的值(比如当a(h(x) - y)x <0.001》来让式子收敛,从而求出θ的值。

二,python代码实现
运行环境, python3.5,windows

'''一元一次方程函数 y =ax+b 缺陷,不能超过25个样本数据训练样本的方程为y=x+1'''def gradient(list):    result = {}    a = 0    b = 0    direction = 0.2 #下降的梯度    g = 0.01    count = 0    while abs(float(g*direction)) > g/100:        for x,y in list.items():            count += 1            x = float(x)            y = float(y)            direction = (a*x+b-y)            a = a - g * direction * x            b = b - g * direction    result['a'] = a    result['b'] = b    result['counts'] = count    return result'''二元一次方程函数 z = ax+by  该代码所实现的算法有缺陷,不能超过15个样本数据训练样本的函数为z = x + y'''def gradient2(list):    result = {}    a = 0    b = 0    direction = 1 #下降的梯度    g = 0.01    count = 0    while abs(float(g*direction)) > g/100:        for items in list:            count += 1            x = float(items[0])            y = float(items[1])            z = float(items[2])            direction = (a*x+b*y-z)            a = a - g * direction*x            b = b - g * direction*y    result['a'] = a    result['b'] = b    result['count'] = count    return resultlist1 = {1 : 2, 2 : 3, 3 : 4, 4 : 5}list2 = [(1,3,4),(2,5,7),(3,9,12)]a = gradient(list1)b = gradient2(list2)print(a)print(b)

运行结果:

{'a': 1.008908495646052, 'b': 0.9726462684576949, 'counts': 1992}{'a': 0.9450581576040846, 'b': 1.0184250039014437, 'counts': 7269}

在实验过程中,我发现我所写的代码训练的数据集数目有限,训练一元一次函数不能超过25个数据量,训练二元一次函数不能超过15个数据量,一旦超过限定数量,训练出来的参数不准确,当数量超过一定规模,训练出来的参数显示为无穷大或无穷小。我更改了其他同志所写的梯度下降学习代码,如http://blog.csdn.net/programmer_wei/article/details/51941358,将其数据集规模扩大,当扩大到25个数据时,该代码训练的参数也会产生很大的误差,我分析了一下,认为可能有以下原因引起:

(1)随着训练的进行,x值越来越大,为了使函数收敛,a(h(x)-y)(代码中等同于a*x+b-y)的值必须要很小,反复迭代后a的值就越来越小以至于近似无穷小,使得参数计算不准确。

针对训练集数目导致参数计算不准确的问题,有哪位同志可以给出专业的解释吗?不甚感激。

阅读全文
0 0
原创粉丝点击