动手学深度学习4.9 环境和分布偏移-笔记&练习(PyTorch)

本节教材地址:4.9. 环境和分布偏移 — 动手学深度学习 2.0.0 documentation (d2l.ai)

本节开源代码:...>d2l-zh>pytorch>chapter_multilayer-perceptrons>environment.ipynb


环境和分布偏移

前面我们学习了许多机器学习的实际应用,将模型拟合各种数据集。 然而,我们从来没有想过数据最初从哪里来?以及我们计划最终如何处理模型的输出? 通常情况下,开发人员会拥有一些数据且急于开发模型,而不关注这些基本问题。

许多失败的机器学习部署(即实际应用)都可以追究到这种方式。 有时,根据测试集的精度衡量,模型表现得非常出色。 但是当数据分布突然改变时,模型在部署中会出现灾难性的失败。 更隐蔽的是,有时模型的部署本身就是扰乱数据分布的催化剂。 举一个有点荒谬却可能真实存在的例子。 假设我们训练了一个贷款申请人违约风险模型,用来预测谁将偿还贷款或违约。 这个模型发现申请人的鞋子与违约风险相关(穿牛津鞋申请人会偿还,穿运动鞋申请人会违约)。 此后,这个模型可能倾向于向所有穿着牛津鞋的申请人发放贷款,并拒绝所有穿着运动鞋的申请人。

这种情况可能会带来灾难性的后果。 首先,一旦模型开始根据鞋类做出决定,顾客就会理解并改变他们的行为。 不久,所有的申请者都会穿牛津鞋,而信用度却没有相应的提高。 总而言之,机器学习的许多应用中都存在类似的问题: 通过将基于模型的决策引入环境,我们可能会破坏模型。

虽然我们不可能在一节中讨论全部的问题,但我们希望揭示一些常见的问题, 并激发批判性思考,以便及早发现这些情况,减轻灾难性的损害。 有些解决方案很简单(要求“正确”的数据),有些在技术上很困难(实施强化学习系统), 还有一些解决方案要求我们完全跳出统计预测,解决一些棘手的、与算法伦理应用有关的哲学问题。

分布偏移的类型

首先,我们考虑数据分布可能发生变化的各种方式,以及为挽救模型性能可能采取的措施。 在一个经典的情景中,假设训练数据是从某个分布 p_S(\mathbf{x},y) 中采样的, 但是测试数据将包含从不同分布 p_T(\mathbf{x},y) 中抽取的未标记样本。 一个清醒的现实是:如果没有任何关于 p_S 和 p_T 之间相互关系的假设, 学习到一个分类器是不可能的。

考虑一个二元分类问题:区分狗和猫。 如果分布可以以任意方式偏移,那么我们的情景允许病态的情况, 即输入的分布保持不变:p_S(\mathbf{x}) = p_T(\mathbf{x}) , 但标签全部翻转: p_S(y | \mathbf{x}) = 1 - p_T(y | \mathbf{x}) 。 换言之,如果将来所有的“猫”现在都是狗,而我们以前所说的“狗”现在是猫。 而此时输入 p(\mathbf{x}) 的分布没有任何改变, 那么我们就不可能将这种情景与分布完全没有变化的情景区分开。


补充

以上问题涉及到领域自适应(domain adaptation)中的一种情况,即标签转置的情况。在这种情况下,虽然输入的分布保持不变,但标签的分布发生了变化,使得原本属于一个类别的样本现在被误标为另一个类别。

在这样的情况下,传统的分类器在源领域上学到的模型可能无法很好地泛化到目标领域。因为在目标领域中,狗和猫的标签发生了翻转,原先的分类决策边界可能无法正确地区分新的标签分布。实际上,对于任何分类模型而言,只依赖于输入的分布是不够的,而必须考虑样本标签的分布信息。

要解决这个问题,可以尝试使用领域自适应的方法,如迁移学习或对抗性训练等技术,通过尽量减小源域和目标域之间的分布差异,来提高模型在目标域上的性能。另外,一些特定的领域自适应方法,如在神经网络中使用对抗性训练或领域分类器,也可以应对标签转置的情况,提高模型的泛化能力。


幸运的是,在对未来我们的数据可能发生变化的一些限制性假设下, 有些算法可以检测这种偏移,甚至可以动态调整,提高原始分类器的精度。

协变量偏移

在不同分布偏移中,协变量偏移可能是最为广泛研究的。 这里我们假设:虽然输入的分布可能随时间而改变, 但标签函数(即条件分布 P(y \mid \mathbf{x}) )没有改变。 统计学家称之为协变量偏移(covariate shift), 因为这个问题是由于协变量(特征)分布的变化而产生的。 虽然有时我们可以在不引用因果关系的情况下对分布偏移进行推断, 但在我们认为 \mathbf{x} 导致 y 的情况下,协变量偏移是一种自然假设。

考虑一下区分猫和狗的问题:训练数据包括 下图中的图像。

在测试时,我们被要求对 下图 中的图像进行分类。

训练集由真实照片组成,而测试集只包含卡通图片。 假设在一个与测试集的特征有着本质不同的数据集上进行训练, 如果没有方法来适应新的领域,可能会有麻烦。


补充

