数值计算

  对于机器学习中的问题,有一部分可以通过数学推导的方式直接得到用公式表达的解析解,但对绝大多数的问题来说,解析解是不存在的,需要使用迭代更新的方法求数值解。然而实数的精度是无限的,计算机能够表达的精度是有限的,这就涉及到许多数值计算方法的问题。

1. 基本概念

max min and saddle point

overall min

2. 基于梯度的优化方法

3. 利用梯度下降法求解的实例

问题

  假设有一些样本点$\boldsymbol{X}$和对应的目标$\boldsymbol{y}$,已知$\boldsymbol{y}$可以由$f(\boldsymbol{x}) = \boldsymbol{w \cdot x}+ b$加上噪音生成,求解函数$f$的参数$\boldsymbol{w}$和$b$。

求解

  首先定义$f(\boldsymbol{x})$相对于$y$的损失函数

那么损失函数相对于参数$\boldsymbol{w}$和$b$的导数分别为:

根据梯度下降法的公式可以得到参数的更新公式:

下面是利用numpy实现上述过求解的代码

这些代码可以在我们提供的jupyter notebook示例gradient descent example中直接运行查看。

import numpy as np
import matplotlib.pyplot as plt

## 定义w和b
feature_num = 10
w_real = np.random.random(feature_num)
b_real = np.random.random()

## 生成训练数据
instance_num = 1000
X = np.random.uniform(-100,100,(feature_num, instance_num))
y = np.matmul(w_real, X) + b_real
y = y + np.random.random(y.shape)

## 初始化参数
w = np.random.random(feature_num)
b = np.random.random()

iter_time = 20
step_size = 0.0001
loss_value = []

## 迭代求解
for i in range(iter_time):
    delta = np.matmul(w, X) + b_real - y
    loss_value.append((delta*delta).mean())
    w = w - step_size*(np.matmul(delta, X.T))/instance_num
    b = b - step_size*delta.mean()
plt.clf
plt.plot(np.array(loss_value[1:]))
plt.show()

运行上述代码可以得到是迭代过程中的损失变化情况,如下图示:

gradient descent loss

最后可以实际观察一下w和w_real的值,可以看到经过梯度迭代,确实可以得到参数的值。

>>>w
array([ 0.79842335,  0.42003747,  0.04151777,  0.05549998,  0.71396875,
        0.60893848,  0.19337114,  0.42662969,  0.27833712,  0.63035355])
>>>w_real
array([ 0.79855966,  0.41969485,  0.04192018,  0.05457261,  0.7145736 ,
        0.60895623,  0.19295485,  0.42620365,  0.27826274,  0.63047412])

上面的示例中,可以根据梯度迭代公式很容易且快速的迭代算出参数值,然而实际的机器学习问题往往比上面的问题复杂的多,因此迭代过程也不像上面的例子一样简单,而是涉及到许多技巧,在后续的章节中我们将根据学习进程对这些方法逐一介绍。