章节 5

预测函数与通用预测理论

在机器学习(ML)的语境中,构建有效预测模型的一个重要要素,是确定预测函数的假设。该函数建立特征变量与学习参数之间的联系,其选择必须有充分依据。预测函数的核心任务,是利用一组给定的学习参数,在特征空间中高精度地预测任意线性函数。需要强调的是,预测函数被假定为关于特征变量的完整线性函数;这是本领域中的一个基本假设。 完整的线性预测函数在仿射空间中对数据执行仿射变换。此类变换保持仿射性:欧几里得距离和直线的平行性在相应意义下得到保持,尽管角度以及点之间的距离可能发生变化。这保证了数据变换的唯一性和连续性,避免在学习参数变化时出现不同点合并,或一个点被分裂为两个点的情况。 仿射变换是由学习参数控制的线性变换与平移的组合。它能够在特征空间中复现任意一阶函数,这一点对于 ML 模型的预测能力至关重要。...

25分钟 13,106词数 10资料

关键思想

  • 5.1 线性预测函数与仿射变换
  • 5.2 典型数据结构
  • 5.3 仿射变换的演示示例
  • 5.4 参数编码与学习的基本机制
  • 5.5 预测函数的梯度
  • 5.6 仿射变换阵列(ATA)

实践任务

选取一个与“预测函数与通用预测理论”相关的小例子,说明机器学习、特征在其中如何发挥作用,并用一句话解释结果。

打开实验室

预测函数与通用预测理论

打开实验室

在机器学习(ML)的语境中,构建有效预测模型的一个重要要素,是确定预测函数的假设。该函数建立特征变量与学习参数之间的联系,其选择必须有充分依据。预测函数的核心任务,是利用一组给定的学习参数,在特征空间中高精度地预测任意线性函数。需要强调的是,预测函数被假定为关于特征变量的完整线性函数;这是本领域中的一个基本假设。

完整的线性预测函数在仿射空间中对数据执行仿射变换。此类变换保持仿射性:欧几里得距离和直线的平行性在相应意义下得到保持,尽管角度以及点之间的距离可能发生变化。这保证了数据变换的唯一性和连续性,避免在学习参数变化时出现不同点合并,或一个点被分裂为两个点的情况。

仿射变换是由学习参数控制的线性变换与平移的组合。它能够在特征空间中复现任意一阶函数,这一点对于 ML 模型的预测能力至关重要。

本章将详细讨论预测函数的表述及其可预测性,并进一步分析仿射变换、仿射变换的性质,以及它们对模型行为的影响。同时,本章还将给出 Python 示例。本教材以及本章所使用的全部代码可在以下地址获取:https://sohoware.ru/SohoBook/。本章重点关注两个方面:

1. 模型在特征空间中预测函数的能力; 2. 仿射空间中仿射变换的特点,包括其独特性质以及在不同机器学习场景中的应用。

随后,我们将引入仿射变换单元(ATU,Affine Transformation Unit)的概念,也可称为线性预测函数单元。本章将展示能够执行仿射变换的简单神经网络,并着重说明它们的行为和性质。我们还将考察学习参数如何对特征进行编码,以及这些编码的唯一性,从而突出“数据到参数”变换的重要性。

接着,我们将讨论如何扩展 ATU 的概念以构建仿射变换阵列(ATA),以及如何在 ATA 外部包裹激活函数,从而形成多层感知机(MLP)或深度神经网络。这有助于理解深度网络如何获得对高阶非线性函数的可预测性。

本章最后将引入通用预测理论。该理论为解释深度网络在预测中的有效性提供基础框架,并帮助说明为什么深度网络能够在机器学习的多个领域中高效地用于预测任务。

5.1 线性预测函数与仿射变换

在人工神经网络(ANN)中,我们使用神经元内部的数据与学习参数之间的仿射变换,在某种意义上模拟神经递质中的信息转换过程。

ANN 中的仿射变换,是通过学习参数调节的线性变换与平移的组合。这样的变换能够在保持特征空间几何性质的同时,对数据中的复杂依赖关系进行建模。

5.1.1 线性预测函数:基本假设

在机器学习模型中,假设预测函数 z 由以下形式给出:

Text
z(x; w, b) = xw + b

其中,z(x; w, b) 可理解为“在给定参数 w 与 b 的情况下,关于 x 的函数 z”。这里的向量通常可写为:

Text
x = [x1, x2, ..., xp]
\hat{x} = [1, x] = [1, x1, x2, ..., xp]
w = [w1, w2, ..., wp]^T
\hat{w} = [b, w1, w2, ..., wp]^T

其中,x1, x2, ..., xp 是用于线性基函数的特征变量。权重 wi (i = 1, 2, ..., p) 与偏置 b 是模型参数,它们在相应空间中组成向量。w 上方的“帽子”表示扩展向量:它把偏置 b 也纳入其中,从而在假设空间中形成新的参数向量。

权重和偏置可以被调整,以精确预测特征空间中的任意给定线性函数。这里特别强调学习参数的转置,是为了说明它们可以表示为矩阵;在本例中即为一列矩阵。特征通常表示为行向量,因此学习参数矩阵从右侧作用于特征向量。

我们有意把最常用的预测函数 z 的公式合并为统一形式,以便清楚展示这些变量之间的关系。建议读者仔细理解这一表述,因为后续推导将反复使用它。

当使用 z = xw + b 时,我们称之为 xw + b 表述;当使用 z = \hat{x}\hat{w},并把偏置 b 合并到 \hat{w} 中时,我们称之为 \hat{x}\hat{w} 表述。本书会交替使用这两种写法,因为它们本质上表达同一概念。xw + b 表述有助于在分析中明确区分权重和偏置的作用;\hat{x}\hat{w} 表述则在推导过程中更加简洁,并能更明确地表达仿射变换。

5.1.2 对常数的可预测性:偏置的作用