协变量偏移发生在当输入数据的特征分布在源域和目标域之间有所不同的情况下。在这种情况下,虽然输出标签的分布可能是相似的,但输入特征的分布却存在差异。这种差异可能导致在源域上训练的模型不能直接应用到目标域上,因为模型在源域上学到的特征分布信息可能无法很好地适应目标域的数据。就像上文中举的例子,训练数据(源域)是真实猫狗图像,而测试数据(目标域)是卡通猫狗图像。


标签偏移

标签偏移(label shift)描述了与协变量偏移相反的问题。 这里我们假设标签边缘概率 P(y) 可以改变, 但是类别条件分布 P(\mathbf{x} \mid y) 在不同的领域之间保持不变。 当我们认为 y 导致 \mathbf{x} 时,标签偏移是一个合理的假设。 例如,预测患者的疾病,我们可能根据症状来判断, 即使疾病的相对流行率随着时间的推移而变化。 标签偏移在这里是恰当的假设,因为疾病会引起症状。 在另一些情况下,标签偏移和协变量偏移假设可以同时成立。 例如,当标签是确定的,即使 y 导致 \mathbf{x} ,协变量偏移假设也会得到满足。 有趣的是,在这些情况下,使用基于标签偏移假设的方法通常是有利的。 这是因为这些方法倾向于包含看起来像标签(通常是低维)的对象, 而不是像输入(通常是高维的)对象。


补充

标签偏移发生在不同领域中相同样本的标签不同的情况下。在这种情况下,虽然输入数据的分布可能是相似的,但输出标签的分布却存在差异。这种差异可能使得在源域上训练的模型不能直接应用到目标域上,因为源域上学到的标签分布信息可能无法很好地适应目标域的真实标签。

对于上文中提到的例子,可以理解为,当根据症状预测疾病时,因为在不同时期的数据集中,同一个症状可能对应不同的疾病,或者同一个疾病在不同时期表现的症状可能也会有所不同,所以会导致同一个症状在不同时期对应的疾病类型发生变化,即标签的分布会发生偏移。这种情况下,如果我们直接在过去的数据集上训练模型,并将其应用到现在的数据上,由于疾病的相对流行率和症状的表现可能已经发生变化,模型的性能会受到影响。


概念偏移

我们也可能会遇到概念偏移(concept shift): 当标签的定义发生变化时,就会出现这种问题。 这听起来很奇怪——一只猫就是一只猫,不是吗? 然而,其他类别会随着不同时间的用法而发生变化。 精神疾病的诊断标准、所谓的时髦、以及工作头衔等等,都是概念偏移的日常映射。 事实证明,假如我们环游美国,根据所在的地理位置改变我们的数据来源, 我们会发现关于“软饮”名称的分布发生了相当大的概念偏移, 如 下图 所示。

如果我们要建立一个机器翻译系统, P(y \mid \mathbf{x}) 的分布可能会因我们的位置不同而得到不同的翻译。 这个问题可能很难被发现。 所以,我们最好可以利用在时间或空间上逐渐发生偏移的知识。

分布偏移示例

在深入研究形式体系和算法之前,我们可以讨论一些协变量偏移或概念偏移可能并不明显的具体情况。

医学诊断

假设我们想设计一个检测癌症的算法,从健康人和病人那里收集数据,然后训练算法。 它工作得很好,有很高的精度,然后我们得出了已经准备好在医疗诊断上取得成功的结论。 请先别着急。

收集训练数据的分布和在实际中遇到的数据分布可能有很大的不同。 这件事在一个不幸的初创公司身上发生过,我们中的一些作者几年前和他们合作过。 他们正在研究一种血液检测方法,主要针对一种影响老年男性的疾病, 并希望利用他们从病人身上采集的血液样本进行研究。 然而,从健康男性身上获取血样比从系统中已有的病人身上获取要困难得多。 作为补偿,这家初创公司向一所大学校园内的学生征集献血,作为开发测试的健康对照样本。 然后这家初创公司问我们是否可以帮助他们建立一个用于检测疾病的分类器。

正如我们向他们解释的那样,用近乎完美的精度来区分健康和患病人群确实很容易。 然而,这可能是因为受试者在年龄、激素水平、体力活动、 饮食、饮酒以及其他许多与疾病无关的因素上存在差异。 这对检测疾病的分类器可能并不适用。 这些抽样可能会遇到极端的协变量偏移。 此外,这种情况不太可能通过常规方法加以纠正。 简言之,他们浪费了一大笔钱。

自动驾驶汽车

对于一家想利用机器学习来开发自动驾驶汽车的公司,一个关键部件是“路沿检测器”。 由于真实的注释数据获取成本很高,他们想出了一个“聪明”的想法: 将游戏渲染引擎中的合成数据用作额外的训练数据。 这对从渲染引擎中抽取的“测试数据”非常有效,但应用在一辆真正的汽车里真是一场灾难。 正如事实证明的那样,路沿被渲染成一种非常简单的纹理。 更重要的是,所有的路沿都被渲染成了相同的纹理,路沿检测器很快就学习到了这个“特征”。

