对梯度下降的理解

在神经网络以及很多机器学习模型的训练优化过程中,不可避免的需要用到梯度下降,可以说梯度下降是很多机器学习算法的核心。这篇文章首先介绍了梯度,偏导数等,然后根据一个具体的例子“根据历史数据来预测当前房价”讲解梯度下降及其代码实现,在实例中使用了Mini-Batch梯度下降(Mini-Batch Stochastic Gradient),并解释了其误差迭代曲线的变化趋势和原因。

梯度下降的基本概念

说起求解梯度,也就是求解函数的导数,简单来说,导数就是某个点函数变化率或斜率。例如我们有如下图所示的一个函数 f ( x ) = x 2 ,那么 f ( x ) 在x处的倒数就是在该点时 f ( x ) 的斜率,当x=2时,该点的导数就为2*2=4.
这里写图片描述
其实梯度和导数是完全一样的东西,只是梯度(Gradient)是一个存储偏导数的矢量值函数。所以,梯度是一个向量,它的每个分量都是一个特定变量的偏导数。
现在我们选用一个多变量函数 f ( x , y ) = 2 x 2 + y 2 作为例子, 这里 f ( x , y ) 的梯度是一个矢量,同时包含x和y。下面我们分别计算 f ( x , y ) 的偏导数可以得到:
f x = 4 x
f y = 2 y
梯度为以下矢量:
Δ f ( x , y ) = [ f x , f y ] T
Δ f ( x , y ) = [ 4 x , 2 y ] T
同样的,如果我们有4个变量的函数,我们将得到一个具有4个偏导数的梯度向量,通常,n变量函数具有n维梯度向量。
f ( x 1 , x 2 , x 3 , . . . , x n ) = Δ f = [ x 1 , x 2 , . . . , x n ]

下面我们看一个具体实例加深对梯度下降的理解

预测房价

我们的目标是根据历史数据来预测当前的房价,一般构建一个机器学习模型至少需要3个元素:问题T, 性能指标P和经验E,然后模型会从历史数据中学习一中能够用于数据预测的模式。
这里我们用一个很简单的线性模型来建模,模型从经验E(house 数据集)中学习,然后用于预测数据。
用于实验的数据可以通过以下链接下载:https://wiki.csc.calpoly.edu/datasets/wiki/Houses
该集合中有781个数据记录,8个特征,我们本次只关注两个特征大小和价格。输入特征为大小,价格是我们的目标值。这里性能指标我们选用SSE(平方误差总和).
E r r = 1 2 ( ( W 0 + W 1 X μ ) y μ ) 2
SSE相对于绝对误差的特点是SSE比绝对误差的错误的惩罚更大。

下面用代码来实现,首先我们对数据进行归一化处理,用归一化数据做梯度下降会比其他情况快得多。

import pandas as pd
import numpy as np

housing_data = pd.read_csv("/Users/huoshirui/Desktop/xgboost", sep=",")

Xs = housing_data[['Size']]
Ys = housing_data[['Price']]

max_size = np.max(Xs)
min_size = np.min(Xs)
max_price = np.max(Ys)
min_price = np.max(Ys)

# normalization
Xs = (Xs - min_size) / (max_size - min_size)
Ys = (Ys - min_price) / (max_price - min_price)

下图展示了房屋价格和房屋大小的关系:
这里写图片描述
线性模型就是通过已有的数据来拟合一条直线,最简单的线性方程的表示如下:
f ( x ) = m x + b
其中,m为斜率,b为与y轴的截距,我们的目标就是寻找到合适的m和b使得误差最小。
对于梯度下降来说,我们希望采取与梯度相反的方向。
我们改变这两个值,使得函数值可以沿误差曲面上最陡的方向下降。每次迭代后,这些权重变化将优化我们的模型使得误差更小。
这里写图片描述
如上图所示,我们想尽可能找到最小值,但是可能到局部最小值时训练就停止了,无法到达全局最小值。
但是并不是所有的局部最小值都是不好的,其中有一些与全局最小值是相近的,这是我们就可以接受局部最小值。
同时,我们在初始化模型权重的方式可能导致它停留在局部最小值,为了避免这种状况,我们用来自均0值和低方差的随机正态分布的值来初始化两个权向量。
在每次迭代中,我们将从我们的数据集中随机采样子集,并将其与权重线性组合。这个子集称为mini-batch。在线性组合之后,我们将模型预测得到的结果送入SSE函数来计算当前误差。计算误差的偏导数就可以得到梯度:
对W0求偏导数为:
W 0 = ( W 0 + W 1 X ) y
对W1求偏导数为:
W 1 = X ( ( W 0 + W 1 X ) y )
这样我们就可以得到梯度向量:
Δ E r r = [ W 0 , W 0 ]
下面就可以使用梯度来更新权重向量W0和W1,以最大限度的减少误差值。
更新权重时需要沿着每个相应梯度的相反方向,在每个方向上采取尺寸为 η 的最小步长。其中 η 为学习率,假设 η 为0.1。更新权重可以表达成下面的式子:
W 0 = W 0 + η ( W 0 )
W 1 = W 1 + η ( W 1 )
完整的模型代码如下,梯度钱加负号用来保证采用梯度相反的方向
这里写图片描述
每迭代一次权重,都会导致直线向误差最小的方向移动,当误差足够小的时候就可以停止学习了。
这里写图片描述
使用mini-batch随机梯度下降,可以每次训练使用一小部分数据集来计算梯度, 加速了梯度下降速度
下图是每次迭代的误差曲线图:
这里写图片描述
这个图中我们可以发现在刚开始训练的时候误差下降的很快,但到迭代次数为100之后误差下降就变得很慢。这是因为一开始指向最陡下降的梯度矢量的幅度很大,两个权重变化就很快。但当他们接近误差曲面的顶点是,梯度变化越来越小,导致了权重变化很慢。最后学习曲线稳定了,学习过程完成。

reference:https://towardsdatascience.com/machine-learning-101-an-intuitive-introduction-to-gradient-descent-366b77b52645

猜你喜欢

转载自blog.csdn.net/katherine_hsr/article/details/80049287