在预测常数时,偏置 b 是非常有用的工具。它能够使模型正确对齐目标值,补偿系统性误差,并提高预测的稳定性与准确性。如果令 b = 0 而完全依赖权重 w,模型就会失去预测常数这类简单函数的能力。

设函数 y(x) = c,其中 c 是一个与 x 无关的常数。当 x = 0 时,显然有 y(0) = c。如果我们希望用 xw + b 来预测 c,就需要 z(w, b; x = 0) = c。但如果从方程中去掉 b,那么无论如何选择 w,模型都会给出:

Text
z = 0 · w = 0

这说明,如果没有偏置 b,假设函数永远无法预测常数值 c。因此,仅使用权重 w 的简单线性变换不足以完成充分的预测,因为它无法预测最基本的常数值。

相反,如果模型中包含偏置 b,我们只需令 b = c,假设函数就可以成功预测常数 c。这也说明变量 z 应当被放在仿射空间中理解;仿射空间是扩展的特征空间。在这一空间中,引入偏置后,模型不仅能够表达特征与权重之间的关系,还能够表达目标变量的绝对水平。

5.1.3 对线性函数的可预测性:权重的作用

理解预测线性模型中权重 w 与偏置 b 的作用,有助于精确预测一大类线性函数。下面进一步说明其机制。

考虑线性函数:

Text
y(x) = xk + c

其中:

• c 是常数;

• k 是向量空间中的向量。

虽然 k 可以属于某一空间,但为了进行向量运算,它必须被置于合适的向量空间框架之中。

关键在于正确选择模型参数。如果选择 w = k 且 b = c,就可以用模型精确复现函数 y(x):

Text
z(w, b; x) = xk + c = y(x)

这种参数选择使模型能够精确预测给定的线性函数。这意味着,对任意依赖于变量 x 的线性函数,都可以使用上述预测函数假设进行预测。

权重 w 与偏置 b 共同决定输入数据(变量 x)如何被转换为预测值。权重决定每个特征对最终预测的影响;偏置则负责与输入无关的常数成分。对于未中心化的数据,即特征均值不为零的情况,偏置尤其重要,因为它可以校正预测的整体水平。

5.1.4 线性函数的预测:机器学习方法

使用预测函数 z 来预测线性函数,是相对直接的过程。这是因为模型参数(或学习参数)可以根据观测结果进行选择。在线性模型中,这些参数通常是权重(系数),它们决定每个输入特征如何影响预测值。

然而,在更复杂的问题中,数据与预测值之间的关系不那么明显,或者数据本身具有更复杂的结构,仅凭观察来“选择”参数就不够了。此时需要更加系统的方法。为了在复杂情形中找到最优学习参数,可以使用最小化过程。该过程的目标,是找到使模型预测值与真实值之间误差最小的一组参数。

这一次,我们采用 \hat{x}\hat{w} 表述,把线性函数写成:

Text
y(x) = xk + c = \hat{x}\hat{k}

其中,\hat{x} 是包含常数 1 的扩展特征向量,\hat{k} 是包含常数项 c 的扩展参数向量。

步骤 1:定义损失函数。 机器学习中的损失函数用于衡量模型预测正确值的程度。损失函数评估预测方程 \hat{x}\hat{w} 与真实标签函数 y(x) 之间的差异。目标是最小化这种差异,使模型预测尽可能准确。

常见的选择之一是平方误差损失。对于单个样本,可写为:

Text
L(\hat{w}; x) = (\hat{x}\hat{w} - y(x))^2

对于包含多个样本的数据集,则通常对所有样本误差求和或求平均。

步骤 2:通过优化寻找学习参数。 训练过程就是寻找使损失函数达到最小值的参数 \hat{w}。如果目标函数是线性函数,并且数据没有噪声,那么理论上可以找到使损失为零的参数。若数据含有噪声或模型表达能力有限,则训练将寻找在整体意义上最优的近似参数。

步骤 3:用训练得到的参数进行预测。 当最优参数确定后,模型就可以对新的输入特征 x 计算预测值 z。这正是机器学习模型从数据中学习并用于预测的基本流程。

因此,在线性函数的情形下,机器学习方法把“选择参数”的问题转化为“最小化损失函数”的问题。这个思想也会延伸到后续更复杂的神经网络模型之中。

5.1.5 仿射变换

线性预测函数与仿射变换密切相关。仿射变换可以看作线性变换与平移的组合,其典型形式为:

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.1.5 仿射变换
Text
z = xW + b

其中,W 是权重矩阵,b 是偏置向量,x 是输入特征向量。若把偏置合并到扩展矩阵中,也可以写成:

Text
\hat{z} = \hat{x}\hat{W}

这种写法把仿射变换统一表示为扩展空间中的矩阵乘法。扩展输入向量 \hat{x} 在原始输入 x 前添加常数 1;扩展权重矩阵 \hat{W} 则同时包含偏置和权重。

在神经网络中,仿射变换通常发生在隐藏层之间。它不仅执行线性变换,还通过偏置实现平移,使模型能够表达更丰富的数据关系。隐藏层使用这样的变换来建立层与层之间的联系,并为后续激活函数提供输入。

考虑几个特殊情形:

1. 如果所有学习参数都设为零,即 \hat{W} = 0,那么任意数据点都会塌缩到同一个点。这表示模型失去了区分不同输入的能力。 2. 如果令 b = 0 且 W = I,其中 I 为单位矩阵,则有 z = x。这表示输入点保持不变,即没有发生变换。 3. 如果令 b = c 且 W = I,则有 z = x + c。这表示所有点都按向量 c 发生平移。 4. 如果适当选择 b 与 W,仿射变换就可以复现前面讨论的线性函数 y(x) = xk + c。

因此,在特征空间中预测线性函数,可以看作在仿射空间中执行仿射变换。权重控制旋转、缩放、剪切等线性成分,而偏置控制平移成分。

5.2 典型数据结构

5.2.1 具有 p 个输入特征和 1 个输出神经元的网络

预测函数 z 可以以具有明确维度的矩阵形式写出:

Text
z(w, b; x) = xw + b