当美军第一次试图在森林中探测坦克时,也发生了类似的事情。 他们在没有坦克的情况下拍摄了森林的航拍照片,然后把坦克开进森林,拍摄了另一组照片。 使用这两组数据训练的分类器似乎工作得很好。 不幸的是,分类器仅仅学会了如何区分有阴影的树和没有阴影的树: 第一组照片是在清晨拍摄的,而第二组是在中午拍摄的。

非平稳分布

当分布变化缓慢并且模型没有得到充分更新时,就会出现更微妙的情况: 非平稳分布(nonstationary distribution)。 以下是一些典型例子:

  • 训练一个计算广告模型,但却没有经常更新(例如,一个2009年训练的模型不知道一个叫iPad的不知名新设备刚刚上市);
  • 建立一个垃圾邮件过滤器,它能很好地检测到所有垃圾邮件。但是,垃圾邮件发送者们变得聪明起来,制造出新的信息,看起来不像我们以前见过的任何垃圾邮件;
  • 建立一个产品推荐系统,它在整个冬天都有效,但圣诞节过后很久还会继续推荐圣诞帽。

更多轶事

  • 建立一个人脸检测器,它在所有基准测试中都能很好地工作,但是它在测试数据上失败了:有问题的例子是人脸充满了整个图像的特写镜头(训练集中没有这样的数据)。
  • 为美国市场建立了一个网络搜索引擎,并希望将其部署到英国。
  • 通过在一个大的数据集来训练图像分类器,其中每一个大类的数量在数据集近乎是平均的,比如1000个类别,每个类别由1000个图像表示。但是将该系统部署到真实世界中,照片的实际标签分布显然是不均匀的。

分布偏移纠正

正如我们所讨论的,在许多情况下训练和测试分布 P(\mathbf{x}, y) 是不同的。 在一些情况下,我们很幸运,不管协变量、标签或概念如何发生偏移,模型都能正常工作。 在另一些情况下,我们可以通过运用策略来应对这种偏移,从而做得更好。 本节的其余部分将着重于应对这种偏移的技术细节。

经验风险与实际风险

首先我们反思一下在模型训练期间到底发生了什么? 训练数据{(\mathbf{x}_1, y_1), \ldots, (\mathbf{x}_n, y_n)}的特征和相关的标签经过迭代,在每一个小批量之后更新模型 𝑓 的参数。 为了简单起见,我们不考虑正则化,因此极大地降低了训练损失:

\mathop{\mathrm{minimize}}_f \frac{1}{n} \sum_{i=1}^n l(f(\mathbf{x}_i), y_i), (4.9.1)

其中 l 是损失函数,用来度量: 给定标签 y_i ,预测 f(\mathbf{x}_i) 的“糟糕程度”。 统计学家称 上式 中的这一项为经验风险。 经验风险(empirical risk)是为了近似 真实风险(true risk), 整个训练数据上的平均损失,即从其真实分布 p(\mathbf{x},y) 中 抽取的所有数据的总体损失的期望值:

E_{p(\mathbf{x}, y)} [l(f(\mathbf{x}), y)] = \int\int l(f(\mathbf{x}), y) p(\mathbf{x}, y) \;d\mathbf{x}dy. (4.9.2)

然而在实践中,我们通常无法获得总体数据。 因此,经验风险最小化即在 (4.9.1) 中最小化经验风险, 是一种实用的机器学习策略,希望能近似最小化真实风险。


补充

经验风险最小化(Empirical Risk Minimization,ERM)旨在通过最小化模型在训练集上的平均损失来选择最优的模型参数。在实践中,经验风险最小化通常会结合正则化等技术来避免过拟合问题,以提高模型的泛化能力。通过在训练集上最小化经验风险,并在损失函数中加入正则化项来惩罚模型复杂度,可以使得模型更好地适应未见过的测试数据,并避免在训练集上出现过度拟合的情况。


协变量偏移纠正

假设对于带标签的数据 (\mathbf{x}_i, y_i) , 我们要评估P(y \mid \mathbf{x}) 。 然而观测值 \mathbf{x}_i 是从某些源分布 q(\mathbf{x}) 中得出的, 而不是从目标分布 p(\mathbf{x}) 中得出的。 幸运的是,依赖性假设意味着条件分布保持不变,即: p(y \mid \mathbf{x}) = q(y \mid \mathbf{x}) 。 如果源分布 q(\mathbf{x}) 是“错误的”, 我们可以通过在真实风险的计算中,使用以下简单的恒等式来进行纠正:

\begin{aligned} \int\int l(f(\mathbf{x}), y) p(y \mid \mathbf{x})p(\mathbf{x}) \;d\mathbf{x}dy = \int\int l(f(\mathbf{x}), y) q(y \mid \mathbf{x})q(\mathbf{x})\frac{p(\mathbf{x})}{q(\mathbf{x})} \;d\mathbf{x}dy. \end{aligned}

换句话说,我们需要根据数据来自正确分布与来自错误分布的概率之比, 来重新衡量每个数据样本的权重:

\beta_i \stackrel{\mathrm{def}}{=} \frac{p(\mathbf{x}_i)}{q(\mathbf{x}_i)}, q(\mathbf{x}_i) \neq 0.

将权重 \beta_i 代入到每个数据样本 (\mathbf{x}_i, y_i) 中, 我们可以使用”加权经验风险最小化“来训练模型:

\mathop{\mathrm{minimize}}_f \frac{1}{n} \sum_{i=1}^n \beta_i l(f(\mathbf{x}_i), y_i). (4.9.5)

由于不知道这个比率,我们需要估计它。 有许多方法都可以用,包括一些花哨的算子理论方法, 试图直接使用最小范数或最大熵原理重新校准期望算子。 对于任意一种这样的方法,我们都需要从两个分布中抽取样本: “真实”的分布 p ,通过访问测试数据获取; 训练集 q ,通过人工合成的很容易获得。 请注意,我们只需要特征 \mathbf{x} \sim p(\mathbf{x}) , 不需要访问标签 y \sim p(y)

在这种情况下,有一种非常有效的方法可以得到几乎与原始方法一样好的结果: 对数几率回归(logistic regression)。 这是用于二元分类的softmax回归(见 3.4节)的一个特例。 综上所述,我们学习了一个分类器来区分从 p(\mathbf{x}) 抽取的数据 和从 q(\mathbf{x}) 抽取的数据。 如果无法区分这两个分布,则意味着相关的样本可能来自这两个分布中的任何一个。 另一方面,任何可以很好区分的样本都应该相应地显著增加或减少权重。

为了简单起见,假设我们分别从 p(\mathbf{x}) 和 q(\mathbf{x}) 两个分布中抽取相同数量的样本。 现在用 𝑧 标签表示:从 p 抽取的数据为 1 ,从 q 抽取的数据为 −1 。 然后,混合数据集中的概率由下式给出

P(z=1 \mid \mathbf{x}) = \frac{p(\mathbf{x})}{p(\mathbf{x})+q(\mathbf{x})} \text{ and hence } \frac{P(z=1 \mid \mathbf{x})}{P(z=-1 \mid \mathbf{x})} = \frac{p(\mathbf{x})}{q(\mathbf{x})}.

因此,如果我们使用对数几率回归方法,其中 P(z=1 \mid \mathbf{x})=\frac{1}{1+\exp(-h(\mathbf{x}))} ( h 是一个参数化函数),则很自然有:

\beta_i = \frac{1/(1 + \exp(-h(\mathbf{x}_i)))}{\exp(-h(\mathbf{x}_i))/(1 + \exp(-h(\mathbf{x}_i)))} = \exp(h(\mathbf{x}_i)).

因此,我们需要解决两个问题: 第一个问题是关于区分来自两个分布的数据; 第二个问题是关于 (4.9.5) 中的加权经验风险的最小化问题。 在这个问题中,我们将对其中的项加权 \beta_i 。

现在,我们来看一下完整的协变量偏移纠正算法。 假设我们有一个训练集 {(\mathbf{x}_1, y_1), \ldots, (\mathbf{x}_n, y_n)} 和一个未标记的测试集 {\mathbf{u}_1, \ldots, \mathbf{u}_m} 。 对于协变量偏移,我们假设 1 \leq i \leq n 的 \mathbf{x}_i 来自某个源分布, \mathbf{u}_i 来自目标分布。 以下是纠正协变量偏移的典型算法:

  1. 生成一个二元分类训练集: {(\mathbf{x}_1, -1), \ldots, (\mathbf{x}_n, -1), (\mathbf{u}_1, 1), \ldots, (\mathbf{u}_m, 1)} 。
  2. 用对数几率回归训练二元分类器得到函数 h 。
  3. 使用 \beta_i = \exp(h(\mathbf{x}_i)) 或更好的 \beta_i = \min(\exp(h(\mathbf{x}_i)), c) ( c 为常量)对训练数据进行加权。
  4. 使用权重 \beta_i 进行 (4.9.5) 中 {(\mathbf{x}_1, y_1), \ldots, (\mathbf{x}_n, y_n)} 的训练。

请注意,上述算法依赖于一个重要的假设: 需要目标分布(例如,测试分布)中的每个数据样本在训练时出现的概率非零。 如果我们找到 𝑝(𝑥)>0 但 𝑞(𝑥)=0 的点, 那么相应的重要性权重会是无穷大。


补充

针对于协变量偏移的输入数据的特征分布在源域和目标域之间不同的问题,协变量偏移纠正的主要目的是通过对输入特征进行变换或映射(比如增加上述的权重 \beta_i ),调整特征空间中输入数据的分布,使得源领域和目标领域的特征分布更一致,从而提高模型在目标领域上的泛化性能。


标签偏移纠正

假设我们处理的是 k 个类别的分类任务。 使用 4.9.3.2节 中相同符号, q 和 p 中分别是源分布(例如训练时的分布)和目标分布(例如测试时的分布)。 假设标签的分布随时间变化: q(y) \neq p(y) , 但类别条件分布保持不变: q(\mathbf{x} \mid y)=p(\mathbf{x} \mid y) 。 如果源分布 q(y) 是“错误的”, 我们可以根据 (4.9.2) 中定义的真实风险中的恒等式进行更正:

\begin{aligned} \int\int l(f(\mathbf{x}), y) p(\mathbf{x} \mid y)p(y) \;d\mathbf{x}dy = \int\int l(f(\mathbf{x}), y) q(\mathbf{x} \mid y)q(y)\frac{p(y)}{q(y)} \;d\mathbf{x}dy. \end{aligned}

