AI 数学课程 · 第 3 课,共 180

定义域与陪域:每个 AI 函数都需要的输入契约

学习定义域和陪域如何规定有效的模型输入与承诺的输出类型,然后诊断形状、范围和未定义运算导致的失败。

分享这篇文章

第 2 课把函数描述为一条为每个允许输入指定一个输出的规则。“允许”一词的分量比初看起来更重。

如果文本分类器期待词元 ID,就不能安全地接收任意字节块。矩阵乘法不能接受不兼容的形状。对负输入取对数不能产生实数值。规则只是函数契约的一部分;有效输入集合和承诺的输出集合是另外两部分。

学完本课后,你将能够连同定义域和陪域写出函数,区分陪域与实际到达的值,并把常见的 AI 输入失败解释为违反数学契约。

箭头携带类型信息

一个简洁的函数声明如下:

f:AB.f:A\to B.

读作“ffAA 映射到 BB”。

  • AA定义域,即允许的输入集合。
  • BB陪域,即承诺所有输出都属于其中的集合。
  • 规则告诉我们,AA 的每个元素被分配到 BB 的哪个元素。

记号 xAx\in A 表示“xxAA 的一个元素”。它让我们可以把契约和计算写在一起:

xAf(x)B.x\in A \quad\Longrightarrow\quad f(x)\in B.
函数承诺把允许的输入集合映射到输出集合,但并不承诺每个输出都会实际出现。
定义域、函数与陪域映射三个有效的数值特征输入通过风险分数函数,映射为零到一之间的输出。一个文本输入位于定义域之外,因此在计算前被拒绝。定义域0.10.50.9riskScoref(x)陪域 [0, 1]0.180.500.82“high” 位于定义域之外
映射图的文本替代说明
输入有效?输出
0.10.18
0.50.50
0.90.82
“high”否——输入类型错误未计算

图中的文本输入 “high” 并不是失败的数值预测。它不是这个数值函数允许的输入,因此不应开始计算。

陪域是承诺,而不是观察到的输出列表

考虑实数上的平方函数:

q:RR,q(x)=x2.q:\mathbb{R}\to\mathbb{R}, \qquad q(x)=x^2.

这里的 R\mathbb{R} 表示实数集合。每个实数输入都可以平方,结果也都是实数,所以这个声明有效。

q(x)q(x) 从不会为负。函数实际到达的值集合是

[0,)={yR:y0}.[0,\infty)=\{y\in\mathbb{R}:y\ge 0\}.

这个到达集合称为值域。它可以小于声明的陪域。

概念对于 q:RRq:\mathbb{R}\to\mathbb{R}q(x)=x2q(x)=x^2
定义域所有实数
陪域所有实数
非负实数

改变定义域可以修复未定义的规则

表达式

r(x)=1xr(x)=\frac{1}{x}

x=0x=0 时没有定义实数输出。我们可以排除零来声明有效函数:

r:R{0}R,r(x)=1x.r:\mathbb{R}\setminus\{0\}\to\mathbb{R}, \qquad r(x)=\frac{1}{x}.

符号 \setminus 表示集合差。定义域就是“不含零的实数”。同样,

(x)=logx\ell(x)=\log x

的实值定义域限制为正输入:

:(0,)R.\ell:(0,\infty)\to\mathbb{R}.

这些不是吹毛求疵的装饰,而是在告诉实现:计算前必须检查什么。

AI 定义域还包括形状和结构

到目前为止,定义域看起来像数字区间。模型输入通常是向量或矩阵,它们的形状也属于契约。

f:R3R2.f:\mathbb{R}^3\to\mathbb{R}^2.

记号 R3\mathbb{R}^3 表示由三个实坐标组成的有序列表,R2\mathbb{R}^2 表示由两个实坐标组成的有序列表。一个有效输入是

x=[0.21.03.4].x=\begin{bmatrix}0.2\\-1.0\\3.4\end{bmatrix}.

含两个坐标的向量不在声明的定义域内。它的各个元素都可能是实数,但对象的形状错误。

这就是常见张量错误的数学版本:

def project_three_features(x):
    if x.shape != (3,):
        raise ValueError("expected exactly three features")
    return [x[0] + x[1], x[2] - x[1]]