此时,预测函数 z 被明确定义为关于 w 和 b 的函数,并对应于任意输入 x。对于第 i 个数据点 xi,有:

Text
z(w, b; xi) = xi w + b

需要注意的是,对于一个数据点而言,z(\hat{w}; x) 是一个标量。这意味着,当预测函数 z 作用于某一个具体数据点 x 时,它输出单个数值。例如,如果网络根据房屋面积、房间数量等特征来预测价格,那么对于描述一套房屋的一组输入数据,网络会输出一个数值,即预测价格。

还需要注意,在单层网络中,z 通常不需要进一步变换。在更复杂的多层网络中,一层的输出常常作为下一层的输入,并继续接受新的变换;但在这里讨论的单层网络中,函数 z 的输出不需要额外处理。这简化了网络结构,因为每个神经元的输出可以直接作为网络的最终输出。

5.2.2 具有 p 个输入特征和 k 个输出神经元的网络

在高维输出的情形中,当前层的输出可以包含多个神经元,设为 k 个。每个神经元都基于同一组输入数据独立执行仿射变换。因此,输出应当是包含 k 个元素的数组。

数据可用矩阵形式表示为:

Text
z = xW + b

其中:

Text
x: 1 × p
W: p × k
b: 1 × k
z: 1 × k

也就是说,同一个输入向量 x 同时作用于多个输出神经元;每个输出神经元拥有自己的权重列和偏置分量。这样就得到一个包含 k 个分量的输出向量。

值得指出的是,每一层中的神经元数量可以任意增加,因为分配给每个神经元的权重与同一层中其他神经元的权重没有必然绑定。能够添加任意数量的神经元非常重要,因为这为实现通用逼近理论提供了基础。

5.2.3 具有 p 个输入特征、k 个输出神经元和 m 个数据点的网络

对于包含 m 个数据点的数据集,可以把所有输入数据按行堆叠成矩阵:

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.2.3 具有 p 个输入特征、k 个输出神经元和 m 个数据点的网络
Text
X: m × p

在这种情况下,模型会相应地产生 m 个预测结果。矩阵形式可写为:

Text
Z = XW + B

其中:

Text
X: m × p
W: p × k
B: m × k
Z: m × k

这里的 B 是偏置矩阵,它在每一行中重复同一个偏置向量 b。上述表达式也可以看作对每一个数据点分别执行 z = xW + b,然后把所有输出按行组合在一起。

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.2.3 具有 p 个输入特征、k 个输出神经元和 m 个数据点的网络

需要注意的是,在实际计算中,我们并不总是显式形成完整矩阵 Z。在构建损失函数时,它通常表现为对 m 个数据点的求和或求平均。因此,在理论推导中写成矩阵形式很方便,但在实现中会根据效率和内存需求采用更合适的计算方式。

5.3 仿射变换的演示示例

下面给出几个仿射变换的示例。对于由多个数据点组成的给定几何图案(即仿射空间中的点集),其第 i 行可通过预测函数方程 z(·) 计算。设 w 与 b 是假设空间中给定的一组学习参数;当学习参数改变为新的 w 与 b 时,原始点会被映射为新的变换点。

经过这样的处理,得到的变换后数据点仍可写成扩展形式,例如 [1, z1, z2]。也就是说,通过两次改变 ŵ,对原始数据集实施仿射变换,可以得到仍处在同一仿射空间中的变换后数据集。这类变换可以看作该空间中的自同构。

下面用代码演示上述变换的相似性。由于所讨论的空间仍然可以作为二维平面来表示,因此可以只使用两个坐标分量,把原始图案与变换后的图案绘制在同一空间中,以便进行可视化和分析。

5.3.1 边与矩形的仿射变换

Python
import numpy as np
import matplotlib.pyplot as plt

def affine_transformation(data, weights, bias):
    """
    对数据执行仿射变换。

    data: 输入数据
    weights: 权重向量
    bias: 偏置

    返回变换后的数据。
    """
    return np.dot(data, weights) + bias


def rectangular_pattern(min_x, max_x, min_y, max_y, step, rotation_angle):
    """
    在二维空间中创建矩形图案。

    min_x, max_x, min_y, max_y: 矩形边界
    step: 点之间的步长
    rotation_angle: 图案旋转角

    返回数组 X1、X2 以及合并后的点数组 X。
    """
    x = np.arange(min_x, max_x + step, step)
    ymin, ymax = np.full(x.shape, min_y), np.full(x.shape, max_y)

    y = np.arange(min_y, max_y + step, step)
    xmin, xmax = np.full(y.shape, min_x), np.full(y.shape, max_x)

    x1 = np.concatenate([x, xmax, np.flip(x), xmin])
    x2 = np.concatenate([ymin, y, ymax, np.flip(y)])
    x1 = np.append(x1, (max_x + min_x) / 2)
    x2 = np.append(x2, (max_y + min_y) / 2)
    X1 = x1 * np.cos(rotation_angle) + x2 * np.sin(rotation_angle)
    X2 = x2 * np.cos(rotation_angle) - x1 * np.sin(rotation_angle)
    X = np.stack((X1, X2), axis=-1)
    return x, y, X


# 定义不同变换所用的权重和偏置
weights_0, weights_0_1, bias_0 = [0., 1.], [1., 0.], 0  # 原始图案
bias_1 = 1  # 改变偏置
weights_2, weights_2_1 = [0., 0.5], [0.5, 0.]  # 减小权重
weights_3, weights_3_1 = [0.5, 0.3], [1.2, 0.1]  # 改变权重

# 生成矩形图案
x, y, X = rectangular_pattern(-1., 1., 1., 3., 0.1, np.pi / 4)

# 创建图形
plt.figure(figsize=(4., 4.), dpi=90)
plt.scatter(affine_transformation(X, weights_0, bias_0),
            affine_transformation(X, weights_0_1, bias_0),
            label="原始图案", s=5, c='orange')