这里,重要性权重将对应于标签似然比率

\beta_i \stackrel{\mathrm{def}}{=} \frac{p(y_i)}{q(y_i)}.

标签偏移的一个好处是,如果我们在源分布上有一个相当好的模型, 那么我们可以得到对这些权重的一致估计,而不需要处理周边的其他维度。 在深度学习中,输入往往是高维对象(如图像),而标签通常是低维(如类别)。

为了估计目标标签分布,我们首先采用性能相当好的现成的分类器(通常基于训练数据进行训练), 并使用验证集(也来自训练分布)计算其混淆矩阵。 混淆矩阵 \mathbf{C} 是一个 k \times k 矩阵, 其中每列对应于标签类别,每行对应于模型的预测类别。 每个单元格的值 c_{ij} 是验证集中,真实标签为 j , 而我们的模型预测为 i 的样本数量所占的比例。

现在,我们不能直接计算目标数据上的混淆矩阵, 因为我们无法看到真实环境下的样本的标签, 除非我们再搭建一个复杂的实时标注流程。 然而,我们所能做的是将所有模型在测试时的预测取平均数, 得到平均模型输出 \mu(\hat{\mathbf{y}}) \in \mathbb{R}^k , 其中第 i 个元素 \mu(\hat{y}_i) 是我们模型预测测试集中 i 的总预测分数。

结果表明,如果我们的分类器一开始就相当准确, 并且目标数据只包含我们以前见过的类别, 以及如果标签偏移假设成立(这里最强的假设), 我们就可以通过求解一个简单的线性系统来估计测试集的标签分布

\mathbf{C} p(\mathbf{y}) = \mu(\hat{\mathbf{y}}),

因为作为一个估计, \sum_{j=1}^k c_{ij} p(y_j) = \mu(\hat{y}_i) 对所有 1 \leq i \leq k 成立, 其中 p(y_j) 是 k 维标签分布向量 p(\mathbf{y}) 的第 j^\mathrm{th} 元素。 如果我们的分类器一开始就足够精确,那么混淆矩阵 \mathbf{C} 将是可逆的, 进而我们可以得到一个解 p(\mathbf{y}) = \mathbf{C}^{-1} \mu(\hat{\mathbf{y}})

因为我们观测源数据上的标签,所以很容易估计分布 q(y) 。 那么对于标签为 y_i 的任何训练样本 i , 我们可以使用我们估计的 p(y_i)/q(y_i) 比率来计算权重 \beta_i , 并将其代入 (4.9.5)中的加权经验风险最小化中。


补充

在标签偏移的情况下,虽然源领域和目标领域的标签分布存在差异,但如果在源分布上已经训练了一个高质量的模型,那么这个模型学习到的特征权重在不同领域之间可能是相对一致的。这意味着我们可以直接将源领域训练好的模型应用于目标领域,而无需对权重进行大幅度的调整或重新训练,从而可以在目标领域上实现较好的性能。

在深度学习中,输入数据通常是高维对象,如图像、文本等,而标签通常是低维的,比如类别信息。由于标签是比较简单和直观的信息,针对标签偏移问题,我们只需要关注和调整模型的输出层权重,而不需要处理输入数据中的其他高维维度信息。这使得在处理标签偏移时能够更加高效地调整模型,在目标领域上取得较好的泛化能力。

对于上文中提到的混淆矩阵 \mathbf{C} ,

C_{k \times k} = \left( \begin{matrix} c_{11} & c_{12} & \cdots & c_{1k} \\ c_{21} & c_{22} & \cdots & c_{2k} \\ \vdots & \vdots & \ddots & \vdots \\ c_{k1} & c_{kk} & \cdots & c_{kk} \\ \end{matrix} \right)

\mathbf{C} 的每行对应模型的预测类别,那么对预测取平均数 \mu(\hat{y}) ,就是将 \mathbf{C} 第 i 行每个元素 c_{ij} 乘以对应预测类别的分布向量 p(\mathbf{y_j}) ,也即 \sum_{j=1}^k c_{ij} p(y_j) = \mu(\hat{y}_i), (1 \leq i \leq k) 由此可得到 \mathbf{C} p(\mathbf{y}) = \mu(\hat{\mathbf{y}}) 其中:

 p(\mathbf{y})_{k \times 1} = \left( \begin{matrix} p(y_1) \\ p(y_2) \\ \vdots \\ p(y_k) \\ \end{matrix} \right) \mu(\hat{\mathbf{y}})_{k \times 1} = \left( \begin{matrix} \mu(\hat{\mathbf{y_1}}) \\ \mu(\hat{\mathbf{y_2}}) \\ \vdots \\ \mu(\hat{\mathbf{y_k}}) \\ \end{matrix} \right)


概念偏移纠正

概念偏移很难用原则性的方式解决。 例如,在一个问题突然从“区分猫和狗”偏移为“区分白色和黑色动物”的情况下, 除了从零开始收集新标签和训练,别无妙方。 幸运的是,在实践中这种极端的偏移是罕见的。 相反,通常情况下,概念的变化总是缓慢的。 比如下面是一些例子:

  • 在计算广告中,新产品推出后,旧产品变得不那么受欢迎了。这意味着广告的分布和受欢迎程度是逐渐变化的,任何点击率预测器都需要随之逐渐变化;
  • 由于环境的磨损,交通摄像头的镜头会逐渐退化,影响摄像头的图像质量;
  • 新闻内容逐渐变化(即新新闻的出现)。

