# 问题与答案

译者：[@laiczhang](https://github.com/laiczhang)

## 7.1 核回归

我们谈到了线性回归，但是如果我们的数据不具有直线形式呢？使用多项式回归可能会有所帮助。 假设我们有一个一维数据$\left\{\left(x_{i}, y_{i}\right)\right\}_{i=1}^{N}$。我们可以尝试为我们的数据设置二次方程$y=w_{1} x_{i}+w_{2} x_{i}^{2}+b$。通过定义均方误差成本函数，我们可以应用梯度下降并找到参数$w1,w2,b$的值，以最小化该成本函数。 在一维或二维空间中，我们可以很容易地看出函数是否包含数据。但是，如果我们的输入是D维特征向量并且D> 3，那么找到正确的多项式将很难。

核回归是一种非参数方法。 这意味着没有要学习的参数。 该模型基于数据本身（如kNN）。 在最简单的形式中，在内核回归中，我们寻找这样的模型：$f(x)=\frac{1}{N} \sum_{i=1}^{N} w_{i} y_{i},$ where $w_{i}=\frac{N k\left(\frac{x_{i}-x}{b}\right)}{\sum_{k=1}^{N} k\left(\frac{x_{k}-x}{b}\right)}$ (1)

函数k（·）是一个内核。 它可以有不同的形式，最常用的是高斯核：$k(z)=\frac{1}{\sqrt{2 \pi}} \exp \left(\frac{-z^{2}}{2}\right)$ 

![7-1](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-1.png)

值b是我们使用验证集调整的超参数（通过在验证集示例上运行使用特定值b构建的模型并计算均值squarederror）。 你可以用它来说明方程1。

如果您的输入是多维特征向量，$x_{i}-x$ 和 $x_{k}-x$ 在方程1中。必须由欧几里德距离分别代替$\left\|\mathbf{x}_{i}-\mathbf{x}\right\|$ 和 $\left\|\mathbf{x}_{k}-\mathbf{x}\right\|$ 。

## 7.2 多类分类

在多分类中，标签可以是C类：$y \in\{1, \ldots, C\}$之一。许多机器学习算法是二进制的; SVM就是一个例子。 一些算法自然可以扩展到处理多类问题。ID3和其他决策树学习算法可以像这样简单地改变：$f_{I D 3}^{S} \stackrel{\mathrm{def}}{=} \operatorname{Pr}\left(y_{i}=c | \mathbf{x}\right)=\frac{1}{|S|} \sum_{\{y |(\mathbf{x}, y) \in S, y=c\}} y$,for all $c \in\{1, \ldots, C\}$

通过用我们在第6章中已经看到的softmax函数替换sigmoid函数，逻辑回归可以自然地扩展到多类学习问题。

kNN算法也很容易扩展到多类情况：当我们找到输入x的k个最接近的例子并检查它们时，我们返回我们在k个例子中看到的最多的类。

SVM不能自然地扩展到多类问题。 在二进制情况下，某些算法可以更有效地实现。 如果您有多类问题但是二元分类学习算法，您应该怎么做？ 一种常见的策略叫做一对一休息。 我们的想法是将多类问题转换为C二进制分类问题并构建C二进制分类器。例如，如果我们有三个类，$y \in\{1,2,3\}$ 我们创建原始数据集的副本并进行修改。 在第一个副本中，我们将所有不等于1的标签替换为0.在第二个副本中，我们将所有不等于2的标签替换为0.在第三个副本中，我们将所有不等于3的标签替换为0.现在我们 有三个二元分类问题，我们必须学会区分标签1和0,2和0，以及标签3和0之间。

一旦我们有三个模型并且我们需要对新输入特征向量x进行分类，我们将三个模型应用于输入，并且我们得到三个预测。 然后我们选择非零类的预测，这是最确定的。 请记住，在逻辑回归中，模型不返回标签，而是返回得分（0,1），可以将其解释为标签为正的概率。 我们也可以将此分数解释为预测的确定性。 在SVM中，确定性的模拟是从输入x到决策边界的距离。 这个距离是由$d=\frac{\mathbf{w}^{*} \mathbf{x}+b^{*}}{\|w\|}$ 给出的。

距离越大，预测越确定。 大多数学习算法可以自然地转换为多类情况，或者它们返回我们可以在一对战策略中使用的分数。

## 7.3 单类分类

一类分类，也称为一元分类或类建模，试图通过从仅包含该类对象的训练集中学习来识别所有对象中特定类的对象。 与传统的分类问题不同，后者试图用包含来自所有类的对象的训练集来区分两个或更多个类。 典型的一类分类问题是正常情况下安全网络中传输的分类。 在这种情况下，攻击或入侵期间的流量示例很少（如果有）。 然而，正常交通的例子通常很多。 一类分类学习算法用于异常值检测，异常检测和新颖性检测。 

有几种一流的学习算法。 在实践中最广泛使用的是一类高斯，一类kmeans，一类kNN和一类SVM。

一类高斯背后的想法是我们将数据建模为好像它来自高斯分布，更准确地说是多元正态分布（MND）。 MND的概率密度函数（pdf）由以下等式给出：$f_{\boldsymbol{\mu}, \mathbf{\Sigma}}(\mathbf{x})=\frac{\exp \left(-\frac{1}{2}(\mathbf{x}-\boldsymbol{\mu})^{\mathrm{T}} \mathbf{\Sigma}^{-1}(\mathbf{x}-\boldsymbol{\mu})\right)}{\sqrt{(2 \pi)^{D}|\boldsymbol{\Sigma}|}}$ 

其中，$f_{\mu, \mathbf{\Sigma}}(\mathbf{x})$返回对应于输入特征向量x的概率密度。概率密度可以解释为示例x从我们建模为MND的概率分布中抽取的可能性。值$μ$（向量）和$Σ$（矩阵）是我们必须学习的参数。最大似然准则（类似于我们如何解决逻辑回归学习问题）被优化以找到这两个参数的最佳值。$|\mathbf{\Sigma}|=\operatorname{det} \mathbf{\Sigma}$是矩阵$Σ$的行列式。符号$\mathbf{a}^{T}$表示向量$a$的转置。$\mathbf{\Sigma}^{-1}$是矩阵$Σ$的逆矩阵。 

如果行列式，转置和逆矩阵对您来说是新知识，请不要担心。 这些是来自数学分支的矢量和矩阵的标准运算，称为矩阵理论。 如果你觉得有必要知道它们是什么，维基百科很好地解释了这些概念。

实际上，矢量$μ$中的数字决定了我们的高斯分布曲线居中的位置，而$Σ$中的数字决定了曲线的形状。 对于由二维特征向量组成的训练集，在图2中给出了单类高斯模型的示例。

![7-2](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-2.png)

一旦我们的模型通过$μ$和$Σ$从数据中学习参数化，我们就可以通过使用$f_{\boldsymbol{\mu}, \boldsymbol{\Sigma}}(\mathbf{x})$来预测每个输入$x$的可能性。 只有当可能性高于某一某个阈值时,我们预测这个例子属于我们的类; 否则，它被归类为异常值。 阈值的值可以通过实验或使用“有根据的猜测”找到。

当数据具有更复杂的形状时，更高级的算法可以使用几个高斯的组合（称为高斯混合）。 在这种情况下，可以从数据中学习更多参数：每个高斯的一个$μ$和一个$Σ$以及允许组合多个高斯形成一个pdf的参数。 在第9章中，我们考虑了高斯混合体和聚类应用。

一类kmeans和一类kNN基于与一类Gaussian相似的原理：构建一些数据模型，然后根据模型确定我们的新特征向量是否与其他示例类似。 在前者中，使用kmeans聚类算法对所有训练示例进行聚类，并且当观察到新示例x时，距离$d(\mathbf{x})$被计算为$x$与每个聚类的中心之间的最小距离。 如果$d(\mathbf{x})$小于特定阈值，则$x$属于该类。 

根据公式，单类SVM尝试1）将所有训练样例与原点（在特征空间中）分开并最大化从超平面到原点的距离，或2）以获得围绕数据的球形边界。 最小化这个超球面的体积。 我留下了一类kNN算法的描述，以及一类kmeans和一类SVM的细节，用于补充阅读。![7-3](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-3.png)



## 7.4 多标签分类

在多标签分类中，每个训练示例不仅有一个标签，而且还有几个标签。 例如，如果我们想要描述一个图像，我们可以为它分配几个标签：“人”，“音乐会”，“自然”，同时分配这三个标签。

标签的可能值的数量很多，但它们都具有相同的性质，例如标签，我们可以将每个标记的示例转换为几个标记的示例，每个标签一个。 这些新示例都具有相同的特征向量和仅一个标签。 这成为一个多类分类问题。 我们可以使用one-rest策略来解决它。 与通常的多类问题唯一不同的是，现在我们有了一个新的超参数：阈值。 如果某个标签的预测分数高于阈值，则为输入特征向量预测该标签。 在这种情况下，可以为一个特征向量预测多个标签。 使用验证集选择阈值。

类似地，自然可以制成多类算法（决策树，逻辑回归和神经网络等）可以应用于多标签分类问题。 因为它们返回每个类的分数，所以我们可以定义阈值，然后如果阈值高于使用验证集实验选择的某个值，则为一个特征向量分配多个标签。

神经网络算法可以通过使用二元交叉熵成本函数自然地训练多标签分类模型。 在这种情况下，神经网络的输出层每个标签有一个单元。 输出层的每个单元具有S形激活功能。

因此，每个标记$l$是二进制的($y_{i, l} \in\{0,1\}$)，其中$l=1, \ldots, L$ 且 $i=1, \ldots, N$ 。预测概率$\hat{y}_{i, l}$的二元交叉熵，即示例$\mathbf{x}_{i}$具有标记$l$的概率为：$-\left(y_{i, l} \ln \left(\hat{y}_{i, l}\right)+\left(1-y_{i, l}\right) \ln \left(1-\hat{y}_{i, l}\right)\right)$最小化标准仅仅是所有训练样本中所有二元交叉熵项的平均值以及这些示例的所有标签。 在每个标签可以采用的可能值的数量很小的情况下，可以将多标签转换为多标签问题。 想象一下以下问题。 我们想要标记图像和标签可以有两种类型。 第一种标签可以有两个可能的值： { photo,painting } ; 第二种类型的标签可以有三个可能的值:{portrait,paysage,other}.我们可以为两个原始类的每个组合创建一个新的假类，如下所示：![7-4](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-4.png)

现在我们有相同的标记示例，但是我们用一个假标签替换真正的多标签，其值为1到6.当没有太多可能的类组合时，这种方法在实践中很有效。 否则，您需要使用更多的训练数据来补偿增加的类集。

后一种方法的主要优点是，您可以保持标签的相关性，这与先前看到的预测每个标签彼此独立的方法相反。 标签之间的相关性可能是许多问题中的基本属性。 例如，如果您想要预测电子邮件是否是垃圾邮件或not_spam，则可以预测它是普通电子邮件还是优先电子邮件。 您希望避免像[垃圾邮件，优先级]这样的预测。

## 7.5 集成学习

集成学习是一种学习范式，它不是试图学习超精确模型，而是专注于训练大量低精度模型，然后将这些弱模型给出的预测结合起来，以获得高精度的元模型。 低精度模型通常由弱学习者学习，即学习算法无法学习复杂模型，因此通常在训练和预测时快速。 最常用的弱学习者是决策树学习算法，其中我们经常在几次迭代后停止分割训练集。 获得的树很浅而且不是特别准确，但是集合学习背后的想法是如果树不相同并且每棵树至少比随机猜测略好，那么我们可以通过组合大量这样的树来获得高精度。

为了获得输入$x$的预测，使用某种加权投票来组合每个弱模型的预测。 投票权重的具体形式取决于算法，但是，与算法无关，这个想法是相同的：如果弱模型理事会预测该消息是垃圾邮件，那么我们将标签垃圾邮件分配给$x$。 两种最广泛使用和有效的集成学习算法是随机森林和梯度增强。

### 7.5.1 随机森林

有两种集合学习范例：套袋和提升。 套袋包括创建训练数据的许多“副本”（每个副本与另一个副本略有不同），然后将弱学习者应用于每个副本以获得多个弱模型然后将它们组合。 套袋范例是随机森林学习算法的背后。

“vanilla”装袋算法的工作原理如下。 给定训练集，我们创建训练集的$B$随机样本$S_{b}$（对于每个$b=1, \ldots, B $），并使用每个样本$S_{b}$作为训练集来构建决策树模型$f_b$。 为了对某些$b$采样$S_{b}$，我们进行了替换采样。 这意味着我们从空集开始，然后从训练集中随机选取一个示例，并通过将原始示例保留在原始训练集中将其精确副本放入$S_{b}$。 我们一直随机挑选示例，直到$\left|S_{b}\right|=N$.

训练结束后，我们有B决策树。 获得新示例x的预测作为B预测的平均值：$y \leftarrow \hat{f}(\mathbf{x}) \stackrel{\mathrm{def}}{=} \frac{1}{B} \sum_{b=1}^{B} f_{b}(\mathbf{x})$ ,在回归的情况下，或在分类的情况下通过多数投票。

随机森林算法与香草套袋不同，只有一种方式。 它使用修改树学习算法，在学习过程中的每个分割中检查特征的随机子集。 这样做的原因是为了避免树的相关性：如果一个或几个特征是目标的非常强的预测器，则将选择这些特征以在许多树中分割示例。 这将在我们的“森林”中产生许多相关树。相关预测器无助于提高预测的准确性。 模型集成性能更好的主要原因是，良好的模型可能会对同一预测达成一致，而糟糕的模型可能会对不同的模型产生不同意见。 相关性将使坏模型更有可能达成一致，这将阻碍多数投票或平均投票。

要调整的最重要的超参数是树的数量$B$，以及每次拆分时要考虑的特征的随机子集的大小。

随机森林是最广泛使用的集成学习算法之一。 它为什么如此有效？ 原因是通过使用原始数据集的多个样本，我们减少了最终模型的方差。 请记住，低方差意味着低过度配置。 虽然在我们的数据集中，但是因为我们的数据集只是对现象中所有可能的示例进行填充，所以我们试图建模。 如果我们不熟悉我们的训练集是如何被采样的，那么它可能包含一些不期望的（但不可避免的）伪像：噪声，异常值以及过度或不足的示例。 通过创建多个随机样本并替换我们的训练集，我们可以减少这些伪影的影响。

### 7.5.2梯度增强

另一种有效的集成学习算法是梯度增强。 让我们首先看一下回归的梯度增强。 为了构建一个强大的回归量，我们从常量模型$f=f_{0}$开始（就像我们在ID3中所做的那样）：$f=f_{0}(\mathbf{x}) \stackrel{\mathrm{def}}{=} \frac{1}{N} \sum_{i=1}^{N} y_{i}$ 

然后我们在训练集中修改每个例子$i=1, \ldots, N$的标签，如下所示：$\hat{y}_{i} \leftarrow y_{i}-f\left(\mathbf{x}_{i}\right)$  (2)

其中$\hat{y}_{i}$，称为残差，是新标签，例如$x_{i}$。

现在我们使用修改训练集，用残差而不是原始标签来构建新的决策树模型$f_{1}$。 现在将增强模型定义为$f \stackrel{\mathrm{def}}{=} f_{0}+\alpha f_{1}$，其中$α$是学习速率（超参数）。

然后我们使用方程2重新计算残差。再次替换训练数据中的标签，训练新的决策树模型$f_{2}$，将增强模型重新定义为$f \stackrel{\mathrm{def}}{=} f_{0}+\alpha f_{1}+\alpha f_{2}$，并且该过程继续直到$M$（另一个超参数）树的最大值被组合。

直观地说，这里发生了什么？ 通过计算残差，我们发现当前模型f预测每个训练样例的目标的好坏程度（或差）。 然后我们训练另一棵树来修复当前模型的误差（这就是为什么我们使用残差而不是真实标签）并将这个新树添加到具有一些权重$α$的现有模型中。 因此，添加到模型中的每个附加树部分地修复了先前树所做的错误，直到组合了最大数量的树。

现在你应该合理地问为什么算法被称为梯度增强？ 在梯度增强中，我们不计算任何与第4章中线性回归相反的梯度。 为了看到梯度增强和梯度下降之间的相似性，请记住为什么我们在线性回归中计算梯度：我们这样做是为了了解我们应该在哪里移动参数值以使MSE成本函数达到最小值。 梯度显示了方向，但是我们不知道我们应该朝这个方向走多远，所以我们在每次迭代时使用了一个小步α，然后重新评估了我们的方向。 在梯度增强中也是如此。 然而，我们不是直接获得渐变，而是以残差的形式使用其代理：它们向我们展示了如何调整模型以便减少误差（残差）。

调整梯度增强的三个主要超参数是树的数量，学习速率和树的深度 - 这三个都是模型的精确度。 树木的深度也会影响训练和预测的速度：越短，越快。

可以证明，对残差的训练优化了均方误差标准的整体模型f。 你可以在这里看到与装袋的不同之处：增强可以减少偏差（或者在配置下）而不是方差。 因此，提升可以超过。 但是，通过调整树木的深度和数量，可以在很大程度上避免过度配置。

渐进式算法的分类方法类似，但很有可能。 让我们考虑二元情况。 假设我们有M个回归决策树。 与逻辑回归类似，使用sigmoid函数对决策树集合的预测进行建模：$\operatorname{Pr}(y=1 | \mathbf{x}, f) \stackrel{\mathrm{def}}{=} \frac{1}{1+e^{-f(\mathbf{x})}}$,其中$f(\mathbf{x})=\sum_{m=1}^{M} f_{m}(\mathbf{x})$且$f_{m}$是回归树。

同样，在逻辑回归中，我们通过尝试找到最大化$L_{f}=\sum_{i=1}^{N} \ln \left(\operatorname{Pr}\left(y_{i}=1 | \mathbf{x}_{i}, f\right)\right)$的$f$来应用最大似然原理。 同样，为了避免数值超过流量，我们最大化对数似然的总和而不是可能性的乘积。

该算法以初始常数模型$f=f_{0}=\frac{p}{1-p}$开始，其中$p=\frac{1}{N} \sum_{i=1}^{N} y_{i}$。 （可以证明这种初始化对于sigmoid函数是最佳的。）然后在每次迭代$m$，将新的树$f_{m}$添加到模型中。 为了找到最佳的$f_{m}$，首先计算当前模型的偏导数$g_{i}$，每个$i=1, \ldots, N $：$g_{i}=\frac{d L_{f}}{d f}$,其中$f$是在前一次迭代$m-1$中构建的集合分类器模型。为了计算$g_{i}$，我们需要找到关于所有$i$的$f$的$\ln \left(\operatorname{Pr}\left(y_{i}=1 | \mathbf{x}_{i}, f\right)\right)$的导数。 注意$\ln \left(\operatorname{Pr}\left(y_{i}=1 | \mathbf{x}_{i}, f\right)\right) \stackrel{\operatorname{def}}{=} \ln \left(\frac{1}{1+e^{-f\left(\mathbf{x}_{i}\right)}}\right)$。 前一个等式中右手项的导数相对于$f$等于$\frac{1}{e^{f\left(\mathbf{x}_{i}\right)}+1}$。

然后，我们通过用相应的偏导数$g_{i}$替换原始标签$y_{i}$来变换我们的训练集，并且我们使用变换的训练集来构建新的树$f_{m}$。 然后我们找到最佳更新步骤$ρ_{m}$：$\rho_{m}=\underset{\rho}{\arg \max } L_{f+\rho f_{m}}$

在迭代$m$结束时，我们通过添加新树$f_{m}$来更新集合模型$f$：$f \leftarrow f+\alpha \rho_{m} f_{m}$

我们迭代直到$m = M$，然后我们停止并返回整体模型$f$。

渐变增强是最强大的机器学习算法之一。 不仅因为它创建了非常精确的模型，还因为它能够处理具有数百万个示例和功能的大型数据集。 它通常在准确性上优于随机森林，但由于其连续性，在训练中可能会明显变慢。

## 7.6 学习标记序列

序列是最常观察到的结构化数据类型之一。 我们使用单词和句子的顺序进行交流，我们按顺序执行任务，我们的基因，我们听的音乐和我们观看的视频，我们对连续过程的观察，例如移动的汽车或股票的价格都是连续的。

在序列标记中，标记的顺序示例是一对列表$(X，Y)$，其中X是特征向量的列表，每个时间步长一个，$Y$是相同长度的标签的列表。 例如，$X$可以表示句子中的单词，如[“big”，“beautiful”，“car”]，$Y$可以是相应词性的列表，例如[“形容词”，“形容词”， “名词”]）。 更正式地，在示例$i$中，$X_{i}=\left[\mathbf{x}_{i}^{1}, \mathbf{x}_{i}^{2}, \ldots, \mathbf{x}_{i}^{\text {size}}\right]$，其中$size_{i}$是示例$i$的序列的长度，$Y_{i}=\left[y_{i}^{1}, y_{i}^{2}, \ldots, y_{i}^{s i z e_{i}}\right]$和$y_{i} \in\{1,2, \ldots, C\}$。

您已经看到RNN可用于注释序列。 在每个时间步长$t$，它读取输入特征向量$\mathbf{x}_{i}^{(t)}$，最后一个复发层最后输出标签$y_{l a s t}^{(t)}$（在二进制标记的情况下）或最后输出$y_{l a s t}^{(t)}$（在 多类或多标签标签）。

然而，RNN不是序列标记的唯一可能模型。 称为条件随机场（CRF）的模型是一种非常有效的替代方案，在实践中通常对具有许多信息特征的特征向量表现良好。 例如，假设我们有命名实体提取的任务，我们想要构建一个模型，用以下类之一标记句子中的每个单词，例如“我去旧金山”：{location，name，company_name， 其他}。 如果我们的特征向量（代表单词）包含诸如“单词是否以大写字母开头”和“是否可以在位置列表中找到该单词”这样的二进制特征，则这些特征将提供非常丰富的信息。 帮助将San和Francisco这两个词分类为位置。 众所周知，构建手工制作的特征是一个劳动密集型过程，需要大量的领域专业知识。

CRF是一个有趣的模型，可以看作是对序列的逻辑回归的推广。 然而，在实践中，它已经被双向深门控RNN用于序列标记任务。 CRF在训练中也明显变慢，这使得它们很难应用于大型训练集（有数十万个例子）。 此外，大型训练集是深度神经网络蓬勃发展的地方。

![7-5](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-5.png)

## 7.7序列到序列学习

序列到序列学习（通常简称为secq2seqlearning）是序列标记问题的中心化。 在seq2seq中，$X_{i}$和$Y_{i}$可以有不同的长度。 seq2seq模型已经在机器翻译中找到应用（例如，输入是英语句子，输出是相应的法语句子），会话界面（输入是用户输入的问题，输出是 从机器上回答），文本摘要，拼写纠正等等。

许多但不是大多数序列到序列学习问题目前最好通过神经网络解决。 机器翻译是一个臭名昭着的例子。 seq2seq有多种神经网络架构，根据任务的不同，它们的性能优于其他架构。 所有这些网络架构都有一个共同的特性：它们有两个部分，一个编码器和一个解码器（因此它们也被称为编码器 - 解码器神经网络）。

在seq2seq学习中，编码器是一个接受顺序输入的神经网络。 它可以是RNN，也可以是CNN或其他一些架构。 编码器的作用是读取输入并生成某种状态（类似于RNN中的状态），可以将其视为机器可以使用的输入含义的数字表示。 某个实体的含义，无论是图像，文本还是视频，通常都是包含实数的矢量或矩阵。 这个向量（或矩阵）在机器学习术语中被称为输入的嵌入。

seq2seq学习中的解码器是另一个神经网络，它将嵌入作为输入并且能够生成一系列输出。 正如您可能已经猜到的那样，嵌入来自编码器。 为了产生一系列输出，解码器采用序列输入特征向量$\mathbf{x}^{(0)}$的开始（通常为全零），产生第一输出$\mathbf{y}^{(1)}$，通过组合嵌入和输入$\mathbf{x}^{(0)}$来更新其状态 ，然后使用输出$\mathbf{y}^{(1)}$作为其下一个输入$\mathbf{x}^{(1)}$。 为简单起见，$\mathbf{y}^{(t)}$的维数可以与$\mathbf{x}^{(t)}$的维度相同; 但是，这不是绝对必要的。 正如我们在第6章中看到的那样，RNN的每一层都可以产生许多同时输出：一个可用于生成标签$\mathbf{y}^{(t)}$，而另一个具有不同维度的输出可用作$\mathbf{x}^{(t)}$。
![7-6](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-6.png)

使用训练数据同时训练编码器和解码器。 解码器输出处的误差通过反向传播传播到编码器。

传统的seq2seq架构如图所示。 图4使用注意力的架构可以获得更准确的预测。 注意机制由一组额外的参数实现，这些参数组合来自编码器的一些信息（在RNN中，该信息是来自所有编码器时间步骤的最后一个重复层的状态向量的列表）和解码器的当前状态以生成 标签。 与门控单元和双向RNN相比，这可以更好地保留长期依赖性。 图5中示出了一个引人注目的seq2seq架构。

![7-7](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-7.png)

序列到序列学习是相对较新的研究领域。 定期发现并发布新的网络架构。 培训这样的架构可能具有挑战性，因为调整的超参数和其他架构决策的数量可能是压倒性的。 我建议您查阅本书的wiki，了解最新的材料，教程和代码示例。

![7-8](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-8.png)



## 7.8 主动学习

主动学习是一种有趣的监督学习范式。 通常在获得标记的示例时使用它是昂贵的。 在医疗或金融领域中通常就是这种情况，其中可能需要专家的意见来注释患者或客户的数据。 我们的想法是，我们使用相对较少的标记示例和大量未标记的示例开始学习，然后仅将标签添加到对模型质量贡献最大的那些示例中。

主动学习有多种策略。 在这里，我们仅讨论以下两个：

1）基于数据密度和不确定性，以及

2）支持基于矢量的。

前一策略将使用现有标记示例训练的当前模型f应用于剩余的未标记示例中的每一个（或者，为了节省计算时间，将其保存到它们的一些随机样本中）。 对于每个未标记的示例x，计算以下重要性分数：密度($x$)*不确定性($f(x)$)。 密度反映了在其邻近区域中围绕$x$的示例，而不确定性$f(x)$反映了模型f的预测对于x的不确定性。 在具有sigmoid的二进制分类中，预测分数越接近0.5，预测就越不确定。 在SVM中，示例越靠近决策边界，最不确定的是预测。

在多类分类中，熵可以用作不确定性的典型度量：$\mathrm{H}_{f}(\mathrm{x})=-\sum_{c=1}^{C} \operatorname{Pr}\left(y^{(c)} ; f(\mathrm{x})\right) \ln \operatorname{Pr}\left(y^{(c)} ; f(\mathrm{x})\right)$

其中$\operatorname{Pr}\left(y^{(c)} ; f(\mathbf{x})\right)$是模型$f$在分类$x$时分配给类$y^{(c)}$的概率分数。你可以看到，如果每个$y^{(c)}$，$f\left(y^{(c)}\right)=\frac{1}{C}$，则模型最不确定，熵最大为1; 另一方面，如果对于某些$y^{(c)}, f\left(y^{(c)}\right)=1$，则模型确定关于类$y^{(c)}$并且熵最小为0。

可以通过获取从x到其k个最近邻居中的每一个的平均距离来获得示例x的密度（其中k是超参数）。

一旦我们知道每个未标记示例的重要性得分，我们选择具有最高重要性得分的那个并请求专家对其进行注释。 然后我们将新注释的示例添加到训练集，重建模型并继续该过程，直到满足一些停止标准。 可以提前选择停止标准（基于可用预算向专家请求的最大数量），或者取决于我们的模型根据某个度量标准执行的程度。

基于支持向量的主动学习策略包括使用标记数据构建SVM模型。 然后，我们请求我们的专家注释最接近分隔两个类的超平面的未标记示例。 这个想法是，如果这个例子最接近超平面，那么它是最不确定的，并且会对真实（我们寻找的）超平面可能存在的可能位置的减少贡献最大。

一些主动学习策略可以包括向专家询问标签的成本。 其他人学会询问专家的意见。 “委员会查询”策略包括使用不同的方法训练多个模型，然后请专家标记这些模型最不同意的示例。 一些策略尝试选择标注示例，以便模型的方差或偏差减少最多。

## 7.9 半监督学习

在半监督学习（SSL）中，我们也标记了数据集的一小部分; 大多数其余的例子都没有标记。 我们的目标是利用大量未标记的示例来提高模型性能，而无需咨询专家的标签示例。

从历史上看，有多次尝试解决这个问题。 它们都不能被称为普遍赞誉并且经常在实践中使用。 例如，一种经常引用的SSL方法称为“自学习”。在自学习中，我们使用学习算法使用标记的示例来构建初始模型。 然后我们将模型应用于所有未标记的示例，并使用模型标记它们。 如果某些未标记的示例x的预测的置信分数高于某个阈值（通过实验选择），那么我们将这个标记的示例添加到我们的训练集中，重新训练模型并继续这样，直到满足停止标准。 例如，如果在最后$m$次迭代期间模型的准确性没有得到改善，我们就可以停止。

与仅使用最初标记的数据集相比，上述方法可以为模型带来一些改进，但性能的提高通常不是很令人印象深刻。 此外，在实践中，模型的质量甚至可以降低。 这取决于数据来源的统计分布的属性，我们通常不知道。

另一方面，神经网络学习的最新进展带来了一些令人印象深刻的结果。 例如，据显示，对于某些数据集，例如MNIST（计算机视觉中的频繁测试平台，由0到9的手写数字标记图像组成），以半监督方式训练的模型具有几乎完美的性能 每个类别10个标记的示例（总共100个标记的示例）。 为了比较，MNIST包含70,000个标记示例（60,000个用于训练，10,000个用于测试）。 获得如此卓越性能的神经网络架构称为梯形网络。 要了解梯形网络，您必须了解自动编码器的含义。

自动编码器是具有编码器 - 解码器架构的前馈神经网络。 它经过培训可以重建其输入。 所以训练样例是一对$(x，x)$。 我们希望模型$f(x)$的输出x尽可能类似于输入$x$。

![7-9](https://github.com/apachecn/ml-book-100-zh/blob/master/doc/img/7-9.png)

这里一个重要的细节是自动编码器的网络看起来像一个沙漏，中间有一个瓶颈层，包含D维输入向量的嵌入; 嵌入层通常具有比D少得多的单元。解码器的目标是从该嵌入重构输入特征向量。 从理论上讲，在瓶颈层中有10个单元来成功编码MNIST图像是非常有用的。 在典型的自动编码器中，如图所示。 在图6中，成本函数通常是均方误差（当特征可以是任何数字时）或负对数似然（当特征是二进制并且解码器的最后一层的单位具有S形激活函数时）。 如果成本是均方误差，则由下式给出：$\frac{1}{N} \sum_{i=1}^{N}\left\|\mathbf{x}_{i}-f\left(\mathbf{x}_{i}\right)\right\|^{2}$，其中$\left\|\mathbf{x}_{i}-f\left(\mathbf{x}_{i}\right)\right\|$是两个向量之间的欧几里德距离

去噪自动编码器通过向特征添加一些随机扰动来破坏训练示例$(x,x)$中的左侧$x$。 如果我们的示例是具有表示为0和1之间的值的像素的灰度图像，则通常将普通高斯噪声添加到每个特征。 对于输入特征向量x的每个特征$j$，噪声值$n^{(j)}$从以下分布中采样：$n^{(j)} \sim \frac{1}{\sigma \sqrt{2 \pi}} \exp \left(-\frac{(-\mu)^{2}}{2 \sigma^{2}}\right)$,其中符号$〜$表示“从中采样”，$π$是常数3.14159 ...而$μ$是必须调整的超参数。 特征$x^{(j)}$的新的，损坏的值由$x^{(j)}+ n{(j)}$给出。

梯形网络是一种具有升级功能的去噪自动编码器。 编码器和解码器具有相同的层数。 瓶颈层直接用于预测标签（使用softmax激活功能）。 该网络具有多种成本功能。 对于编码器的每个层$l$和解码器的对应层$l$，一个成本$C_{d}^{l}$惩罚两个层的输出之间的差异（使用平方欧几里德距离）。 当在训练期间使用标记示例时，另一个成本函数$C_{c}$惩罚标签预测中的误差（使用负对数似然成本函数）。 组合的成本函数$C_{c}+\sum_{l=1}^{L} \lambda_{l} C_{d}^{l}$（在批次中的所有实例上平均）通过随后的梯度下降与反向传播来优化。 每个层$l$的超参数$λ_{l}$确定分类和编码 - 解码成本之间的交换。

在梯形网络中，不仅输入被噪声破坏，而且每个编码器层的输出（在训练期间）也被破坏。 当我们将训练的模型应用于新输入$x$以预测其标签时，我们不会破坏输入。

存在与训练神经网络无关的其他半监督学习技术。 其中一个意味着使用标记数据构建模型，然后使用任何聚类技术将未标记和标记的示例聚集在一起（我们在第9章中考虑其中的一些）。

对于每个新示例，我们然后输出它所属的集群中的多数标签作为预测。 另一种称为S3VM的技术基于使用SVM。 我们为每个可能的未标记示例标记构建一个SVM模型，然后我们选择具有最大边距的模型。 关于S3VM的论文描述了一种方法，该方法允许在不实际枚举所有可能的标签的情况下解决该问题。

## 7.10 单样本学习

这个章节可能完全没有完成任何其他重要的监督学习范式。 其中之一是一次性学习。 在一次性学习中，通常应用于人脸识别，我们想要建立一个模型，可以识别同一个人的两张照片代表同一个人。 如果我们向模特展示两张不同人物的两张照片，我们希望模特能够认识到这两个人是不同的。

构建这种模型的一种方法是训练暹罗神经网络（SNN）。 SNN可以实现为任何类型的神经网络，CNN，RNN或MLP。 重要的是我们如何培训网络。

为了训练SNN，我们使用三重态损失函数。 例如，让我们有三个面部图像：图像$A$（用于锚点），图像$P$（用于正面）和图像$N$（用于负面）。 $A$和$P$是同一个人的两张不同的照片; $N$是另一个人的照片。 每个训练示例i现在是三元组($A_{i}，P_{i}，N_{i}$)。

假设我们有一个神经网络模型$f$，它可以将一张面部图片作为输入并输出该图片的嵌入。 一个例子的三重态损失定义为，$\max \left(\left\|f\left(A_{i}\right)-f\left(P_{i}\right)\right\|^{2}-\left\|f\left(A_{i}\right)-f\left(N_{i}\right)\right\|^{2}+\alpha, 0\right)$   (3)

成本函数定义为平均三重损失：$\frac{1}{N} \sum_{i=1}^{N} \max \left(\left\|f\left(A_{i}\right)-f\left(P_{i}\right)\right\|^{2}-\left\|f\left(A_{i}\right)-f\left(N_{i}\right)\right\|^{2}+\alpha, 0\right)$,其中$α$是正超参数。 直观地，当我们的神经网络为$A$和$P$输出类似的嵌入向量时，$\|f(A)-f(P)\|^{2}$是低的; 当两个不同人物的图片嵌入不同时，$\left\|f\left(A_{i}\right)-f\left(N_{i}\right)\right\|^{2}$很高。如果我们的模型以我们想要的方式工作，则术语$m=\left\|f\left(A_{i}\right)-f\left(P_{i}\right)\right\|^{2}-\left\|f\left(A_{i}\right)-f\left(N_{i}\right)\right\|^{2}$将始终为负，因为我们从较小的值中减去一个高值。 通过将$α$设置得更高，我们强制使用该术语$m$要更小，以确保模型学会识别两个相同的面和两个具有高边距的不同面。 如果$m$不够小，那么由于$α$，成本将为正，并且模型参数将在反向传播中进行调整。

不是随机选择N的图像，而是为训练创建三元组的更好方法是在几个学习时期之后使用当前模型，并根据该模型找到与$A$和$P$类似的$N$的候选者。 使用随机例子作为$N$会显着减慢训练速度，因为神经网络很容易看到两个随机人物的图像之间的差异，因此大多数时候平均三胞胎损失会很低，而且参数的更新速度也不够快。

为了构建SNN，我们首先决定我们的神经网络的架构。 例如，如果我们的输入是图像，CNN是典型的选择。 举一个例子，为了计算平均三重态损失，我们连续地将模型应用于$A$，然后应用于$P$，然后应用于$N$，然后我们使用等式3计算该示例的损失。 我们对批次中的所有三元组重复这一点，然后计算成本; 具有反向传播的梯度下降通过网络传播成本以更新其参数。

这是一种常见的误解，对于一次性学习，我们只需要每个实体的一个例子进行训练。 在实践中，我们需要每个人的一个以上的例子，以使人识别模型准确。 它被称为一次性，因为这种模型的应用最频繁：基于面部的身份验证。 例如，这种模型可用于解锁手机。 如果你的模型很好，那么你只需要在你的手机上有一张你的照片，它就会认出你，而且它会认出别人不是你。 当我们有模型时，为了确定两张图片$A$和是$\hat{A}$否属于同一个人，我们检查$\|f(A)-f(\hat{A})\|^{2}$是否小于某个阈值$τ$，这是模型的另一个超参数。

## 7.11 零样本学习

我们通过零样本学习来完成本章。 这是一个相对较新的研究领域，而且还提出了一个尚未实现实用性的算法。 因此，我只在此概述基本思想，并留下各种算法的细节以供进一步阅读。 在零样本学习（ZSL）中，我们想要训练模型以将标签分配给对象。 最常见的应用是学习为图像分配标签。

但是，我们希望模型能够预测我们在训练数据中没有的标签。 怎么可能？

诀窍是使用嵌入不仅代表输入$x$而且代表输出$y$。 想象一下，我们有一个模型，对于英语中的任何单词都可以生成具有以下属性的嵌入向量：如果单词yi与单词yk具有相似的含义，则这两个单词的嵌入向量将是相似的。 例如，如果$y_{i}$是Paris而$y_{k}$是Rome，那么它们将具有类似的嵌入; 另一方面，如果$y_{k}$是马铃薯，那么$y_{i}$和$y_{k}$的嵌入将是不同的。 这种嵌入向量称为“字嵌入”，它们通常使用余弦相似度量度进行比较。

词嵌入向量具有这样的属性，即嵌入的每个维度代表单词含义的特定特征。 例如，如果我们的单词嵌入有四个维度（通常它们更宽，在50到300维之间），那么这四个维度可以代表asanimalness，abstractness，sourness和yellowness这些含义的特征（是的，听起来很有趣，但是 这只是一个例子）。 所以蜜蜂这个词就像这个[1,0,0,1]那样嵌入，像这样的[0,1,0,1]这个单词是黄色，像这样的单词[1,1,0,0]。 每个嵌入的值是使用应用于大文本语料库的特定训练过程获得的。

现在，在我们的分类问题中，我们可以使用词嵌入替换我们训练集中每个示例$i$的标签$y_{i}$，并训练预测单词嵌入的多标签模型。 为了获得新示例$x$的标签，我们将模型$f$应用于$x$，得到嵌入$\hat{\mathbf{y}}$，然后在所有英语单词中搜索嵌入与$\hat{\mathbf{y}}$最相似的那些使用余弦相似性的单词。

为什么这样做？ 以斑马为例。 它是白色的，它是一种哺乳动物，它有条纹。 拿一个小丑，它是橙色的，不是哺乳动物，有条纹。 现在拿一只老虎：它是橙色的，它有条纹，它是一种哺乳动物。 如果在字嵌入中存在这三个特征，则CNN将学习在图片中检测这些相同的特征。 即使标签虎没有出现在训练数据中，但其他物体包括斑马和小丑，那么CNN很可能会学习哺乳动物，橙色和条纹的概念来预测这些物体的标签。 一旦我们将老虎的图片呈现给模型，这些特征将从图像中正确识别，并且很可能从我们的英语词典嵌入到预测嵌入的最接近的词将是老虎的。