plt.scatter(affine_transformation(X, weights_0, bias_1),
            affine_transformation(X, weights_0_1, bias_1),
            label="改变偏置", s=5, c='blue')
plt.scatter(affine_transformation(X, weights_2, bias_0),
            affine_transformation(X, weights_2_1, bias_0),
            label="权重减小", s=5, c='red')
plt.scatter(affine_transformation(X, weights_3, bias_0),
            affine_transformation(X, weights_3_1, bias_0),
            label="权重改变", s=5, c='green')

# 显示图例
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.axis('scaled')  # 保持坐标比例
plt.show()

本节考察作用于矩形的仿射变换过程。首先创建一个矩形图案,它由一组橙色点表示;随后对这些点应用由预测函数方程 z(·) 定义的仿射变换。

接着,对变换前后的图案进行可视化。这样的表示方式有助于直观观察不同变换类型带来的效果。

矩形特别适合用于说明仿射变换,因为它由直线边组成。因此,形状与方向的变化很容易在原始结构的参照下被观察到。根据图示可以得到以下结论:

仿射变换之后,原始的橙色矩形图案只发生旋转、缩放、错切与平移,并被移动到新的位置。权重 w 控制线性变换的结果,包括缩放与旋转;偏置 b 控制平移。该变换把点映射为点,把边映射为边,把四边形映射为四边形。

仿射变换保持平行线段长度之间的比例。例如,橙色矩形两条较长边之间的比例,与绿色四边形两条较长边之间的比例相同。

平行线段在仿射变换之后仍然保持平行。

仿射变换不保持点与点之间的绝对距离。它只保持位于同一直线上的点之间的距离比例。

仿射变换也不保持线与线之间的角度。这个简单示例有助于说明:当改变 w 与 b 时,仿射变换后的图案如何覆盖同一个空间。单纯的线性变换本身不会改变坐标原点,因此其覆盖能力受到更大限制。

5.3.2 仿射变换作用下的圆

下面考察圆的仿射变换。

Python
import numpy as np
import matplotlib.pyplot as plt

def affine_transformation(data, weights, bias):
    """
    对数据执行仿射变换。

    data: 输入数据
    weights: 权重向量
    bias: 偏置

    返回变换后的数据。
    """
    return np.dot(data, weights) + bias


def circular_pattern(radius, angle_step):
    """
    在二维空间中创建圆形图案。

    radius: 圆半径
    angle_step: 角度步长(弧度)

    返回坐标 x、y 以及点数组 X。
    """
    angles = np.arange(0.0, 2 * np.pi, angle_step)
    x = radius * np.cos(angles)
    y = radius * np.sin(angles)
    X = np.column_stack((x, y))
    return x, y, X


# 定义不同变换所用的权重和偏置
weights_0, weights_0_1, bias_0 = [0., 1.], [1., 0.], 0  # 原始图案
bias_1 = 1  # 改变偏置
weights_2, weights_2_1 = [0., 0.5], [0.5, 0.]  # 减小权重
weights_3, weights_3_1 = [0.5, 0.3], [1.2, 0.1]  # 改变权重

# 生成圆形图案
x, y, X = circular_pattern(1, 0.1)

# 创建图形
plt.figure(figsize=(4., 4.), dpi=90)
plt.scatter(affine_transformation(X, weights_0, bias_0),
            affine_transformation(X, weights_0_1, bias_0),
            label="原始图案", s=5, c='orange')
plt.scatter(affine_transformation(X, weights_0, bias_1),
            affine_transformation(X, weights_0_1, bias_1),
            label="改变偏置", s=5, c='blue')
plt.scatter(affine_transformation(X, weights_2, bias_0),
            affine_transformation(X, weights_2_1, bias_0),
            label="权重减小", s=5, c='red')
plt.scatter(affine_transformation(X, weights_3, bias_0),
            affine_transformation(X, weights_3_1, bias_0),
            label="权重改变", s=5, c='green')

# 显示图例
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.axis('scaled')  # 保持坐标比例
plt.show()

从图中可以清楚看到,经过变换后,原始的橙色圆会发生旋转、缩放和平移,并变成椭圆。我们在矩形示例中得到的观察结论仍然成立。

5.3.3 仿射变换作用下的科赫分形

再看一个复杂图形的仿射变换示例:科赫分形。

科赫分形(科赫雪花)可以通过旋转、缩放、反射和平移的组合,由一个图形仿射变换为另一个图形。例如,红色雪花可以看作深蓝色雪花的仿射变换。下面给出对科赫分形进行仿射变换的代码。

Python
import matplotlib.pyplot as plt
import numpy as np

def koch_snowflake(order, scale=10):
    """递归生成科赫分形。"""
    if order == 0:
        return np.array([[0, 0], [1, 0], [0.5, np.sqrt(3) / 2], [0, 0]])
    else:
        points = koch_snowflake(order - 1, scale)
        new_points = []
        for i in range(len(points) - 1):
            start, end = points[i], points[i + 1]
            s = start + (end - start) / 3
            e = start + 2 * (end - start) / 3
            angle = np.pi / 3
            m = np.array([[np.cos(angle), -np.sin(angle)],
                          [np.sin(angle), np.cos(angle)]])
            t = s + np.dot(m, (e - s))
            new_points.extend([start, s, t, e])
        new_points.append(points[-1])
        return np.array(new_points)


def affine_transform(points, A, b):
    """对点集应用仿射变换。"""
    return np.dot(points, A.T) + b


# 创建科赫分形
order = 4
original_points = koch_snowflake(order)

# 应用仿射变换
A = np.array([[0.2, 0.1], [-0.3, 0.5]])  # 变换矩阵
b = np.array([0.1, 0.5])  # 偏置向量
transformed_points = affine_transform(original_points, A, b)

# 在同一图中绘制原始分形及其仿射变换结果
plt.figure(figsize=(8, 8))
plt.plot(original_points[:, 0], original_points[:, 1], 'b-', label='原始科赫雪花')
plt.plot(transformed_points[:, 0], transformed_points[:, 1], 'r-', label='仿射变换后的科赫雪花')
plt.title("科赫雪花:原始图形与仿射变换图形")
plt.legend()
plt.show()