在这种情况下,我们可以使用与训练网络相同的方法,使其适应数据的变化。 换言之,我们使用新数据更新现有的网络权重,而不是从头开始训练。

学习问题的分类法

有了如何处理分布变化的知识,我们现在可以考虑机器学习问题形式化的其他方面。

批量学习

批量学习(batch learning)中,我们可以访问一组训练特征和标签 {(\mathbf{x}_1, y_1), \ldots, (\mathbf{x}_n, y_n)} , 我们使用这些特性和标签训练 f(\mathbf{x})。 然后,我们部署此模型来对来自同一分布的新数据 (\mathbf{x}, y) 进行评分。 例如,我们可以根据猫和狗的大量图片训练猫检测器。 一旦我们训练了它,我们就把它作为智能猫门计算视觉系统的一部分,来控制只允许猫进入。 然后这个系统会被安装在客户家中,基本再也不会更新。

在线学习

除了“批量”地学习,我们还可以单个“在线”学习数据 (\mathbf{x}_i, y_i) 。 更具体地说,我们首先观测到 \mathbf{x}_i , 然后我们得出一个估计值 f(\mathbf{x}_i), 只有当我们做到这一点后,我们才观测到 y_i 。 然后根据我们的决定,我们会得到奖励或损失。 许多实际问题都属于这一类。 例如,我们需要预测明天的股票价格, 这样我们就可以根据这个预测进行交易。 在一天结束时,我们会评估我们的预测是否盈利。 换句话说,在在线学习(online learning)中,我们有以下的循环。 在这个循环中,给定新的观测结果,我们会不断地改进我们的模型。

\mathrm{model} ~ f_t \longrightarrow \mathrm{data} ~ \mathbf{x}_t \longrightarrow \mathrm{estimate} ~ f_t(\mathbf{x}_t) \longrightarrow \mathrm{observation} ~ y_t \longrightarrow \mathrm{loss} ~ l(y_t, f_t(\mathbf{x}_t)) \longrightarrow \mathrm{model} ~ f_{t+1}

老虎机

老虎机(bandits)是上述问题的一个特例。 虽然在大多数学习问题中,我们有一个连续参数化的函数 𝑓 (例如,一个深度网络)。 但在一个老虎机问题中,我们只有有限数量的手臂可以拉动。 也就是说,我们可以采取的行动是有限的。 对于这个更简单的问题,可以获得更强的最优性理论保证,这并不令人惊讶。 我们之所以列出它,主要是因为这个问题经常被视为一个单独的学习问题的情景。

控制

在很多情况下,环境会记住我们所做的事。 不一定是以一种对抗的方式,但它会记住,而且它的反应将取决于之前发生的事情。 例如,咖啡锅炉控制器将根据之前是否加热锅炉来观测到不同的温度。 在这种情况下,PID(比例—积分—微分)控制器算法是一个流行的选择。 同样,一个用户在新闻网站上的行为将取决于之前向她展示的内容(例如,大多数新闻她只阅读一次)。 许多这样的算法形成了一个环境模型,在这个模型中,他们的行为使得他们的决策看起来不那么随机。 近年来,控制理论(如PID的变体)也被用于自动调整超参数, 以获得更好的解构和重建质量,提高生成文本的多样性和生成图像的重建质量 ([2004.05988] ControlVAE: Controllable Variational Autoencoder (arxiv.org))。

强化学习

强化学习(reinforcement learning)强调如何基于环境而行动,以取得最大化的预期利益。 国际象棋、围棋、西洋双陆棋或星际争霸都是强化学习的应用实例。 再比如,为自动驾驶汽车制造一个控制器,或者以其他方式对自动驾驶汽车的驾驶方式做出反应 (例如,试图避开某物体,试图造成事故,或者试图与其合作)。

考虑到环境

上述不同情况之间的一个关键区别是: 在静止环境中可能一直有效的相同策略, 在环境能够改变的情况下可能不会始终有效。 例如,一个交易者发现的套利机会很可能在他开始利用它时就消失了。 环境变化的速度和方式在很大程度上决定了我们可以采用的算法类型。 例如,如果我们知道事情只会缓慢地变化, 就可以迫使任何估计也只能缓慢地发生改变。 如果我们知道环境可能会瞬间发生变化,但这种变化非常罕见, 我们就可以在使用算法时考虑到这一点。 当一个数据科学家试图解决的问题会随着时间的推移而发生变化时, 这些类型的知识至关重要。

机器学习中的公平、责任和透明度

最后,重要的是,当我们部署机器学习系统时, 不仅仅是在优化一个预测模型, 而通常是在提供一个会被用来(部分或完全)进行自动化决策的工具。 这些技术系统可能会通过其进行的决定而影响到每个人的生活。

