15、机器学习中的数学基础与反向传播算法

机器学习中的数学基础与反向传播算法

1. 数学基础的重要性

机器学习离不开数学,尤其是线性代数和微积分。线性代数为处理向量、矩阵和张量等数据数组提供了工具,而微积分则用于计算函数的导数,这在优化算法中至关重要。

1.1 进一步阅读建议

  • 若想深入学习线性代数,推荐 Sheldon Axler 的《Linear Algebra Done Right》(2015 年,Springer 出版)。
  • 对于微积分,包括向量微积分,James Stewart 的《Calculus: Early Transcendentals》(2015 年,Cengage Learning 出版)是一本全面且实用的指南。
  • 若想深入理解微积分的数学理论,Walter Rudin 的经典著作《Principles of Mathematical Analysis》(1976 年,McGraw Hill 出版)是不二之选。

2. 线性代数基础

2.1 向量:一维数据

向量是一维的数字数组,数组的大小即为向量的维度。在 Python 中,可以使用 NumPy 数组来表示向量。以下是一些基本操作:

import numpy as np

# 创建向量
x = np.array([1, 2])
print(x)  # 输出: array([1, 2])
print(x.shape)  # 输出: (2,)

y = np.array([3, 3.1, 3.2, 3.3])
print(y)  # 输出: array([3., 3.1, 3.2, 3.3])
print(y.shape)  # 输出: (4,)

# 访问向量元素
x = np.array([5, 6, 7, 8])
print(x[0])  # 输出: 5
print(x[1])  # 输出: 6

# 向量加法
x = np.array([1, 2, 3, 4])
y = np.array([5, 6, 7, 8])
print(x + y)  # 输出: array([ 6,  8, 10, 12])

# 元素-wise 乘法(Hadamard 积)
x = np.array([1, 2, 3, 4])
y = np.array([5, 6, 7, 8])
print(x * y)  # 输出: array([ 5, 12, 21, 32])

# 标量乘法
x = np.array([1, 2, 3, 4])
print(0.5 * x)  # 输出: array([0.5, 1., 1.5, 2.])

# 点积
x = np.array([1, 2, 3, 4])
y = np.array([4, 5, 6, 7])
print(np.dot(x, y))  # 输出: 60
print(x @ y)  # 输出: 60

2.2 矩阵:二维数据

矩阵是二维的数字数组,同样可以使用 NumPy 数组来表示。以下是矩阵的基本操作:

# 创建矩阵
x = np.array([
    [1, 2, 3],
    [4, 5, 6]
])
print(x)
# 输出:
# array([[1, 2, 3],
#        [4, 5, 6]])
print(x.shape)  # 输出: (2, 3)

# 访问矩阵元素
print(x[0][1])  # 输出: 2
print(x[0, 1])  # 输出: 2
print(x[1][0])  # 输出: 4
print(x[1, 0])  # 输出: 4

# 提取矩阵的行和列
y = x[0]
print(y)  # 输出: array([1, 2, 3])
print(y.shape)  # 输出: (3,)

z = x[:, 1]
print(z)  # 输出: array([2, 5])

# 矩阵加法
x = np.array([
    [1, 2, 3],
    [4, 5, 6]
])
y = np.array([
    [3, 4, 5],
    [6, 7, 8]
])
print(x + y)
# 输出:
# array([[ 4,  6,  8],
#        [10, 12, 14]])

# 元素-wise 乘法
print(x * y)
# 输出:
# array([[ 3,  8, 15],
#        [24, 35, 48]])

# 标量乘法
print(0.5 * x)
# 输出:
# array([[0.5, 1., 1.5],
#        [2., 2.5, 3.]])

2.3 三阶张量

在一些场景中,如表示棋盘或图像,可以使用三阶张量。以围棋棋盘为例,可以用多个矩阵堆叠来表示,每个矩阵代表一种棋子类型。同样,图像可以用三个通道(红、绿、蓝)的矩阵来表示。以下是创建和操作三阶张量的示例:

# 创建三阶张量
x = np.array([
    [[1, 2, 3],
     [2, 3, 4]],
    [[3, 4, 5],
     [4, 5, 6]]
])
print(x.shape)  # 输出: (2, 2, 3)
print(x[0])
# 输出:
# array([[1, 2, 3],
#        [2, 3, 4]])
print(x[1])
# 输出:
# array([[3, 4, 5],
#        [4, 5, 6]])

三阶张量也支持元素-wise 加法、乘法和标量乘法。在处理张量时,需要注意索引方案,常见的有 channels_first channels_last 两种。

2.4 四阶张量

为了提高效率,可以将多个三阶张量打包成四阶张量。矩阵和向量是张量的特殊情况,矩阵是二阶张量,向量是一阶张量,而零阶张量就是普通的数字。

3. 微积分基础:导数与求最大值

3.1 导数的概念

在微积分中,函数的变化率称为导数。以下是一些实际生活中的导数示例:
| 数量 | 导数 |
| ---- | ---- |
| 行驶的距离 | 行驶的速度 |
| 浴缸中的水量 | 水流出的速度 |
| 客户数量 | 客户增减的数量 |

导数不是一个固定的量,而是一个随时间或空间变化的函数。当函数递增时,导数为正;当函数递减时,导数为负。可以利用导数来寻找函数的局部最大值或最小值,在局部最大值处,导数为零。

3.2 梯度上升和梯度下降

在机器学习中,许多函数以高维向量为输入,输出一个标量。这类函数的导数是一个与输入维度相同的向量,称为梯度。沿着梯度方向最大化函数的过程称为梯度上升,而最小化函数的过程称为梯度下降。

大多数简单的代数函数都有已知的导数,可以在微积分教材中查找。对于复杂的函数,可以使用链式法则来计算其导数。一些库,如 TensorFlow 和 Theano,利用链式法则自动计算复杂函数的导数。在 Keras 中定义复杂函数时,无需手动计算梯度,Keras 会将工作交给 TensorFlow 或 Theano 处理。

4. 反向传播算法

4.1 符号说明

在处理前馈神经网络时,使用以下符号:
- 网络有 $l$ 层,第 $i$ 层的权重记为 $W_i$,偏置项记为 $b_i$。
- 输入数据为 $x$,输出为 $y$。
- 第 $i$ 层的激活输出记为 $y_{i+1}$,即 $y_{i+1} = \sigma(W_i y_i + b_i)$。
- 第 $i$ 层的非激活输出记为 $z_i$,即 $z_i = W_i \cdot y_i + b_i$。

4.2 前馈神经网络的反向传播算法

前馈神经网络的前向传播可以表示为:
$y_{i+1} = \sigma(W_i y_i + b_i) = f \circ y_i$
预测值可以递归地表示为:
$y = f \circ \cdots \circ f(x)$
损失函数可以表示为:
$Loss(y, \hat{y}) = Loss \circ f \circ \cdots \circ f(x)$

通过链式法则计算损失函数的导数,定义第 $i$ 层的 $\delta$ 为:
$\Delta_i = (W_i)^{\top} \cdot (\Delta_{i+1} \odot \sigma’(z_i))$

其中,$^{\top}$ 表示矩阵转置,$\odot$ 表示 Hadamard 积。计算可以分为两部分,一部分是密集层的计算,另一部分是激活函数的计算:
$\Delta_{\sigma} = \Delta_{i+1} \odot \sigma’(z_i)$
$\Delta_i = (W_i)^{\top} \cdot \Delta_{\sigma}$

最后,计算每一层参数 $W_i$ 和 $b_i$ 的梯度,根据这些误差项,可以使用任何优化器或更新规则来更新神经网络的参数。

4.3 顺序神经网络的反向传播

一般来说,顺序神经网络可能包含更复杂的层,如卷积层或其他激活函数。但反向传播的基本思路是相同的。如果 $g$ 表示无激活的前向传播,$Act$ 表示相应的激活函数,将 $\Delta$ 传播到第 $i$ 层需要计算以下转换:
需要计算激活函数在中间输出 $z_i$ 处的导数,以及层函数 $g$ 相对于第 $i$ 层输入的导数。知道所有的 $\Delta$ 后,通常可以快速推导出层中所有参数的梯度。

4.4 一般神经网络的反向传播

在非顺序网络中,一层可能有多个输出、多个输入或两者都有。对于有 $m$ 个输出的层,前向传播可以拆分为 $k$ 个独立的函数,反向传播时,每个函数的导数分别计算,且每个导数对传递到前一层的 $\Delta$ 贡献相同。对于有 $n$ 个输入和一个输出的情况,前向传播由一个函数从 $n$ 个输入分量计算得到一个输出值,反向传播时,从下一层接收一个 $\Delta$,需要计算 $n$ 个输出 $\Delta$ 传递给前 $n$ 层。一般情况下,$n$ 个输入和 $m$ 个输出的情况可以通过结合上述两种情况来处理。