5.3.4 关于带有仿射变换的线性预测函数

不要把线性预测函数与仿射变换混淆。从本质上说,它们是同一个假设,只是从不同角度加以观察。

线性预测函数强调的是机器学习模型基于输入特征的线性组合来预测结果的能力。它有助于理解模型如何在特征空间中生成预测,或者换言之,模型如何解释并使用数据。

另一方面,仿射变换是一种数学变换,它包括空间中对象的缩放、平移(或位移)和旋转。在机器学习语境中,仿射变换可用于在数据或特征被模型使用之前对其进行变换。

因此,在特征空间中预测线性函数,也可以看作在仿射空间中执行仿射变换。正因为如此,本书会在许多地方交替使用这两个术语,但需要理解其中细微的视角差异。

5.3.5 仿射变换与激活函数的结合

当由 z(w, b; x) 给出的仿射变换与非线性激活函数结合时,输出值 φ(z) 会被限制在该激活函数的取值范围内,这会导致仿射性质的丧失。不过,这种组合也赋予系统预测非线性关系的能力,因为机器学习中使用的激活函数通常是连续的、平滑的(至少可微),并且随 z 单调变化。

例如,当仿射变换后的图案与 sigmoid 激活函数结合时,结果 φ(z) 会被限制在区间 (0, 1) 内。为了演示机器学习中仿射变换的应用,可以使用如下代码:

Python
import numpy as np
import matplotlib.pyplot as plt

def sigmoid(z):
    return 1. / (1. + np.exp(-z))


def affine_transformation(data, weights, bias):
    return np.dot(data, weights) + bias


def rectangular_pattern(min_x, max_x, min_y, max_y, step, rotation_angle):
    x = np.arange(min_x, max_x + step, step)
    ymin, ymax = np.full(x.shape, min_y), np.full(x.shape, max_y)

    y = np.arange(min_y, max_y + step, step)
    xmin, xmax = np.full(y.shape, min_x), np.full(y.shape, max_x)

    x1 = np.concatenate([x, xmax, np.flip(x), xmin])
    x2 = np.concatenate([ymin, y, ymax, np.flip(y)])
    x1 = np.append(x1, (max_x + min_x) / 2)
    x2 = np.append(x2, (max_y + min_y) / 2)
    X1 = x1 * np.cos(rotation_angle) + x2 * np.sin(rotation_angle)
    X2 = x2 * np.cos(rotation_angle) - x1 * np.sin(rotation_angle)
    X = np.stack((X1, X2), axis=-1)
    return x, y, X


# 定义不同变换所用的权重和偏置
weights_0, weights_0_1, bias_0 = [0., 1.], [1., 0.], 0  # 原始图案
bias_1 = 1  # 改变偏置
weights_2, weights_2_1 = [0., 0.5], [0.5, 0.]  # 减小权重
weights_3, weights_3_1 = [0.5, 0.3], [1.2, 0.1]  # 改变权重

# 生成矩形图案
x, y, X = rectangular_pattern(-1., 1., 1., 3., 0.1, np.pi / 4)

# 创建图形
plt.figure(figsize=(4., 4.), dpi=90)
plt.scatter(sigmoid(affine_transformation(X, weights_0, bias_0)),
            sigmoid(affine_transformation(X, weights_0_1, bias_0)),
            label="原始图案", s=5, c='orange')
plt.scatter(sigmoid(affine_transformation(X, weights_0, bias_1)),
            sigmoid(affine_transformation(X, weights_0_1, bias_1)),
            label="改变偏置", s=5, c='blue')
plt.scatter(sigmoid(affine_transformation(X, weights_2, bias_0)),
            sigmoid(affine_transformation(X, weights_2_1, bias_0)),
            label="权重减小", s=5, c='red')
plt.scatter(sigmoid(affine_transformation(X, weights_3, bias_0)),
            sigmoid(affine_transformation(X, weights_3_1, bias_0)),
            label="权重改变", s=5, c='green')
plt.title('带 sigmoid 的仿射变换')

# 显示图例
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.axis('scaled')  # 保持坐标比例
plt.show()

分析代码与图形可以注意到以下几点。

即使仿射变换与 sigmoid 函数结合,它仍然保持每个点和每条边被唯一变换的性质。这意味着输入数据中的每一个元素(点或边)都对应输出数据中的唯一元素。这种唯一性之所以能够保持,是因为所用的激活函数(这里为 sigmoid)是连续、平滑并且单调变化的。

当应用 sigmoid 函数时,位于同一直线上的点之间的距离比例会发生变化。这意味着点之间的线性关系(仿射性)被破坏。此外,并非所有平行线段在经过 sigmoid 处理后仍保持平行,这表明变换中引入了非线性。

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.3.5 仿射变换与激活函数的结合

不过,正是由于非线性激活函数的作用,输出值 φ(z(ŵ; x)) 会以非线性方式依赖于输入特征 x。这使得此类变换可以用于诸如逻辑回归等任务,通过训练权重 ŵ 对取值为 0 或 1 的标签进行分类。

由于 φ(z(ŵ; x)) 相对于输入特征 x 不是简单线性函数,网络便可以在把该层输出传递到下一层时,对这些输出数据继续施加新的仿射变换。

函数 φ(z(ŵ; x)) 也可以被看作独立于该层所使用权重 ŵ 的新特征表示。这对构建多层神经网络(深度网络)非常重要,因为每个新层都可以使用与前一层不同且相互独立的新权重。

由于 sigmoid 这类非线性激活函数的非线性作用,可以看到明显的形状扭曲。点到点的映射仍然存在,但当 z 接近 0.0 或 1.0 时,由于 sigmoid 曲线在这些区域变得更加平缓,原始点与变换后的点会被“压缩”得更靠近。在 sigmoid 函数梯度接近零的区域,训练过程中调整神经网络的权重 w 与偏置 b 会变得不够有效。这是因为很小的梯度会导致权重和偏置的更新量很小,从而使模型难以被充分校正,尤其是在这些边缘区域中难以实现准确预测或分类。