从考虑预测到决策的飞跃不仅提出了新的技术问题, 而且还提出了一系列必须仔细考虑的伦理问题。 如果我们正在部署一个医疗诊断系统,我们需要知道它可能适用于哪些人群,哪些人群可能无效。 忽视对一个亚群体的幸福的可预见风险可能会导致我们执行劣质的护理水平。 此外,一旦我们规划整个决策系统,我们必须退后一步,重新考虑如何评估我们的技术。 在这个视野变化所导致的结果中,我们会发现精度很少成为合适的衡量标准。 例如,当我们将预测转化为行动时,我们通常会考虑到各种方式犯错的潜在成本敏感性。 举个例子:将图像错误地分到某一类别可能被视为种族歧视,而错误地分到另一个类别是无害的, 那么我们可能需要相应地调整我们的阈值,在设计决策方式时考虑到这些社会价值。 我们还需要注意预测系统如何导致反馈循环。 例如,考虑预测性警务系统,它将巡逻人员分配到预测犯罪率较高的地区。 很容易看出一种令人担忧的模式是如何出现的:

  1. 犯罪率高的社区会得到更多的巡逻;
  2. 因此,在这些社区中会发现更多的犯罪行为,输入可用于未来迭代的训练数据;
  3. 面对更多的积极因素,该模型预测这些社区还会有更多的犯罪;
  4. 下一次迭代中,更新后的模型会更加倾向于针对同一个地区,这会导致更多的犯罪行为被发现等等。

通常,在建模纠正过程中,模型的预测与训练数据耦合的各种机制都没有得到解释, 研究人员称之为“失控反馈循环”的现象。 此外,我们首先要注意我们是否解决了正确的问题。 比如,预测算法现在在信息传播中起着巨大的中介作用, 个人看到的新闻应该由他们喜欢的Facebook页面决定吗? 这些只是在机器学习职业生涯中可能遇到的令人感到“压力山大”的道德困境中的一小部分。

小结

  • 在许多情况下,训练集和测试集并不来自同一个分布。这就是所谓的分布偏移。
  • 真实风险是从真实分布中抽取的所有数据的总体损失的预期。然而,这个数据总体通常是无法获得的。经验风险是训练数据的平均损失,用于近似真实风险。在实践中,我们进行经验风险最小化。
  • 在相应的假设条件下,可以在测试时检测并纠正协变量偏移和标签偏移。在测试时,不考虑这种偏移可能会成为问题。
  • 在某些情况下,环境可能会记住自动操作并以令人惊讶的方式做出响应。在构建模型时,我们必须考虑到这种可能性,并继续监控实时系统,并对我们的模型和环境以意想不到的方式纠缠在一起的可能性持开放态度。

练习

  1. 当我们改变搜索引擎的行为时会发生什么?用户可能会做什么?广告商呢?

解:
改变搜索引擎的行为可能会有以下影响:
对于用户而言:

  • 改变搜索结果排序:如果搜索引擎改变了搜索结果的排序方式,用户可能会对搜索结果的相关性和可信度产生与之前不同的感受。如果已经习惯了之前特定的排序方式,用户可能会感到困惑或不满;如果是优化了之前的排序方式,用户也可能会觉得体验感更好。
  • 引入新功能:如果搜索引擎引入了新的功能或界面设计,用户可能会花费一些时间适应这种变化。同上一条一样,一些用户可能会喜欢新功能,而另一些用户可能会觉得新设计不方便或难以理解。
  • 改变用户行为:搜索引擎的行为变化也可能影响用户的搜索习惯和行为,比如用户可能会尝试不同的搜索关键词来获取信息,或者会更频繁或更少地使用该搜索引擎。

对于广告商而言:

  • 广告曝光和点击率:搜索引擎行为的改变可能会影响广告的展示位置和点击率,从而影响广告商的广告效果和投资回报。
  • 广告成本和竞争:新的搜索引擎行为可能会导致广告商展位的竞争加剧或减弱,从而影响广告的投放成本。广告商可能需要根据搜索引擎行为的变化及时调整广告投放策略。

2. 实现一个协变量偏移检测器。提示:构建一个分类器。

解:
实现一个协变量偏移检测器的步骤分为:

  1. 准备两个数据集分别作为训练数据和测试数据,要求两个数据集特征分布不同、输出分布相同。
  2. 构建一个分类器,并使用训练数据训练分类器。
  3. 用训练好的分类器分别评估对于训练数据和测试数据预测的精度,用于检测协变量偏移:若精度相差较大,则说明存在协变量偏移。
    代码如下:
import torch
from torch import nn

# 生成具有协变量偏移的训练数据和测试数据
samples = 1000
features = 2
X_train = torch.randn(samples , features)# 训练数据特征
X_test_1 = torch.randn(samples , features)  # 测试数据特征
X_test_2 = torch.randn(samples , features) *5 # 引入协变量偏移
y = torch.ones(samples)  # 输出分布一致

# 构建softmax回归分类器
net = nn.Linear(2, 2)  # 输入特征维度为2,输出类别数为2
loss = nn.CrossEntropyLoss(reduction='mean')
trainer = torch.optim.SGD(net.parameters(), lr=0.1)

def clf_train(X, y, net, loss, trainer, epochs=10):
    for epoch in range(epochs):
        trainer.zero_grad()
        l = loss(net(X), y.long())
        l.backward()
        trainer.step()

def clf_test(X, y, net):    
    _, predicted = torch.max(net(X), dim=1)
    acc = (predicted == y).sum().item() / len(y)
    return acc

