随机梯度下降实现

随机梯度下降:

   我们用X1,X2..Xn 去描述feature里面的分量,比如x1=房间的面积,x2=房间的朝向,等等,我们可以做出一个估计函数:

image

    θ在这儿称为参数,在这儿的意思是调整feature中每个分量的影响力,就是到底是房屋的面积更重要还是房屋的地段更重要。为了如果我们令X0 = 1,就可以用向量的方式来表示了:

image

    我们程序也需要一个机制去评估我们θ是否比较好,所以说需要对我们做出的h函数进行评估,一般这个函数称为损失函数(loss function)或者错误函数(error function),描述h函数不好的程度,在下面,我们称这个函数为J函数

    在这儿我们可以做出下面的一个错误函数:

image 

    这个错误估计函数是去对x(i)的估计值与真实值y(i)差的平方和作为错误估计函数,前面乘上的1/2是为了在求导的时候,这个系数就不见了。

    如何调整θ以使得J(θ)取得最小值有很多方法,其中有最小二乘法(min square),是一种完全是数学描述的方法,在stanford机器学习开放课最后的部分会推导最小二乘法的公式的来源,这个来很多的机器学习和数学书上都可以找到,这里就不提最小二乘法,而谈谈梯度下降法。

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

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

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

    为了更清楚,给出下面的图:

image    这是一个表示参数θ与误差函数J(θ)的关系图,红色的部分是表示J(θ)有着比较高的取值,我们需要的是,能够让J(θ)的值尽量的低。也就是深蓝色的部分。θ0,θ1表示θ向量的两个维度。

    在上面提到梯度下降法的第一步是给θ给一个初值,假设随机给的初值是在图上的十字点。

    然后我们将θ按照梯度下降的方向进行调整,就会使得J(θ)往更低的方向进行变化,如图所示,算法的结束将是在θ下降到无法继续下降为止。

image     当然,可能梯度下降的最终点并非是全局最小点,可能是一个局部最小点,可能是下面的情况:

image

   上面这张图就是描述的一个局部最小点,这是我们重新选择了一个初始点得到的,看来我们这个算法将会在很大的程度上被初始点的选择影响而陷入局部最小点  

   下面我将用一个例子描述一下梯度减少的过程,对于我们的函数J(θ)求偏导J:(求导的过程如果不明白,可以温习一下微积分)

  image

    下面是更新的过程,也就是θi会向着梯度最小的方向进行减少。θi表示更新之前的值,-后面的部分表示按梯度方向减少的量,α表示步长,也就是每次按照梯度减少的方向变化多少。

image     一个很重要的地方值得注意的是,梯度是有方向的,对于一个向量θ,每一维分量θi都可以求出一个梯度的方向,我们就可以找到一个整体的方向,在变化的时候,我们就朝着下降最多的方向进行变化就可以达到一个最小点,不管它是局部的还是全局的。

    用更简单的数学语言进行描述步骤2)是这样的:

  image    倒三角形表示梯度,按这种方式来表示,θi就不见了,看看用好向量和矩阵,真的会大大的简化数学的描述啊。

 

#举个随机梯度下降应用在神经网络的例子

 

 

'''
目标:

输入1 经过神经元 输出0

like:
x=0 ==> sigmode(w*x+b)==>0 需要机器学习w,b的优值
'''
weight=0
bias=0
import math



def sigmode(z):
    return 1/(1+math.exp(-z))

#定义损失函数
'''
是用来估量你模型的预测值f(x)与真实值Y的不一致程度,它是一个非负实值函数.
'''

def quadratic_cost(a):
    '''
    二次损伤函数:J(θ))=损伤函数=1/2(预测值-真实值)^2
    (备注:1/2没有意思方便计算,如果损失函数越小那么预测值就越准)
    
    如何调整θ以使得J(θ)取得最小值?
    
    梯度下降法是按下面的流程进行的:
    1)首先对θ赋值,这个值可以是随机的,也可以让θ是一个全零的向量。
    2)改变θ的值,使得J(θ)按梯度下降的方向进行减少。
    
    设立a=sigmode(z),z=wx+b
    实际值为0呀,0就是那个理想值  [经过神经元 输出0]
    那么:J(θ)=1/2(a-0)^2=a^2/2
    '''
    return a*a/2

def quadratic_derivative(a):
    '''
    这个地方的导数要知道:
    sigmode的倒数为
    
    f(sigmode)=sigmode*(1-sigmode)
    
    a=sigmode
    
    sigmode*sigmode=sigmode*导sigmode+导sigmode*sigmode=a*a(1-a)+a(1-a)*a=2a*a*(1-a)
    
    最后再除以2 得到
    '''
    return a*a*(1-a)

def outputValue(weight,bias):
    '''
    神经元输出
    
    神经元输入为1
    '''
    return sigmode(weight*1+bias);

def gradient_descent():
    '''
    梯度下降
    '''
    #学习次数
    umFrames = 300;
    weight = 0.6
    bias = 0.9
    count=0
    
    #学习步长
    eta=0.15
    while True:
        a = outputValue(weight, bias)
        delta = quadratic_derivative(a)
        weight += -eta*delta
        bias += -eta*delta
        count += 1
        if count > umFrames:
            print "w = ",weight
            print "b = ",bias
            print "sigmoid:",a
            break;

gradient_descent()    

 
  

w =  -1.28433217279

 
  

b =  -0.984332172794

 
  

sigmoid: 0.0939556948636

图解:

  ==》》

ref:http://neuralnetworksanddeeplearning.com/chap3.html#the_cross-entropy_cost_function

 

#这儿模拟了使用梯度下降来实现神经元的自主学习 

转载于:https://www.cnblogs.com/similarface/p/6497637.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值