【学习笔记】反向误差传播之数值微分

所谓数值微分,其实说白了就是求导,求导有直接求导和求偏导,在神经网络中用到的一般都是求偏导,从而得到每一个权值的误差。
这次准备用Python来研究一波数值微分。

直接求导

具体求导公式,学过高数应该知道有一个叫“向前差分”的玩意儿,他的公式长这样:
求导函数
求导函数示意
然而在Python中其实并不好实现,因为在这个定义中,向前差分的步长越小越好,但是在Pyhton中小数点并不会保留那么多。所以在小到一定程度的时候就变成了0。
因此一般用“中心差分”,就是x向前加一个步长,向后减一个步长,于是变成了:
中心差分
其结果和上面那个是一样的,下面我们可以用Python敲一波代码实现看一下。

#求导函数
#向前差分
def forward_diff(f,x,h=1e-4):
    return (f(x+h)-f(x))/h
#中心差分
def diff(f,x,h=1e-4):
    return (f(x+h)-f(x-h))/(2*h)
#定义一个函数:y=x^2
def fun(x):
    return x**2
x = np.arange(0,4,0.01)
f = fun(x)
#函数在(2,4)处的倒数
dy = diff(fun,2)
plt.plot(x,f)
#利用直线的公式画出切线
plt.plot(x,dy*(x-2)+4)
plt.xlabel('x')
plt.ylabel('y')
plt.show()

求导结果

偏导与梯度

上面只是开胃菜,下面才是正题,那就是函数求偏导。这个梯度也是我们在学函数求偏导的时候接触过的一个概念。
如果还有印象,就知道求偏导的时候就是一个函数,比方说下面这个:
函数
在这个公式当中出现了两个自变量,所以上面的求导公式就不太好使了。因为那个公式只适用于一个自变量的情况下。不过也不是完全不能用,那就是,对于一个自变量求导的时候,就把另一个看作常数处理。这个就是我们在学高数时候的求偏导。而梯度就是由偏导数形成的向量,表现形式如下:
梯度
所以梯度是一个向量,他指向的是函数的最低处,也就是最小值。上面的函数有三个个变量,所以有三个坐标轴。因此显示的图像是三维的图像。所以我们可以想象,地面出现凹进去的一块,那么梯度就是指向凹进去的最低处。
图片来源于网络
学过地理都知道等高线的概念,所以上面的图变化成等高线就是这样,梯度就是指向中心的最低点。就好像我们小时候玩玻璃珠,靠近中间的洞口的时候,玻璃珠自然就会滑到那个洞的最低点。
等高线
下面老规矩,还是用Python的代码来看。

def gradient(f,x,h=1e-4):
    #梯度计算
    grad = np.zeros_like(x)
    for idx in range(x.size):
        tmp_val = x[idx]
        x[idx] = tmp_val + h
        fxh1 = f(x)
        x[idx] = tmp_val - h
        fxh2 = f(x)
        grad[idx] = (fxh1-fxh2)/(2*h)
        x[idx] = tmp_val
    return grad

到这里先不要急,我们再学一个机器学习中最经典的算法,那就是梯度下降法,然后我们再来看效果。

梯度下降法

说到梯度下降法这个可就经典了,虽说不是最好的算法,但却是最实用的,也是最简单的,他的存在就是为了找到一个叫做“全局最优解”的东西。不过事与愿违,其实很多时候他会困在“局部最优解”的地方。还是我们玩玻璃珠的例子,玻璃珠在地面滚向洞口的时候,结果刚好路途中还有一个小小的凹洞,于是玻璃珠受重力影响就划进去出不来了,最终是没有达到你想要的那个洞。
这个时候其实就是因为不管是什么洞口,在最低端其实梯度都为0,当梯度为0的时候,就默认以为是到达最优解的地方。
所以具体算法其实很简单。首先我们有一个初始化的坐标,也就是最初玻璃珠的所在地,然后我们求他的梯度值,得到一个指向地面最低处的向量。然后玻璃珠就可以滚过去了(这里绝对不是在骂人)。不过滚过去的时候,肯定不可能一次性滚过去,他存在一个“步长”。就好像我们人走路一样,走向目的地肯定是一步一步的走的,并不能直接飞过去,一步到位。因此我们在这里也设置了一个叫做“学习率”的东西。因此可以得到一次计算更新的值。
更新
下面就是鸡动人心的代码时刻了,我们用Python画一个图,并且记录下每次更新的坐标,然后显示出来。

