![]() |
OpenCV 4.12.0
开源计算机视觉
|
在机器学习算法中,存在训练数据的概念。训练数据包括几个组成部分
如您所见,训练数据可能具有相当复杂的结构;此外,它可能非常大和/或并非完全可用,因此需要对此概念进行抽象。在 OpenCV ml 中,为此有一个 cv::ml::TrainData 类。
这种简单的分类模型假设每个类别的特征向量都呈正态分布(尽管不一定是独立分布的)。因此,整个数据分布函数被假定为高斯混合模型,每个类别一个分量。该算法利用训练数据估计每个类别的均值向量和协方差矩阵,然后使用它们进行预测。
该算法缓存所有训练样本,并通过分析样本的特定数量(K)最近邻居,使用投票、计算加权和等方式来预测新样本的响应。该方法有时被称为“通过示例学习”,因为在预测时,它会寻找具有已知响应且最接近给定向量的特征向量。
最初,支持向量机(SVM)是一种构建最优二元(2类)分类器的技术。后来,该技术扩展到回归和聚类问题。SVM是基于核方法的特例。它使用核函数将特征向量映射到更高维空间,并在此空间中构建最优线性判别函数或与训练数据拟合的最优超平面。在SVM的情况下,核函数没有明确定义。相反,需要定义超空间中任意2点之间的距离。
该解决方案是最优的,这意味着分离超平面与来自两个类(在2类分类器的情况下)的最近特征向量之间的间隔最大。最接近超平面的特征向量被称为支持向量,这意味着其他向量的位置不影响超平面(决策函数)。
OpenCV 中的 SVM 实现基于 [51]
应使用 StatModel::predict(samples, results, flags)。传递 flags=StatModel::RAW_OUTPUT 以获取 SVM 的原始响应(在回归、1类或2类分类问题中)。
本节讨论的 ML 类实现了 [41] 中描述的分类与回归树算法。
类 cv::ml::DTrees 表示单个决策树或决策树的集合。它也是 RTrees 和 Boost 的基类。
决策树是一种二叉树(每个非叶节点有两个子节点的树)。它既可以用于分类,也可以用于回归。对于分类,每个树叶都标有类别标签;多个叶子可以具有相同的标签。对于回归,每个树叶也被赋一个常数,因此近似函数是分段常数。
为了到达叶节点并获得输入特征向量的响应,预测过程从根节点开始。从每个非叶节点,过程根据存储在观察节点中的某个变量的值,向左(选择左子节点作为下一个观察节点)或向右。可能的变量如下:
因此,在每个节点中,使用一对实体(variable_index,决策规则(阈值/子集))。这对实体被称为一个分裂(基于变量variable_index进行分裂)。一旦到达叶节点,赋给该节点的值将用作预测过程的输出。
有时,输入向量的某些特征可能会丢失(例如,在黑暗中很难确定物体颜色),预测过程可能会卡在某个节点上(在上述示例中,如果节点按颜色划分)。为了避免这种情况,决策树使用所谓的代理分裂。也就是说,除了最佳的“主要”分裂之外,每个树节点还可以根据一个或多个其他变量进行分裂,这些变量会产生几乎相同的结果。
树是从根节点开始递归构建的。所有训练数据(特征向量和响应)都用于分裂根节点。在每个节点中,根据某些标准找到最优决策规则(最佳“主要”分裂)。在机器学习中,分类使用基尼“纯度”标准,回归使用平方误差和。然后,如有必要,找到代理分裂。它们类似于训练数据上的主要分裂结果。所有数据都使用主要分裂和代理分裂(就像在预测过程中所做的那样)在左、右子节点之间进行划分。然后,该过程递归地分裂左右节点。在每个节点,递归过程可以在以下任一情况下停止(即停止进一步分裂节点):
当树构建完成后,如有必要,可以使用交叉验证程序对其进行剪枝。也就是说,可能导致模型过拟合的某些树分支会被剪除。通常,此过程仅应用于独立的决策树。树集成模型通常会构建足够小的树,并使用其自身的保护机制来防止过拟合。
除了作为决策树的明显用途的预测之外,决策树还可以用于各种数据分析。构建的决策树算法的关键特性之一是能够计算每个变量的重要性(相对决定能力)。例如,在垃圾邮件过滤器中,如果使用消息中出现的词汇集合作为特征向量,则变量重要性评级可用于确定最“指示垃圾邮件”的词汇,从而有助于保持字典大小合理。
每个变量的重要性是根据树中该变量的所有分裂(主要分裂和代理分裂)计算的。因此,为了正确计算变量重要性,即使没有缺失数据,也必须在训练参数中启用代理分裂。
常见的机器学习任务是监督学习。在监督学习中,目标是学习输入 \(x\) 和输出 \(y\) 之间的函数关系 \(F: y = F(x)\) 。预测定性输出称为分类,而预测定量输出称为回归。
提升法是一个强大的学习概念,为监督分类学习任务提供了解决方案。它结合了许多“弱”分类器的性能,以产生一个强大的委员会 [276]。弱分类器只要求比随机猜测好,因此可以非常简单且计算成本低。然而,许多弱分类器能够巧妙地组合结果,形成一个强大的分类器,其性能通常优于大多数“单体”强分类器,如 SVM 和神经网络。
决策树是提升法方案中最常用的弱分类器。通常,每棵树只有一个分裂节点的最简单决策树(称为“树桩”)就足够了。
提升模型基于 \(N\) 个训练样本 \({(x_i,y_i)}1N\) ,其中 \(x_i \in{R^K}\) 且 \(y_i \in{-1, +1}\) 。 \(x_i\) 是一个 \(K\) 维向量。每个分量编码与当前学习任务相关的特征。所需的二分类输出编码为 -1 和 +1。
提升法的不同变体包括离散 Adaboost、实值 AdaBoost、LogitBoost 和 Gentle AdaBoost [97]。它们在总体结构上都非常相似。因此,本章仅关注下面概述的标准两类离散 AdaBoost 算法。最初为每个样本分配相同的权重(步骤 2)。然后,在加权训练数据上训练一个弱分类器 \(f_{m(x)}\) (步骤 3a)。计算其加权训练误差和缩放因子 \(c_m\) (步骤 3b)。对被错误分类的训练样本增加权重(步骤 3c)。然后对所有权重进行归一化,寻找下一个弱分类器的过程继续进行 \(M\) -1 次。最终分类器 \(F(x)\) 是各个弱分类器加权和的符号(步骤 4)。
两类离散 AdaBoost 算法
为了减少提升模型的计算时间,同时不显著降低精度,可以使用影响修剪技术。随着训练算法的进行和集成中树的数量增加,更多的训练样本被正确分类并具有更高的置信度,因此这些样本在后续迭代中获得较小的权重。相对权重非常低的示例对弱分类器训练的影响很小。因此,在弱分类器训练期间可以排除这些示例,而不会对生成的分类器产生太大影响。此过程由 weight_trim_rate 参数控制。在弱分类器训练中,仅使用总权重质量中总结分数 weight_trim_rate 的示例。请注意,所有训练示例的权重在每次训练迭代时都会重新计算。在特定迭代中删除的示例可以在后续学习某些弱分类器时再次使用 [97]
应使用 StatModel::predict(samples, results, flags)。传递 flags=StatModel::RAW_OUTPUT 以获取 Boost 分类器的原始和。
随机树由 Leo Breiman 和 Adele Cutler 引入:http://www.stat.berkeley.edu/users/breiman/RandomForests/。该算法可以处理分类和回归问题。随机树是树预测器的一个集合(集成),在本节中称为森林(该术语也由 L. Breiman 引入)。分类工作方式如下:随机树分类器接收输入特征向量,使用森林中的每棵树对其进行分类,并输出获得多数“投票”的类别标签。在回归的情况下,分类器响应是森林中所有树的响应平均值。
所有树都使用相同的参数进行训练,但训练集不同。这些集合是使用自助法(bootstrap)从原始训练集生成的:对于每个训练集,您随机选择与原始集合相同数量的向量(=N)。向量是带替换抽样的。也就是说,某些向量会出现多次,而某些向量会缺失。在每棵训练树的每个节点,并非所有变量都用于寻找最佳分裂,而是使用它们的随机子集。每个节点都会生成一个新的子集。但是,其大小对于所有节点和所有树都是固定的。它是一个训练参数,默认设置为 \(\sqrt{变量数量}\) 。所有构建的树都不会被剪枝。
在随机树中,无需任何精度估计程序,例如交叉验证或自助法,也无需单独的测试集来估计训练误差。误差在训练期间内部估计。当通过有放回抽样抽取当前树的训练集时,会留下一些向量(即所谓的袋外(oob)数据)。oob 数据的大小约为 N/3。分类误差通过以下方式使用此 oob 数据进行估计:
有关随机树的使用示例,请参阅 OpenCV 发行版中的 letter_recog.cpp 示例。
参考文献
期望最大化(EM)算法估计具有指定混合数量的高斯混合分布形式的多元概率密度函数参数。
考虑从高斯混合分布中抽取的 d 维欧几里得空间中的 N 个特征向量集合 { \(x_1, x_2,...,x_{N}\) }
\[p(x;a_k,S_k, \pi _k) = \sum _{k=1}^{m} \pi _kp_k(x), \quad \pi _k \geq 0, \quad \sum _{k=1}^{m} \pi _k=1,\]
\[p_k(x)= \varphi (x;a_k,S_k)= \frac{1}{(2\pi)^{d/2}\mid{S_k}\mid^{1/2}} exp \left \{ - \frac{1}{2} (x-a_k)^TS_k^{-1}(x-a_k) \right \} ,\]
其中 \(m\) 是混合数,\(p_k\) 是均值为 \(a_k\) 且协方差矩阵为 \(S_k\) 的正态分布密度,\(\pi_k\) 是第 k 个混合的权重。给定混合数 \(M\) 和样本 \(x_i\), \(i=1..N\),算法寻找所有混合参数 \(a_k\), \(S_k\) 和 \(\pi_k\) 的最大似然估计(MLE)
\[L(x, \theta )=logp(x, \theta )= \sum _{i=1}^{N}log \left ( \sum _{k=1}^{m} \pi _kp_k(x) \right ) \to \max _{ \theta \in \Theta },\]
\[\Theta = \left \{ (a_k,S_k, \pi _k): a_k \in \mathbbm{R} ^d,S_k=S_k^T>0,S_k \in \mathbbm{R} ^{d \times d}, \pi _k \geq 0, \sum _{k=1}^{m} \pi _k=1 \right \} .\]
EM 算法是一个迭代过程。每次迭代包括两个步骤。在第一步(期望步或 E 步)中,您使用当前可用的混合参数估计值找到样本 i 属于混合 k 的概率 \(p_{i,k}\) (在下面的公式中表示为 \(\alpha_{i,k}\) )
\[\alpha _{ki} = \frac{\pi_k\varphi(x;a_k,S_k)}{\sum\limits_{j=1}^{m}\pi_j\varphi(x;a_j,S_j)} .\]
在第二步(最大化步或 M 步)中,使用计算出的概率来细化混合参数估计值
\[\pi _k= \frac{1}{N} \sum _{i=1}^{N} \alpha _{ki}, \quad a_k= \frac{\sum\limits_{i=1}^{N}\alpha_{ki}x_i}{\sum\limits_{i=1}^{N}\alpha_{ki}} , \quad S_k= \frac{\sum\limits_{i=1}^{N}\alpha_{ki}(x_i-a_k)(x_i-a_k)^T}{\sum\limits_{i=1}^{N}\alpha_{ki}}\]
或者,当可以提供 \(p_{i,k}\) 的初始值时,算法可以从 M 步开始。当 \(p_{i,k}\) 未知时的另一种替代方法是使用更简单的聚类算法对输入样本进行预聚类,从而获得初始 \(p_{i,k}\) 。通常(包括机器学习),k-means 算法用于此目的。
EM 算法的主要问题之一是要估计的参数数量庞大。大多数参数存在于协方差矩阵中,每个协方差矩阵都是 \(d \times d\) 个元素,其中 \(d\) 是特征空间的维度。然而,在许多实际问题中,协方差矩阵接近对角矩阵甚至 \(\mu_k*I\) ,其中 \(I\) 是单位矩阵,\(\mu_k\) 是依赖于混合的“尺度”参数。因此,一个稳健的计算方案可以从对协方差矩阵施加更严格的约束开始,然后将估计的参数作为输入用于约束较少的优化问题(通常对角协方差矩阵已经是一个足够好的近似)。
参考文献
ML 实现了前馈人工神经网络,或者更具体地说,多层感知器(MLP),这是最常用的神经网络类型。MLP 由输入层、输出层和一个或多个隐藏层组成。MLP 的每一层都包含一个或多个神经元,它们与前一层和下一层的神经元定向连接。下面的示例表示一个3层感知器,具有三个输入、两个输出,以及一个包含五个神经元的隐藏层
MLP 中的所有神经元都相似。每个神经元都有多个输入连接(它将前一层中多个神经元的输出值作为输入)和多个输出连接(它将响应传递给下一层中的多个神经元)。从前一层检索到的值会与特定权重(每个神经元独有)以及偏置项相加。总和通过激活函数 \(f\) 进行转换,该函数对于不同神经元也可能不同。
换句话说,给定层 \(n\) 的输出 \(x_j\) ,层 \(n+1\) 的输出 \(y_i\) 计算如下:
\[u_i = \sum _j (w^{n+1}_{i,j}*x_j) + w^{n+1}_{i,bias}\]
\[y_i = f(u_i)\]
可以使用不同的激活函数。ML 实现了三种标准函数
在 ML 中,所有神经元都具有相同的激活函数,并具有相同的自由参数( \(\alpha, \beta\) ),这些参数由用户指定且不受训练算法更改。
因此,整个训练好的网络工作方式如下:
因此,要计算网络,您需要知道所有权重 \(w^{n+1)}_{i,j}\) 。权重由训练算法计算。该算法接收一个训练集,其中包含多个输入向量及其对应的输出向量,并迭代调整权重,以使网络能够对所提供的输入向量给出期望的响应。
网络规模(隐藏层数量及其大小)越大,潜在的网络灵活性就越大。训练集上的误差可以做得任意小。但同时,学习到的网络也会“学习”训练集中存在的噪声,因此在网络规模达到一定限制后,测试集上的误差通常会开始增加。此外,大型网络的训练时间远长于小型网络,因此合理的数据预处理是必要的,可以利用 cv::PCA 或类似技术,只在基本特征上训练一个较小的网络。
MLP 的另一个特点是无法直接处理分类数据。然而,有一种变通方法。如果输入或输出层中的某个特征(对于 \(n>2\) 的 n 类分类器)是分类的,并且可以取 \(M>2\) 个不同的值,则将其表示为 M 个元素的二元组是有意义的,其中第 i 个元素当且仅当该特征等于 M 个可能值中的第 i 个值时为 1。这会增加输入/输出层的大小,但会加快训练算法的收敛速度,同时允许这些变量的“模糊”值,即一组概率而不是固定值。
ML 实现了两种训练 MLP 的算法。第一种算法是经典的随机序列反向传播算法。第二种(默认)是批量 RPROP 算法。
ML 实现了逻辑回归,这是一种概率分类技术。逻辑回归是一种二分类算法,与支持向量机 (SVM) 密切相关。与 SVM 类似,逻辑回归可以扩展到处理多类分类问题,例如数字识别(即从给定图像中识别 0、1、2、3 等数字)。此版本的逻辑回归支持二分类和多分类(对于多分类,它会创建多个两类分类器)。为了训练逻辑回归分类器,使用了批量梯度下降和迷你批量梯度下降算法(参见 http://en.wikipedia.org/wiki/Gradient_descent_optimization)。逻辑回归是一种判别式分类器(更多详情请参见 http://www.cs.cmu.edu/~tom/NewChapters.html)。逻辑回归在 LogisticRegression 中作为 C++ 类实现。
在逻辑回归中,我们尝试优化训练参数 \(\theta\) ,以实现假设 \(0 \leq h_\theta(x) \leq 1\) 。我们有 \(h_\theta(x) = g(h_\theta(x))\) 且 \(g(z) = \frac{1}{1+e^{-z}}\) 作为逻辑或 S 形函数。“逻辑回归”中的“逻辑”一词即指此函数。对于给定类别 0 和 1 的二分类问题数据,如果 \(h_\theta(x) \geq 0.5\) 则可以确定给定数据实例属于类别 1,如果 \(h_\theta(x) < 0.5\) 则属于类别 0。
在逻辑回归中,选择正确的参数对于减少训练误差和确保高训练精度至关重要
逻辑回归分类器的训练参数示例如下初始化: