损失函数表示的时模型有多大程度上与数据不拟合,神经网络学习的过程就是让模型与数据拟合,并且尽可能使模型具有泛化能力。神经网络的损失函数往往很复杂,参数有很多,我们不知道参数为何值时算是函数最小(或者局部最小),我们转变一下参数更新的问题,参数的更新实际上就是在求解损失函数的最小值。根据微积分的知识可以知道,函数的梯度指向的额方向使函数的极小值,所以参数的更新是依靠计算损失函数的梯度来进行的(梯度下降)。
关于梯度的求解,主要有两种方法:
- 数值微分(导数的定义,实际应用时速度很慢)
- 误差反向传播
梯度下降
梯度下降的主要思想:
- 初始化参数
- 不断的改变参数的 值,不断减少 损失函数$L$直至达到最小值(一般为局部最小,很难达到全局最小)。
把梯度下降的过程想象成下山,每次向下走一段距离,最终会走到一个局部(全局)最低点。从图中可以看出,全局最低点为左侧箭头标注的地方,实际轨迹达到的是一个局部最低点,我们在训练模型时的函数往往很复杂,很难达到全局最优(复杂函数中,梯度往往指向的都不是全局最小值,但即使是局部最优,模型的性能也足够优秀)。
梯度下降数的学表达:
$$ W = W - \eta \frac{\\partial L}{\partial W} $$
其中$W$为参数矩阵,$\eta$为学习率,$\frac{\partial f}{\partial W}$为算式函数对参数的偏导数。
假设参数有$x_0$、$x_1$两个,则表达式为:
$$ x_0 = x_0 - \eta\frac{\partial L}{\partial x_0} $$
$$x_1 = x_1 - \eta\frac{\partial L}{\partial x_1}$$
还是以下山为例,学习率就相当于时下山时迈的步子的大小,步子大了,下山速度就会快,步子小了,下山速度就慢。同理,学习率大,参数更新步伐就大,模型收敛的会快,学习率小,收敛速度就慢,但学习率不是太大或者太小都不好:
学习率太大,会导致损失函数发散,导致很难收敛。
学习率太小,会导致收敛速度很慢,可能训练结束了,损失函数的值还很大。
如下图,上方的为学习率刚刚好,不是很大,也不是很小,下方的图是学习率太大,导致在接近最低点的地方由于步幅太大,跨刀了另一边,如此反复,无法达到最低点。我们把神经网络的权重、偏置等称为参数,这些是神经网络自动调整的;像学习率这种人为指定的参数,称为超参数,除了学习率(learning rate),超参数还有批大小(batch size等)等。
使用数值微分进行梯度下降
数值微分
导数的定义:
$$ \frac{df(x)}{dx} = \lim_{h \to 0}\frac{f(x+h)-f(x)}{h}$$
实际应用中,$h$如果取得太小(如$1e-50$),可能会发生舍入误差(因为省略小数的精细部分数值而造成最终结果的误差)。
除了舍入误差,数值微分本身也有误差,为了减小误差,我们计算函数$f(x)$在邻域$(x-h, x+h)$上的差分(中心差分),即:
$$ \frac{df(x)}{dx} = \lim_{h \to 0}\frac{f(x+h)-f(x-h)}{2h} $$
这样,我们就可以求出损失函数的梯度。
代码实现:
def numerical_gradient(f, x):
h = 1e-4 # 0.0001
grad = np.zeros_like(x) # 用来保存求得的梯度
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
idx = it.multi_index
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 # 还原值
it.iternext()
return grad
# 进行测试
data = np.array([3.0, 4.0])
def func(X):
return X[0]**2 + X[1]**2
print('在点(3, 4)处的值:', func(data))
print('在点(3, 4)处的梯度:', numerical_gradient(func, data))
函数numerical_gradient的参数为一个函数 $f(损失函数)$,和数据 $x$。
假设损失函数为代码中的函数func($L=x_0^2+x_1^2$),计算函数在点(3.0, 4.0)处的函数值和梯度。
运行结果:
在点(3, 4)处的值: 25.0
在点(3, 4)处的梯度: [6. 8.]
Comments | NOTHING