梯度下降法

来源:互联网 发布:淘客查询软件 编辑:程序博客网 时间:2024/06/08 08:12

首先我们需要了解得分函数和损失函数,在上一篇文章中有介绍;而我们的核心目标是找到最适合的参数w,使得损失函数取值最小化。这就是最优化的过程。

损失函数往往定义在非常高维的空间,一般,我们可以把高维投射到一个向量/方向(1维)或者一个面(2维)上,从而直观地观察到一些变化,这也称为曲线救国。


一、凸优化:

SVM损失函数是一个凸函数;凸函数的正系数加和仍然是凸函数;但扩充到神经网络之后,损失函数将变成一个非凸函数。凸函数的局部最优点就是全局最优点.

二、最优点:

策略1:随机搜寻(不太实用)。最直接粗暴的方法,尽量多去试参数,然后从里面选择那个让损失函数最小的,作为最后的w。

策略2:随机局部搜索。在现有参数的基础上,搜寻周边临近的参数,有没有比现在参数更好的w,然后用新的w替代原来的w,不断迭代。

策略3:顺着梯度下滑。找到最陡的方向,迈一小步,然后再找当前位置最陡的方向,再迈一小步......不过这个策略有一个初始值敏感的情况;如下图对比。

三、计算梯度:

有两个常用的梯度计算的方法:

(1)数值梯度(numerical gradient):慢一些但是简单一些;

对每一个维度,都在原始值上加上一个很小的h,然后计算这个维度/方向上的骗到,最后组在一起得到grad

迭代的步长h设得太小时,时间耗不起;步长太大时,容易跳过最优点甚至永远跳不到最优点。

效率问题:这个计算方法的复杂度,基本上是和我们的参数个数成线性关系的。


(2)解析梯度(analytic gradient):速度快但是更容易出错,解析梯度理论上可能能很快解出来,但是实际上很有可能出错。

而如果先计算解析梯度和数值梯度,然后比对结果和校正,然后就可以大胆地解析法计算了,这个过程叫梯度检查/检测。



四、梯度下降:

以下这个简单的循环就是很多神经网络的核心:

while True:      weights_grad = evaluate_gradient(loss_fun,data,weights)#计算梯度      weights += -step_size * weight_grad  #梯度下降更新参数

Mini-batch:对整个训练集数据集的样本都算一遍损失函数,以完成参数迭代是一件非常耗时的事,一般,我们通常采用替代方法,采样出一个子集在其上计算梯度。

while True:      data_batch = sample_training_data(data,256)#抽样256个样本作为一个batch      weights_grad = evaluate_gradient(loss_fun,data_batch,weights)#计算梯度      weights += -step_size * weight_grad  #梯度下降更新参数

一般我们使用的是Mini-batch SGD:

不断循环下列步骤:

(1)采样一个batch数据(可以做镜像对称)

(2)前向计算得到损失loss

(3)反向传播计算梯度(一个batch上)

(4)用这部分梯度迭代更新权重参数