liyier

线性回归之梯度下降法

1.梯度的概念

梯度是一个向量,对于一个多元函数\(f\)而言,\(f\)在点\(P(x,y)\)的梯度是\(f\)在点\(P\)处增大最快的方向,即以f在P上的偏导数为分量的向量。以二元函数\(f(x,y)\)为例,向量\(\{\frac{\partial f}{\partial x},\frac{\partial f}{\partial y}\}|_{(x_0,y_0)}=f_x(x_0,y_0)\overrightarrow i+f_y(x_0,y_0)\overrightarrow j\)就是函数\(f(x,y)\)在点\(P(x_0,y_0)\)处的梯度,记作\(gradf(x,y)\)或者\(\nabla f(x,y)\)

2.梯度下降法

对于梯度下降,我们可以形象地理解为一个人下山的过程。假设现在有一个人在山上,现在他想要走下山,但是他不知道山底在哪个方向,怎么办呢?显然我们可以想到的是,一定要沿着山高度下降的地方走,不然就不是下山而是上山了。山高度下降的方向有很多,选哪个方向呢?这个人比较有冒险精神,他选择最陡峭的方向,即山高度下降最快的方向。现在确定了方向,就要开始下山了。又有一个问题来了,在下山的过程中,最开始选定的方向并不总是高度下降最快的地方。这个人比较聪明,他每次都选定一段距离,每走一段距离之后,就重新确定当前所在位置的高度下降最快的地方。这样,这个人每次下山的方向都可以近似看作是每个距离段内高度下降最快的地方。现在我们将这个思想引入线性回归,在线性回归中,我们要找到参数矩阵\(\theta\)使得损失函数\(J(\theta)\)最小。如果把损失函数\(J(\theta)\)看作是这座山,山底不就是损失函数最小的地方吗,那我们求解参数矩阵\(\theta\)的过程,就是人走到山底的过程。

image-20191105211435202

如图所示,这是一元线性回归(即假设函数\(h_\theta(x) = \theta_0+\theta_1x\))中的损失函数图像,一开始我们选定一个起始点(通常是\((\theta_0=0,\theta_1=0)\)),然后沿着这个起始点开始,沿着这一点处损失函数下降最快的方向(即该点的梯度负方向)走一小步,走完一步之后,到达第二个点,然后我们又沿着第二个点的梯度负方向走一小步,到达第三个点,以此类推,直到我们到底局部最低点。为什么是局部最低点呢?因为我们到达的这个点的梯度为0向量(通常是和0向量相差在某一个可接受的范围内),这说明这个点是损失函数的极小值点,并不一定是最小值点。

image-20191105212707135

从梯度下降法的思想,我们可以看到,最后得到的局部最低点与我们选定的起始点有关。通常情况下,如果起始点不同,最后得到的局部最低点也会不一样。

3.梯度下降算法描述

现在对于梯度下降法,有了一个直观形象的理解了。接下来,我们看一下梯度下降算法。首先,我们给在下山的例子中每一段路的距离取名叫学习率(Learning Rate,也称步长,用\(\alpha\)表示),把一次下山走一段距离叫做一次迭代。算法详细过程:

  1. 确定定参数的初始值,计算损失函数的偏导数

  2. 将参数代入偏导数计算出梯度。若梯度为0,结束;否则转到3

  3. 用步长乘以梯度,并对参数进行更新

  4. 重复2-3

对于多元线性回归来说,拟合函数为:

\[h_\theta(x) = \sum_\limits{i=0}^n\theta_ix_i =\theta_0+ \theta_1x_1 + \cdots+\theta_nx_n \tag{3.1} \]

损失函数为:

\[J(\theta)=\frac{1}{2m}\sum_\limits{i=0}^m(y^{(i)}-h_\theta(x^{(i)}))^2 \tag{3.2} \]

损失函数的偏导数为:

\[\frac{\partial J(\theta)}{\theta_i} = \frac{1}{m}\sum_\limits{j=1}^m(h_\theta(x^{(j)})-y^{(j)})x_i^{(j)}=\frac{1}{m}\sum_\limits{j=1}^m(\sum_\limits{i=0}^n\theta_ix_i^{(j)}-y^{(j)})x_i^{(j)}\quad (i=0,1,\dots,n) \tag{3.3} \]

每次更新参数的操作为:

\[\theta_i = \theta_i-\alpha\frac{\partial J(\theta)}{\theta_i} = \theta_i-\alpha\frac{1}{m}\sum_\limits{j=1}^m(h_\theta(x^{(j)})-y^{(j)})x_i^{(j)}\quad (i=0,1,\dots,n)\tag{3.4} \]

注意,更新参数时必须同步更新所有参数,不能先更新\(\theta_0\)再更新\(\theta_1\),如果用Java伪代码就是:

double []temp = new double[n+1]; //因为参数

分类:

技术点:

相关文章:

  • 2021-09-02
  • 2021-06-01
  • 2021-06-20
  • 2021-09-29
  • 2021-11-27
  • 2022-01-01
  • 2022-01-01
猜你喜欢
  • 2021-11-27
  • 2021-12-12
  • 2021-11-12
  • 2019-03-23
  • 2021-10-24
  • 2021-05-19
  • 2021-07-05
相关资源
相似解决方案