4.5 反向传播的计算挑战

虽然反向传播在理论上只是链式法则在特定机器学习算法中的应用,但在实践中,实现时需要考虑很多因素。例如,为了计算任何层的 $\Delta$ 和梯度更新,需要保留前向传播的输入。如果简单地丢弃前向传播的结果,在反向传播时需要重新计算。因此,需要有效地缓存这些值。另外,重用中间值也很重要,例如在简单的前馈网络中,可以将仿射线性变换和 sigmoid 激活看作一个单元,或者拆分为两层。自动检测哪些操作可以一起执行可以带来很大的速度提升。在更复杂的情况下,如循环神经网络,管理中间状态变得更加重要。

综上所述,线性代数和微积分是机器学习的重要基础,反向传播算法是训练神经网络的核心。理解这些数学概念和算法对于深入学习机器学习至关重要。在实际应用中,需要注意计算效率和内存使用,合理利用现有的库和工具来简化开发过程。

5. 线性代数与微积分在机器学习中的应用示例

5.1 线性代数在数据表示中的应用

线性代数中的向量、矩阵和张量在机器学习的数据表示中起着关键作用。例如,在图像识别任务中,一张彩色图像可以用一个三阶张量表示,其中每个通道分别对应红、绿、蓝三种颜色。以下是一个简单的示例,展示如何使用 NumPy 处理图像数据:

import numpy as np
import matplotlib.pyplot as plt

# 模拟一个 128x64 的彩色图像
image = np.random.randint(0, 256, size=(3, 128, 64), dtype=np.uint8)

# 显示图像
plt.imshow(np.transpose(image, (1, 2, 0)))
plt.show()

在这个示例中,我们首先创建了一个随机的三阶张量来模拟彩色图像,然后使用 matplotlib 库将其显示出来。需要注意的是, matplotlib 要求图像数据的形状为 (height, width, channels) ,因此我们使用 np.transpose 函数对张量进行了转置。

5.2 微积分在优化算法中的应用

微积分中的梯度下降算法是机器学习中常用的优化算法之一。以简单的线性回归问题为例,我们的目标是找到一组参数 $w$ 和 $b$,使得预测值与真实值之间的误差最小。误差函数通常定义为均方误差(MSE):
$MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - (w x_i + b))^2$
我们可以使用梯度下降算法来更新参数 $w$ 和 $b$,以最小化 MSE。以下是一个简单的实现:

import numpy as np

# 生成一些随机数据
x = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])

# 初始化参数
w = 0
b = 0

# 学习率
learning_rate = 0.01

# 迭代次数
epochs = 1000

for epoch in range(epochs):
    # 计算预测值
    y_pred = w * x + b

    # 计算误差
    error = y_pred - y

    # 计算梯度
    dw = (2/len(x)) * np.dot(x, error)
    db = (2/len(x)) * np.sum(error)

    # 更新参数
    w = w - learning_rate * dw
    b = b - learning_rate * db

print(f"Final w: {w}, Final b: {b}")

在这个示例中,我们首先生成了一些随机数据,然后初始化了参数 $w$ 和 $b$。在每次迭代中,我们计算预测值、误差和梯度,然后使用梯度下降算法更新参数。经过多次迭代后,我们得到了最终的参数值。

6. 反向传播算法的流程图与总结

6.1 反向传播算法的流程图

graph TD;
    A[输入数据] --> B[前向传播];
    B --> C[计算损失函数];
    C --> D[反向传播];
    D --> E[计算梯度];
    E --> F[更新参数];
    F --> B;

这个流程图展示了反向传播算法的基本流程:首先进行前向传播,计算预测值和损失函数;然后进行反向传播,计算梯度;最后根据梯度更新参数。这个过程会不断重复,直到达到收敛条件。

6.2 总结

本文介绍了机器学习中重要的数学基础,包括线性代数和微积分,以及用于训练神经网络的反向传播算法。线性代数中的向量、矩阵和张量为数据表示提供了强大的工具,而微积分中的导数和梯度则是优化算法的核心。反向传播算法通过链式法则计算损失函数的梯度,从而实现了神经网络参数的更新。

在实际应用中,我们需要注意计算效率和内存使用,合理利用现有的库和工具来简化开发过程。同时,理解这些数学概念和算法对于深入学习机器学习至关重要,它们为我们提供了理论基础和实践指导。希望本文能够帮助读者更好地理解机器学习中的数学原理和算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值