因此,把 sigmoid 函数加入仿射变换,会为模型引入非线性,使模型更加灵活,并能够处理数据中的复杂关系;但与此同时,它也破坏了输入与输出数据之间的线性关系。

5.4 参数编码与学习的基本机制

5.4.1 从 x 到 ŵ 的编码:数据到参数的转换模块

从预测函数的表达式可以看出,数据集 (x, z) 可以被表示为、或者说“编码”为假设空间中的学习参数 \hat{w}。下面用一个具体例子说明这一思想。设想图中有若干条直线,每一条直线都对应假设空间中的一个点。例如,一条红色直线可以对应于该空间中坐标为 w_0 = 1w_1 = 1 的点。

在机器学习中,一个核心任务是构建能够准确表示或预测数据的模型。这个过程始于确定一组最优参数点,用来反映数据集的特征。这些点就是模型参数,记作 \hat{w}。可以想象,我们拥有一组数据,例如不同形状的直线或模式;模型的任务就是学会准确再现或预测这些形状。

为实现这一目标,我们利用数据集在假设空间中形成一系列点。该空间中的每个点都对应一组特定的模型参数 \hat{w},这些参数决定模型如何解释数据。例如,当处理线性方程时,假设空间中的每个点都代表不同的参数,例如斜率和截距,它们共同确定一条直线。

随后,模型可以基于这些点,也就是参数,来再现或预测数据的行为,例如绘制与原始数据相对应的直线或图形。把数据转换为模型参数,有助于更好地理解并预测数据行为。需要强调的是,原始数据集的规模和质量会直接影响模型在仿射空间中准确表示这些数据的能力。

此外,调节这些参数 \hat{w} 可以得到不同的预测函数。通过改变模型参数,可以让模型的预测结果更接近数据集中的给定标签。参数调节过程就是机器学习中“学习”的本质。虽然真实的机器学习模型可能复杂得多,但这里展示的机制构成了多数学习方法的基础。

因此,在机器学习中,我们并不只是分析数据,而是把数据转换成模型参数,再利用这些参数进行预测或解释。数据到参数的转换以及随后对这些参数的调节,共同构成了机器学习训练过程的核心。

5.4.2 编码的唯一性

我们认为,在 x-z 空间中的一条直线到假设空间中一个点的编码是唯一的。

所谓唯一性,是指 x-z 空间中的每一条直线只对应假设空间中的一个点。为说明这一点,可以考虑 x-z 空间中的任意一条直线。假设这条直线可以由假设空间中的两个不同点表示。根据预测函数方程,这条直线可用两种方式写出:一次由第一组参数给出,另一次由第二组参数给出,并且两个表达式对任意 \bar{x} 都成立。

将这两个表达式相减,可得到它们的差为零。这意味着相应参数之间的差也必须为零,因此两组参数实际上相同。这就证明了直线到假设空间中点的映射具有唯一性。

反过来也可以讨论唯一性。假设我们在假设空间中给定一个点,并希望判断它是否只对应 x-z 空间中的唯一一条直线。由这个点出发,似乎可以尝试构造两条不同的直线。然而,利用同样的方程和相同的推理可以发现,由假设空间中同一个点构造出的任意两条直线实际上是同一条直线。两条直线之差为零,说明它们完全一致。

这些论证说明了编码的唯一性。由斜率和偏置定义的直线由参数 \hat{w} 唯一确定,这对数据的正确编码十分重要。唯一性保证了数据集能够在仿射变换假设下被有效表示和解释,从而使机器学习模型能够可靠地从这些数据中学习。

5.4.3 编码的唯一性:与激活函数无关

需要注意的是,对仿射变换施加激活函数并不会破坏编码的唯一性。这与激活函数的性质有关。

神经网络中常用的激活函数通常是严格单调的。这意味着它们始终保持单调增加或单调减少,而不会同时出现两种趋势。单调性保证了输入数据的顺序在应用激活函数之后仍然得到保持。因此,如果两个不同输入在仿射变换中对应于不同的表示,那么在施加单调激活函数之后,它们仍然保持可区分的表示。由此,编码唯一性的特征不会丢失。

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.4.3 编码的唯一性:与激活函数无关

因此,对激活函数有一个关键要求:它们应当是单调的。本教材中讨论的激活函数都满足这一要求,从而保证仿射变换即使经过激活函数修饰后,仍能保持编码的唯一性。

5.5 预测函数的梯度

预测函数的梯度说明了当学习参数发生变化时,预测函数如何变化。这些学习参数包括权重 w 和偏置 b。这些参数的梯度可以用较简单的公式表示。

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.5 预测函数的梯度

关于权重的梯度表明,预测函数对权重的梯度与特征变量 x 成正比。也就是说,某个特征对预测结果的影响越大,与该特征相关的权重梯度也越大。

关于偏置的梯度恒等于一。这是因为在机器学习方程中,偏置常被表示为一个附加特征 x_0,其取值恒为 1。因此,偏置的变化以单位尺度影响预测结果,并且不依赖于其他因素。

在使用正则化技术时,可以为权重和偏置选择不同的正则化参数。正则化是一种防止模型过拟合的方法,它通过对较大的权重在损失函数中加入惩罚项来实现。由于权重梯度和偏置梯度具有不同性质,可以对这些参数采用不同的正则化策略。

当采用 xw 形式时,可得到相应的梯度表达式,这些表达式可用于机器学习训练过程中的自动微分。

5.6 仿射变换阵列(ATA)

这一概念描述的是一种网络结构,其中输出层的每个神经元都与输入层的每个神经元相连接。这种结构也称为全连接网络或稠密连接网络。在这种网络中,一个神经元沿垂直方向复制 k 次,从而形成输入神经元与输出神经元之间的复杂连接结构,使网络能够实现从具有 p 个特征的空间到具有 k 个输出的空间的映射。

