吴恩达机器学习_3

梯度下降

梯度下降法是一种非常常见的最小化代价函数J的方法。
同时,它也常常用于更广泛的机器学习应用中,也就是说梯度下降法可以最小化更一般的函数

下面简述如何使用梯度下降最小化代价函数J
前面已经提到,梯度下降法可以用来解决更有一般的函数,例如J(θ_0,θ_1……θ_n),但为了简化,我们讨论两个值的。

直观理解

在这里插入图片描述
我们的目的是得到最小的J。
为此,
第一步, 给θ_1,θ_0一个初值,一般来说都是0。当然,也可以是不同的其他值,此处的初值会对最终的结果产生影响,后面会讲。
第二步,不断使θ_1,θ_0改变,直到到达局部最小值。
在这里插入图片描述
形象地来说,就是假如你在图中红色的山上,首先你环顾360°移动一点点,找到下山最快的方向,然后移动;这样就会来到一个新的点,再次重复刚才的动作,直到收敛到局部最低点。
就像图中用黑色笔标出的路径一样。
在这里插入图片描述
但是,如果你的初值点稍稍向右偏一点,如上图,显然就会到达不同的局部最优,得到完全不同的结果。

数学含义

直观的理解过后,下面让我们来看看梯度下降法的数学含义。
在这里插入图片描述
我们要做的就是无限使用上面的公式更新θ_j的值,直到收敛。

公式中有很多值得注意的地方。
“:=”赋值符号的意思,学过编程的应该都懂,就是把右边的值赋给左边的变量。
“α”是被称为学习速率的数字,是用来控制梯度下降时,我们更新数据的幅度。α很大的话,我们下山的步子也就很大;反之,步子很小。它总是正数。

后面的一串式子是导数式,为了更好的理解它,我们先来以一个变量的问题为例。
在这里插入图片描述
假设初值就是图中标有θ_1的点,可以看出此时的导数式(斜率)是正的,也就是说,θ会向左减少。直到导数为零的时候,进入收敛。
在这里插入图片描述
而对于现在这种情况,θ_1会减去一个负值,也就是加上一个值,向右边的最低点移动。
在这里插入图片描述

如上图,并且,因为在进行梯度下降时,导数的值越来越小,也就是说你移动的步伐越来越小,直到导数为零不能移动。

从上面两种情况来看,梯度下降法可以到达起始点附近的一个极小点,因为极小点的导数值为0,在极小点处就会陷入递归
可以想到的,如果把α前面的符号改为“+”,就可以到达极大值点。(个人突发奇想)

同步更新

在这里插入图片描述
如上图,使用梯度下降时,需要对θ_1,θ_0同步更新。同样是编程逻辑问题
如果不按照同步更新的方法,例如下图。
在这里插入图片描述
θ_0先更新,就会导致下一步式子中的导数式值发生改变,最终错误。
上述关于同步更新的问题,学过编程的应该都比较熟悉,就不多赘述了。

关于α

如果α过小
在这里插入图片描述
显然,这会导致我们得到结果的速度非常慢。

如果α的值过大
在这里插入图片描述
显然,这会导致我们的结果大幅度的跳跃,直到你发现得到的结果离目标越来越远。

python代码演示(简易)

def _numerical_gradient_1d(f, x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)
    
    for idx in range(x.size):
        tmp_val = x[idx]
        x[idx] = float(tmp_val) + h
        fxh1 = f(x) # f(x+h)
        
        x[idx] = tmp_val - h 
        fxh2 = f(x) # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)
        
        x[idx] = tmp_val # 还原值
        
    return grad

def numerical_gradient_2d(f, X):
    if X.ndim == 1: # .ndim会返回数组的维数
        return _numerical_gradient_1d(f, X)
    else:
        grad = np.zeros_like(X)
        
        for idx, x in enumerate(X): # enumerate()可以同时列出索引对象的序号和索引对象,idx对应的是序号,x对应的是对象本身
            grad[idx] = _numerical_gradient_1d(f, x)
        
        return grad
    # _numercial_gradient_1对应的是一维数组,dnumercial_gradient_2d对应的是二维数组,采用的
    # 主要思想就是把二维数组的每一行看作一个一维数组使用_numercial_gradient_1处理,最终达到处理二维数组的目的


def gradient_descent(function, init_x, lr = 0.01, step_num = 100) : # 一个简单的梯度下降的算法
	# lr:learning rate 学习率
    x = init_x
    
    for i in range(step_num) :
        grad = numerical_gradient_2d(function, x)
        x -= lr * grad
    
    return x

线性回归中的梯度下降

在这里插入图片描述
如上图,我们要做的就是把左边的方法应用到右边的线性回归问题中。
为此,我们要求解偏导数式。
emmmmmm,这里的偏导数,我才刚刚大一,完全不记得自己学过,不过看弹幕上有些人高中就已经学过了。去百度了一下,大致的来说就是,一个函数有多个自变量,在求导数时针对一个自变量求导,其余都看作常数的求导方法。
在这里插入图片描述
看不懂也没关系(don’t worry about it),记住就行。不过有点高数基础的应该都能看懂。
化简结果是这个。
在这里插入图片描述
这里就可以看出来为什么之前的代价函数系数是1/2m了,目的应该是化简到这一步更加容易理解。
在这里插入图片描述
在线性回归问题中,得到的代价函数一般都是如上图的凸函数。它并没有局部最优解,只有一个全局最优
在这里插入图片描述
我们刚刚学习的算法也被叫做Batch梯度下降法,意味着每一次梯度下降我们都遍历了整个数据集的样本。又是也会有不是Batch梯度下降法的方法,它们没有遍历全部的样本,而是关注于小子集。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值