这个检查保护了定义域。函数返回两个数字,与陪域的形状相符。

对于基于词元的模型,完整定义域还可能更加严格。输入可能需要:

  • 整数词元 ID,而不是任意实数;
  • 位于固定词表范围内的 ID;
  • 最大序列长度;
  • 相互一致的批次形状与注意力掩码形状;以及
  • 该模型所要求的图像、音频或文本编码。

说“模型接受一个张量”会隐藏这些约束。好的数学接口和软件接口会把它们显露出来。

输出承诺会约束下游代码

假设一个分类器声明为

c:Rd[0,1]K.c:\mathbb{R}^{d}\to[0,1]^K.

它接受 dd 个实特征,并返回 KK 个介于零和一之间的数字。仅凭这个陪域,不能保证 KK 个数字的和为一。如果预期输出是 KK 个互斥类别上的概率分布,陪域需要额外条件:

ΔK1={p[0,1]K:k=1Kpk=1}.\Delta^{K-1} = \left\{ p\in[0,1]^K: \sum_{k=1}^{K}p_k=1 \right\}.

这个集合称为概率单纯形。我们稍后会学习它。现在只需注意,更丰富的陪域如何向下游代码传达更强的承诺。

阅读模型函数的检查清单

遇到新的数学映射时,问自己四个问题:

  1. 哪些对象属于定义域?
  2. 哪些对象被明确排除或未定义?
  3. 陪域承诺了什么输出集合?
  4. 规则是否实际到达整个陪域,还是只到达更小的像?

这些问题能把许多模糊的“形状不匹配”“无效概率”和“未定义损失”错误变成精确的契约违反。下一课将使用集合来更系统地描述数据集合和事件。

检查你的理解

问题 1

对于声明为 q: R → R 的 q(x) = x²,指出定义域、陪域和像。

显示分步解答

声明说明定义域是 R\mathbb{R},陪域也是 R\mathbb{R}。任意实数输入都可以计算平方,并返回实数。

由于对每个实数 xx 都有 x20x^2\ge 0,实际到达的值恰好是非负实数:

image(q)=[0,).\operatorname{image}(q)=[0,\infty).

因此,像是陪域的真子集。

问题 2

为什么 0 不在 r(x) = 1/x 的实值定义域内?

显示分步解答

代入零要求计算

r(0)=10.r(0)=\frac{1}{0}.

不存在满足 0y=10\cdot y=1 的实数 yy,所以这个除法没有实值。正确的声明排除零:

r:R{0}R.r:\mathbb{R}\setminus\{0\}\to\mathbb{R}.

问题 3

一个函数期待 R³ 的元素。如果 [1, 2] 的两个元素都是实数,它有效吗?请解释。

显示分步解答

属于 R3\mathbb{R}^3 要求恰好三个有序实坐标。向量 [1,2][1,2] 属于 R2\mathbb{R}^2,而不是 R3\mathbb{R}^3

单个值的类型正确,但形状不正确。值类型和形状都是定义域契约的一部分。

问题 4

分类器返回 [0.6, 0.6]。每个元素都在 [0, 1] 内。为什么它仍可能违反陪域?

显示分步解答

如果分类器只承诺 [0,1]2[0,1]^2,这个向量满足较弱的契约。但如果它承诺两个互斥类别上的概率分布,数值的和还必须为一。

这里 0.6+0.6=1.210.6+0.6=1.2\ne1,所以该向量不在概率单纯形内。是否违反陪域取决于实际声明了哪一个输出集合。

问题 5

某实现把 log(p) 替换为 log(max(p, 0.000001))。它是否对每个实数 p 计算完全相同的函数?

显示分步解答

不是。对于 p0.000001p\ge0.000001,两个表达式相同;对于更小的正 pp,截断实现返回常数 log(0.000001)\log(0.000001),而不是 logp\log p。对于零或负 pp,它还会在原始实对数未定义的地方产生有限值。

截断可以是有意的数值保护措施,但它会改变一致区域之外的函数。精确的解释应说明这个约定及其原因。

资料来源

  1. Mathematics for Machine Learning companion website
  2. Mathematics for Machine Learning book PDF