ATA 网络中的预测函数可以用一个特殊方程表示:

\[ Z(\hat{w}; x) \]

其中,z 表示预测函数向量。该向量中的每个元素 z_j 都表示与相应输出神经元对应的一个独立预测函数。

在该模型中,\hat{w}_j 表示输出层第 j 个神经元的学习参数向量,包括权重和偏置。这里,偏置被作为附加参数并入权重向量中,从而简化数学计算。\hat{W} 是将输出层中每个神经元的学习参数向量组合起来的矩阵。它由权重矩阵 W 和偏置向量 b 组成,尺寸为 (p + 1) \times k

当考虑 ATA 的完整学习参数向量时,它由 k 个神经元各自的学习参数向量共同组成。这个向量可以被看作矩阵 \hat{W} 的“展平”形式。这类系统中的学习参数总数为

\[ P = (p + 1) \times k, \]

这说明 ATA 网络中的假设空间维度会迅速增加。

方程

\[ Z(\hat{w}; x) = xW + b = \bar{x}\hat{W} \]

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.6 仿射变换阵列(ATA)

是仿射变换的矩阵形式。它说明每个预测函数 z_j 都通过各自唯一的权重和偏置独立计算。这保证了各个预测函数之间的独立性,在使用具有 p 个特征的数据集解决多维回归问题时,这是一个重要特性。

5.7 深层网络高阶函数的可预测性

5.7.1 激活函数的作用

在构建深度神经网络时,初始步骤是堆叠一组预测函数,随后使用非线性激活函数对这些预测函数进行修饰。这种变换会生成一组新的特征,可记为新的特征变量。这些新特征的特点是与原始特征线性无关。也就是说,它们提供了原始数据中不存在的独特信息。随后,这些新特征作为下一层神经网络的输入,从而为下一层引入新的学习参数集合。

由于激活函数具有非线性,仿射变换阵列(ATA)每一层的输出可以与前一层 ATA 的输出保持线性无关。这种独立性非常关键,因为它使每一个后续 ATA 层都能够以比线性相关输出更复杂的方式处理数据。通过这种逐层添加结构,就形成了深度神经网络。

经过这样一个多层过程,每一层都可看作一组仿射变换并配以非线性激活函数,最终形成极其复杂的深度神经网络。由此产生的预测函数能够在更深层次上处理和分析数据。

此外,根据对预测函数所采用变换的不同,还可以为不同任务设计不同类型的神经网络。例如,把仿射变换替换为空间滤波器,可以构造卷积神经网络(CNN),它们常用于目标检测。类似地,使用时间滤波器可以构造循环神经网络(RNN),适用于时间序列分析。这说明深度神经网络在解决各种机器学习任务时具有高度灵活性和强大能力。

5.7.2 通过组合 ATA 构建深度网络

本节讨论如何把由前一层得到的新特征作为深度神经网络后续层的输入。为便于说明,考虑一个简单的 4-2-3 深度神经网络,其中数字表示每一层神经元的数量。

这里用括号中的数字表示层编号。

第一层(2 个神经元):

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.7.2 通过组合 ATA 构建深度网络

输入数据为 4 个相互独立的特征 x_i,其中 i = 1,\dots,4。该层执行两个仿射变换,对应于两个输出神经元。它们使用尺寸为 4 \times 2 的权重矩阵和相应的偏置向量。每个变换都拥有自己的权重集合和偏置。

经过仿射变换之后,两个输出再通过非线性激活函数 \varphi,从而产生两个新特征。这些新特征非线性地依赖于原始输入数据。

第二层(3 个神经元):

第一层得到的两个特征作为输入,进入第二层的三个仿射变换。这里使用尺寸为 2 \times 3 的权重矩阵和包含三个分量的偏置向量。经过该层仿射变换后,数据还可以继续通过非线性激活函数,从而完成第二层的构造。

上述过程可以对更多层重复进行,从而增加神经网络深度。每一层中的神经元数量可以根据需要变化。

假设空间通过堆叠和组合而增大:堆叠会以乘法方式提高维度,而组合会以加法方式增加维度。

在深度神经网络中,预测函数可能位于极高维的假设空间中。对于这个简单的 4-2-3 深度网络,假设空间维数为

\[ P = (4 \times 2 + 2) + (2 \times 3 + 3) = 19. \]

一般地,对于 p-q-r-k 网络,总参数数目由各层权重和偏置的数量相加得到。

多层感知机(MLP)中所有可训练参数的向量可以写为各层权重矩阵和偏置向量展平后再拼接得到的向量,其中隐藏层总数决定了该向量的整体维度。

.flatten() 是 Python 编程语言中的一个方法,通常用于数组或矩阵,尤其是 NumPy 数组对象。该方法会把多维数组“拉直”为一维数组。换言之,它把任意维度数组中的所有元素按顺序展开为一个“扁平”的一维数组。

需要指出的是,实际计算中不一定真的执行上述“展平”操作。这里这样写主要是为了说明假设空间维度如何增长。在真实计算中,可以把这些参数简单地组织在 Python 列表中,并使用 autograd 算法在训练 MLP 时自动完成所需的前向和反向计算。高维空间中的计算通常以数值方式进行。

5.7.3 示例:网络 1 → 1 → 1

考虑最简单的神经网络结构 1 \to 1 \to 1。该网络由三层组成,每层只有一个神经元。对这个模型,我们采用与前文方程类似的线性预测函数,并在隐藏层和最后一层中都使用 sigmoid 激活函数。

网络从第一层开始工作,输入信号 x 可以归一化到 [-1, 1] 范围内,然后通过 sigmoid 激活函数。该过程可以由相应方程表示。该层的输出再传递给下一层。

在第二层,也就是隐藏层中,发生类似的变换过程。该层的输出就是网络的输出结果。

为了更准确地理解网络工作方式,可以对 sigmoid 激活函数使用泰勒展开。这样可以把网络输出近似表示为输入 x 的三阶多项式。该表示说明了网络输出如何依赖神经元中的权重系数和偏置。多项式中的常数可以通过使用数据集拟合,也就是训练网络的权重和偏置来确定。