# 训练分类模型
clf_train(X_train, y, net, loss, trainer)

# 使用训练/测试数据执行分类模型,生成预测结果
train_accuracy = clf_test(X_train, y, net)
print(f"Accuracy on train data: {train_accuracy}")

test_accuracy = clf_test(X_test_1, y, net)
print(f"Accuracy on test data without covariate shift: {test_accuracy}")

test_accuracy = clf_test(X_test_2, y, net)
print(f"Accuracy on test data with covariate shift: {test_accuracy}")

Accuracy on train data: 0.993
Accuracy on test data without covariate shift: 0.995
Accuracy on test data with covariate shift: 0.681

3. 实现协变量偏移纠正。

解:
基于上题生成的训练数据和带协变量偏移的测试数据,进行协变量偏移纠正,代码如下:

# Step1: 生成二元分类训练集
X = torch.cat([X_train, X_test_2], dim=0)  # 将X_train和带协变量偏移的X_test_2合并在一起
y_set = torch.cat([torch.full((samples,), -1), torch.full((samples,), 1)], dim=0)  # 对应的标签也进行合并

# Step2: 定义对数几率回归模型并训练二元分类器
class LogisticRegression(nn.Module):
    def __init__(self, features):
        super(LogisticRegression, self).__init__()
        self.linear = nn.Linear(features, 1)

    def forward(self, x):
        return self.linear(x)

net = LogisticRegression(features)
loss1 = nn.BCEWithLogitsLoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.1)

def train_model(X, y_set, net, loss, trainer, epochs=10):
    for epoch in range(epochs):
        trainer.zero_grad()
        l = loss(net(X).view(-1), y_set.float())
        l.backward()
        trainer.step()

train_model(X, y_set, net, loss, trainer)

# Step3: 计算权重βi
def compute_weights(net, X, c=5):
    with torch.no_grad():
        logits = net(X)
        exp_logits = torch.exp(logits)
        weight = torch.min(exp_logits, torch.tensor(c).float())
    return weight

weight = compute_weights(net, X)

# Step4: 使用权重βi对训练数据进行加权训练
net = nn.Linear(2, 2)
loss2 = nn.CrossEntropyLoss(reduction='mean')
trainer = torch.optim.SGD(net.parameters(), lr=0.1)

def clf_train_weight(X, y, net, loss, trainer, epochs=10):
    for epoch in range(epochs):
        trainer.zero_grad()
        l = torch.mean(weight * loss(net(X), y.long()))
        l.backward()
        trainer.step()

# 训练分类模型
clf_train_weight(X_train, y, net, loss, trainer)

# 使用训练/测试数据执行分类模型,生成预测结果
train_accuracy = clf_test(X_train, y, net)
print(f"Accuracy on train data: {train_accuracy}")

test_accuracy = clf_test(X_test_1, y, net)
print(f"Accuracy on test data without covariate shift: {test_accuracy}")

test_accuracy = clf_test(X_test_2, y, net)
print(f"Accuracy on test data with covariate shift: {test_accuracy}")
Accuracy on train data: 1.0
Accuracy on test data without covariate shift: 1.0
Accuracy on test data with covariate shift: 0.996

4. 除了分布偏移,还有什么会影响经验风险接近真实风险的程度?

解:

  • 标签噪声:如果训练集中存在标签错误或标签噪声,那么模型学习到的规律可能不准确,从而导致经验风险与真实风险的偏差。
  • 特征选择和提取:特征的选择和提取可能会影响模型的表示能力,从而影响模型在真实数据分布下的泛化能力。
  • 模型的复杂度:过于简单或过于复杂的模型都可能导致经验风险与真实风险之间的偏差。过于简单的模型可能欠拟合,而过于复杂的模型可能产生过拟合。
  • 样本量:训练数据集的样本量大小对经验风险的准确估计也有影响,样本量过小可能会导致估计的偏差。
  • 误差累积:训练集、验证集和测试集的划分和噪声可能导致误差在整个训练和测试过程中的累积,从而影响对真实风险的估计。
  • 领域适应:当训练集与测试集的数据分布在特征空间或标签空间上存在差异时(领域适应),训练出的模型对新数据的泛化可能会受到影响。

最近更新

  1. TCP协议是安全的吗?

    2024-06-09 03:06:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-09 03:06:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-09 03:06:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-09 03:06:03       20 阅读

热门阅读

  1. Access数据中的SQL偏移注入

    2024-06-09 03:06:03       9 阅读
  2. 在Spark SQL中,fillna函数

    2024-06-09 03:06:03       11 阅读
  3. SELinux:安全增强型Linux

    2024-06-09 03:06:03       10 阅读
  4. 嵌入式C中Hex与Bin文件对比分析

    2024-06-09 03:06:03       11 阅读
  5. 数据结构学习笔记-二叉树

    2024-06-09 03:06:03       10 阅读
  6. Python使用Flask构建简单的web应用

    2024-06-09 03:06:03       11 阅读
  7. 深度学习 - softmax交叉熵损失计算

    2024-06-09 03:06:03       10 阅读
  8. 代码杂谈 之 pyspark如何做相似度计算

    2024-06-09 03:06:03       13 阅读