#最小梯度法函数
def grad_desc(f,init_x,lr=0.01,step=100):
    x = init_x
    x_history = []  #记录历史坐标值
    for i in range(step):
        x_history.append( x.copy() ) #使用numpy的copy函数,而不是直接等于
        grad = gradient(f,x)
        x -= lr*grad
    return x,np.array(x_history)
#定义一个函数y=x1^2+x2^2
def fun1(x):
    return x[0]**2+x[1]**2
​
#初始化的坐标
init_x = np.array([-3.0,4.0])
lr = 0.1  #上面默认是0.01,这里可以重新赋值
step = 20  #默认是100,这里重新赋值
x,x_history = grad_desc(fun1,init_x,lr=lr,step=step)
#绘制一个坐标
plt.plot( [-5, 5], [0,0], '--b')
plt.plot( [0,0], [-5, 5], '--b')
#绘制更新的散点
plt.plot(x_history[:,0], x_history[:,1], 'o')
#限定坐标显示范围
plt.xlim(-3.5, 3.5)
plt.ylim(-4.5, 4.5)
plt.xlabel("X1")
plt.ylabel("X2")
plt.show()

结果
不错,效果拔群。从图像就可以看出来,当坐标离最小值越远,梯度也就越大,所以单次步长更新的数值也就越大;当逐渐靠近最小值的时候,梯度变小了,所以虽然步长不变,但单次更新的值也会变小。
那么学习率的值到底怎么确定呢?学习率的值在0到1之间,小了不行,大了也不行。就比如说我们走路,有步子迈的大的,也有小的。大的缺点就是容易一下子走过头了,而且容易卡住,然后怎么也迈不到那个最小的地方。学习率太小了,步子迈的太多,就很慢。所以当迭代次数不够的时候,你都还没走到目的地。
比如我修改学习率到0.05,看看结果:
lr=0.05
可以看到,这个还没到最小值就迭代完了,不过你可以把迭代次数弄多一点就好了。
再修改学习率到0.3:
lr=0.3
可以看到,前面步子迈的很大,一下子跨了那么多。而后面则是因为梯度值的变化,所以即使学习率依然很大,但是没有跨过头。但这里没有出现的情况不代表神经网络算法更新的时候不会出现跨过头的问题。这个后面再讲。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数值分析是一门研究数值计算方法及其应用的学科。Matlab作为一个强大的数值计算工具,可以帮助我们更好地学习和理解数值分析。下面是一些Matlab数值分析学习笔记,供您参考: 1. 数值计算基础 - Matlab的数值计算基础包括基本的数学函数、变量定义、矩阵运算等。 - 常用的数学函数包括sin、cos、exp、log等。 - 变量定义和赋值可以使用等号“=”,例如a=2。 - 矩阵运算可以使用“*”表示矩阵乘法,使用“\”表示矩阵求解线性方程组。 2. 数值解法 - 数值解法包括数值积分、数值微分、插值法、最小二乘法等。 - Matlab中的数值积分函数包括quad、quadl、quadgk等。 - Matlab中的数值微分函数包括diff、gradient、jacobian等。 - 插值法可以使用interp1函数实现。 - 最小二乘法可以使用polyfit函数实现。 3. 常微分方程(ODE) - 常微分方程是数值分析中的重要内容之一,Matlab提供了ode45、ode23等函数实现常微分方程的数值解法。 - ode45函数是最常用的常微分方程数值解法之一,可以处理刚性和非刚性方程。 4. 偏微分方程(PDE) - 偏微分方程是数值分析中的另一个重要内容,Matlab提供了pdepe、pde23等函数实现偏微分方程的数值解法。 - pdepe函数可以处理二阶线性偏微分方程,pde23函数可以处理一般的偏微分方程。 5. 数值优化 - 数值优化是数值分析中的一个重要分支,Matlab提供了fminsearch、fmincon等函数实现数值优化。 - fminsearch函数可以用于无约束优化问题,fmincon函数可以用于有约束优化问题。 以上是一些Matlab数值分析学习笔记,希望能对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值