这一分析表明,结构为 1 \to 1 \to 1 的神经网络能够近似模拟三阶函数。相比之下,更简单的 1 \to 1 网络只能受限于一阶函数。增加一个额外层可以改善网络的预测能力。

类似原理也可用于其他类型的激活函数。通过泰勒展开,可以在截断高阶项的情况下近似更高阶函数。

这说明增加神经网络层数能够让网络模拟更复杂的非线性行为。这也是深度神经网络被视为强大工具的原因之一,尤其是在它们能够被有效训练时。

最后,增加神经网络深度可以类比为在基于物理规律的模型中提高形函数阶数,例如有限元法或无网格方法中的高阶近似。同时,增加某一层中的神经元数量,则类似于在这些物理模型中增加单元或节点数量。

5.8 通用预测理论

通用预测理论讨论深度神经网络如何被构造并用于解决复杂预测问题。这些网络具有一些独特性质,使它们在机器学习和人工智能领域非常强大。

首先,线性预测函数,也就是仿射变换,能够精确模拟任意一阶函数。这意味着网络中的每个神经元都可以有效处理输入数据,并对这些数据执行唯一的变换,无论是否使用激活函数。

其次,各个神经元的逼近函数,也就是仿射变换,彼此独立。这种性质通过 ATA 中的独立连接实现,使每个神经元能够独立处理信息,并为网络整体输出作出贡献。

第三,深层网络的每一层都通过非线性激活函数产生新的独立特征。这使深度网络能够提取并处理数据中复杂而不明显的性质,对于复杂任务尤其重要。

第四,深度网络通过把仿射变换与非线性激活函数串联起来,能够预测任意高阶的复杂非线性函数。这使深度网络可以逼近和模拟复杂系统的行为,因此在许多领域中都不可替代。

这些性质解释了为什么不同类型的深度网络能够从输入特征到数据中存在的目标标签建立复杂映射。通用预测理论的核心观点是:只要深度网络具有足够数量的层和神经元,并配备非线性激活函数,在正确训练的条件下,它就可以被调节为能够预测数据中的隐藏特征。

然而,要实现这种能力,需要采用一系列技术。必须为具体任务类型确定合适的深度网络结构,并找到最优学习参数。训练后模型的质量和适用性还依赖于数据集质量,包括数据集对所建模问题的代表性、正确性、规模、数据点在特征空间中的分布以及噪声水平。

因此,通用预测理论强调了深度神经网络解决复杂问题的潜力,并确认它们在现代人工智能中的重要性和有效性。

5.9 非线性仿射变换

需要注意的是,在上述公式中,特征 x_ii = 1,2,\dots,p,作为线性基函数用于仿射变换。然而,这些基函数也可以是非线性的。以一维问题为例,在线性逼近情况下,特征向量可以写为包含常数项和原始特征的形式,这是最简单的特征表示。

当进行二阶逼近时,也常称为非线性回归,特征向量会扩展为包含二次项的形式。这样可以把平方项纳入模型,从而增强模型描述更复杂关系的能力。

此外,如果已知某个函数可作为有用的基函数,也可以把它加入特征向量。例如,如果认为某个函数 f(x) 对建模数据很重要,就可以把它作为特征向量中的一个分量。

这种把非线性函数用作特征基的做法,也与支持向量机(SVM)的概念有关。在 SVM 中,核函数用于处理线性不可分的类别。这些非线性特征基或核有时也称为特征函数。

在神经网络模型中,高阶基函数和加富函数可以用于更高维空间。例如,在二维空间中,特征不仅可以包括线性项和二次项,还可以包括混合项,例如 xy,以及其他非线性函数。

重要的是,在处理高维问题时,包含非线性基的特征空间可能会达到极高维度。在这种情况下,所谓“核技巧”可能很有用,它可以避免显式地把维度扩展到过大。该方法能够在降低特征空间维度膨胀风险的同时,高效处理非线性特征。

5.10 基于物理规律模型中的特征函数

在基于物理规律的模型中,特征函数的选择具有特殊重要性。特征函数也称为基函数,是用来模拟物理现象的工具。它们可用于表示位移、应力、速度、压力等场变量,而这些变量受物理规律支配。这说明,无论基本物理规律以强形式还是弱形式出现,都可以借助这些基函数得到合适的表示与逼近。

这一方法最常见的应用之一是有限元法。在有限元法中,常使用高阶多项式基函数。这些函数能够更准确地表示物理变量,从而更精确地模拟物理过程。在平滑有限元方法中,也使用基函数,但它们会通过所谓加富函数得到扩展。例如,为了描述空间某些区域中具有奇异性的应力场,可以把相应的加富函数加入基函数集合中。

在无网格方法中,例如径向基函数(RBF)方法,通常使用基于距离的基函数。这使得物理过程能够在没有显式网格的空间中建模。当传统网格方法效率较低或使用不便时,这一点尤其重要。

在线性力学等由物理规律控制的问题中,常使用高阶基函数和特殊基函数,以便更准确地描述系统行为。尽管所得系统方程相对于场变量仍然是线性的,但使用这些复杂特征函数能够捕捉系统所需的关键特征。这印证了一个基本原则:为了恰当地表示系统特征,无论这些特征是由物理规律显式给出的,还是隐藏在数据之中,都需要使用复杂程度合适的特征函数或基函数。因此,即使模型相对于场变量仍保持线性,复杂特征函数的使用也能显著提高物理过程建模的精度和适当性。

教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.10 基于物理规律模型中的特征函数
教材插图:预测函数与通用预测理论
教材插图:预测函数与通用预测理论 — 5.10 基于物理规律模型中的特征函数

自测

哪一项最能概括“预测函数与通用预测理论”这一章的重点?

在机器学习中,理论定义需要通过数值示例和可视化进行检验。

哪些做法有助于巩固本章内容?

参加测试