迈向机器学习的第一步从这里开始!

本文要点:

  • 多项式拟合;
  • 贪心随机训练;
  • 径向基函数(RBF function);
  • 径向基函数网络模型(RBF Network Model)。

从前面几章我们知道,机器学习算法的一般形式是接受出入向量,生成输出向量。要把输入向量变换到输出向量,还要用到另外两个向量,这两个额外的向量分别叫作“长期记忆”和“短期记忆”。长期记忆又被称为“权重”或“系数”,是通过训练来调整的;短期记忆则并非所有的机器学习算法都需要用到。

把机器学习算法想成是一个函数可能会有助于理解。为了便于演示,我们假设式7-1所示的简单等式是一个机器学习算法。

![{f(x) = 5x}](http://private.codecogs.com/gif.latex?{f(x%29%20=%205x})

(7-1)

此处我们假设x是一个单值标量,而非一个向量;值5则是一个系数。通常来说,系数会被组合成一个向量的形式,用以表示算法的“长期记忆”。当我们对式7-1所示的机器学习算法进行训练的时候,我们会调整系数直到得到预期输出。如果清单7-1所示是式7-1对应算法的训练数据,那么就可以向式7-1提供输入,并对其输出结果进行评估。

清单7-1 简单训练数据

Input: [1], Desired Output: [7]
Input: [2], Desired Output: [14]
Input: [3], Desired Output: [21]

显然系数5无法产生预期输出。根据第6章所讲的内容,我们可以计算上述预期输出和式7-1的实际输出之间的误差,比如式7-1的输入为1,则实际输出为5,而对应的预期输出却是7。

要为机器学习算法搜寻适当的系数有许多种不同的方法,并且调整系数的方法也是机器学习的主要研究领域。

如果机器学习算法是一个如式7-1的线性函数,一般会用精确的数学方法来求合适的系数。就本例而言,我们只需找到乘以1后所得结果为7的系数即可,因此系数就是7。并且系数为7的话,对训练集中的其他数据误差也为0。

并非所有的数据集都像清单7-1这么简单,事实上,能够通过拟合系数(长期记忆向量)得到完全零误差的情况是十分少见的,因为大多数数据包含了噪声。所谓“噪声”,指的是输入数据中任何不可复现的部分,因此会导致更高的误差。由于噪声的缘故,机器学习算法的目标一般也是“算法在新数据上运行良好”,而不会苛求“零误差”。

如果得到了零误差的结果,反而应该怀疑是否出现了过拟合现象。过拟合现象的出现是由于机器学习算法已经完全“记住”了训练数据,这种情况下,算法已经不再提取特征,转而仅仅重复调用记忆好的输入向量,因此过拟合的算法对不在原训练数据集中的新数据不具有良好的表现。

接下来让我们来看看优化系数、降低误差的方法,并且还会介绍一些优化系数的基本算法,第8章则会讨论像模拟退火算法、Nelder -Mead算法[1]这样更加高级的算法。

本书中出现的大多数训练算法具有通用性,对任何给定的“长期记忆”,这些算法都可以尝试进行优化;但也不是所有的算法都如此,有些训练算法对训练的模型有独特的适用性,在第10章中就可以看到这样的算法。当然,除此以外,本书其他章节中大多数算法是通用算法。

7.1  多项式系数

本节将以一个多项式作为待优化的机器学习算法,来介绍优化多项式系数的通用训练方法。一般来说,要优化的系数比一个简单的多项式更为复杂,但这样的例子可以作为介绍机器学习算法的一个很好的切入点。在一个数据集上拟合多项式,可以有效说明那些复杂的机器学习算法的基本工作原理。

所谓多项式,其实就是由变量和常系数组成的数学表达式,其中的运算只有加法、减法、乘法和正整数的幂运算,式7-2就是一个典型的二次多项式[2]

![f(x) = 2}{x}^2}} + 4x + 6}](http://private.codecogs.com/gif.latex?{f(x%29%20=%202}{x}^2}}%20+%204x%20+%206})
(7-2)

式7-2接受一个值x,返回一个值y,输入、输出向量的大小均为1,式中三个系数分别为:2,4,6。其中,各系数均乘以变量x的幂项,系数2乘以x的平方,系数4乘以x,系数6则乘以x的0次幂,也就是常数1,表现出来就是一个单纯的常数项。

式7-2所示多项式共有3项,每一项对应一个系数,则式(7-2)中的3个系数可以视作一个向量并表示如下:

[2, 4, 6]

就式7-2而言,系数均已确定,但一般情况下系数的值需要使用机器学习算法来确定。要达到这个目的,就需要用包含各种预期输出的训练集来对算法进行训练,其中,不同的预期输出对应于各种不同的输入,这样的训练数据可以经由实验收集。要将这些数据拟合为二次多项式,机器学习算法就很有用处。

接下来让我们先创建一些训练数据。已知所要的解是系数[2, 4, 6],这当然完全是人为设定的,但有助于说明基本训练算法的使用。要生成训练数据,只需迭代多个x的值,并计算出对应的多项式的值即可,然后使用随机的系数来训练,以接近正确的系数。我们将仅使用训练数据,以此来看看能否重新获得正确的系数。

生成的训练数据如清单7-2所示,显然,这是将输入从-50迭代到+50的结果,理想输出由计算得出。

清单7-2 多项式训练数据

[BasicData: input: [-50.0], ideal: [4806.0]]
[BasicData: input: [-49.0], ideal: [4612.0]]
[BasicData: input: [-48.0], ideal: [4422.0]]
...
[BasicData: input: [47.0], ideal: [4612.0]]
[BasicData: input: [48.0], ideal: [4806.0]]
[BasicData: input: [49.0], ideal: [5004.0]]

给定以上数据,接下来看看如何调整系数以产生这些数。下一节要介绍的是如何使用清单7-2所示的数据来重建式7-2所示的多项式——当然,首先要假定我们并不知道实际的多项式,所有的条件仅仅是清单7-2中的数据。

7.2  训练入门

在训练期间调整一个机器学习算法的长期记忆的方法有很多,在本节中,我们将介绍的是“贪心随机训练算法”,这个算法实现起来很简单。在第8章中,我们将会介绍适应性和稳定性更强的训练算法,这些更加强健的训练算法能够比贪心随机训练法更快地找到“长期记忆”的最优值。

贪心随机训练算法

贪心随机训练算法实现起来尤其简单,概括起来基本上就是为长期记忆向量随机选取一组值。算法的“贪心”之处在于它只保存到当前为止效果最好的一组长期记忆值,如果新的长期记忆值比上一组性能更优,毫无疑问算法会选择保存新的这一组值而丢弃之前的值,这一算法有时也被称作“随机漫步算法”。

这一算法可以用如清单7-3所示的伪代码表示。

清单7-3 贪心随机训练算法(最小性能版本)

function iteration(
 ltm, // 当前的长期记忆向量
 lowRange, // 随机范围的最小值
 highRange //随机范围的最大值
)
{
 // 评估当前状态的性能
 oldScore = calculateScore(ltm);
 // 保存当前状态的副本
 // 以免性能提升失败
 len = ltm.length;
 oldLtm = ltm.clone();

 // 随机设置一个状态
 for i from 0 to len
 {
  ltm[i] = rand(lowRange, highRange);
 }
 // 对新的随机状态进行评估
 newScore = calculateScore(ltm);
 // 贪心判定。新的随机状态相对上一个状态是否有性能上的提升?
 // 如果没有,则恢复上一个状态
 if(newScore>oldScore)
 {
  ltm = oldLtm.clone();2
 }
}

上述代码实现了贪心随机训练算法的一个迭代,传递的参数共有3个。

  • 参数1:要优化的长期记忆向量;
  • 参数2和参数3:给长期记忆向量中各元素赋值的随机范围上下限。

迭代函数把随机值赋给长期记忆向量,将随机赋值前后的评估得分进行比较,如果得分没有下降,则丢弃新的长期记忆值并恢复上一个状态的长期记忆值。算法只接受性能有所改善的结果,这正是算法被称作“贪心”的原因,却并非总是最佳策略。俗话说得好,“退步原来是向前”,偶尔在性能上适当地妥协可能会在之后得到更佳的结果。

无论如何,贪心随机训练算法确实可以对向量值进行训练。对形如式7-2的多项式运行算法,可以得到如下结果:

Iteration #999984, Score = 37.93061791363337,
Iteration #999985, Score = 37.93061791363337,
Iteration #999986, Score = 37.93061791363337,
Iteration #999987, Score = 37.93061791363337,
Iteration #999988, Score = 37.93061791363337,
Iteration #999989, Score = 37.93061791363337,
Iteration #999990, Score = 37.93061791363337,
Iteration #999991, Score = 37.93061791363337,
Iteration #999992, Score = 37.93061791363337,
Iteration #999993, Score = 37.93061791363337,
Iteration #999994, Score = 37.93061791363337,
Iteration #999995, Score = 37.93061791363337,
Iteration #999996, Score = 37.93061791363337,
Iteration #999997, Score = 37.93061791363337,
Iteration #999998, Score = 37.93061791363337,
Iteration #999999, Score = 37.93061791363337,
Iteration #1000000, Score = 37.93061791363337,
Final score: 37.93061791363337
2.0026889363153195xˆ2 + 4.057350732096355x + 9.393343096548456

如上所示,贪心随机训练算法的结果与预期系数相当接近,预期结果是[2,4,6],而算法得到的结果则是[2.002,4.057,9.3933]。

贪心随机训练算法的结果一般被作为一个基准,可以将贪心随机训练算法的结果与要评估的新算法进行比较,如果新算法的表现不比贪心随机训练算法好,就说明新算法的性能堪忧。

7.3  径向基函数网络

上一节中,我们学习了如何优化多项式系数,但大多数机器学习算法比一个简单多项式复杂得多。本节我们就将介绍一种被称为“径向基函数网络[3]”(Radial Basic Function Network,RBF Network)的算法模型,这是一种可以用于回归和分类的统计模型。

径向基函数网络有一个代表“长期记忆”的向量,但不存在“短期记忆”向量,其中“长期记忆”由系数和其他参数组合而成。训练该网络的方法有很多,网络以径向基函数为基本组成结构,并且贪心随机训练算法和爬山算法都可以用于训练这种网络。

第7.3.1节会简单熟悉一下径向基函数的概念,并给出其长期记忆向量具体都由哪些成分组成。

7.3.1 径向基函数

径向基函数是人工智能领域一个非常重要的概念,因为很多人工智能算法都需要用到这种技术。径向基函数也分为许多种不同的类型,本章会介绍其中一部分。

径向基函数关于其在x轴上的中点对称,并在中点处达到最大值,这一最大值称作“峰值”,且峰值一般为1。实际上在径向基函数网络中,峰值总是1,中点则视情况而定。

径向基函数可以是多维的,但无论输入向量是多少维,输出都总是一个标量值。

有很多常见的径向基函数,其中最常用的就是“高斯函数”。图7-1就是对称轴为直线x=0的一维高斯函数图像。

径向基函数通常被用于选择性地放缩数据,高斯函数也不例外。以图7-1为例,如果用这个函数来放缩数据,则中心点处放缩幅值最大,越往x轴正负方向放缩幅值越小。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qWU759Ak-1579520478252)(http://write.epubit.com:9000/api/storage/getbykey/original?key=1911535da53dc0fe365e)]

图7-1 高斯函数

在给出高斯径向基函数的公式之前,先要研究一下多维的情况如何处理。需要注意的是,径向基函数的输入是多维数据,返回的则是一个标量值——这是通过计算径向基函数的输入向量和中心向量之间的距离实现的,其中“距离”记为r。当然,要使计算能够进行,输入向量和中心向量维数必须相同。只要计算出了这个r,接下来就可以计算出对应的径向基函数值了——所有的径向基函数都要用到这个计算出的“距离”r

式7-3即为r的计算公式:

\boldsymbol{r} = |x - {x_i}|

{–:}(7-3)

式7-3中双重竖线的符号表示计算的是“距离”。欧氏距离是径向基函数中最常用的距离概念,但在特殊情况下,也有可能使用其他的距离概念——本书中的示例均使用欧氏距离。因此本书中的r就是指的输入向量x和中心向量xi之间的欧氏距离,本节所有径向基函数中的“距离”r均由式7-3计算得出。

高斯径向基函数的公式如式7-4所示:

![\boldsymbol{\phi} \left( \boldsymbol{r} \right) = {\text{e}^{ - {\boldsymbol{r}2}}}](http://private.codecogs.com/gif.latex?\boldsymbol{\phi}%20\left(%20\boldsymbol{r}%20\right%29%20=%20{\text{e}{%20-%20{\boldsymbol{r}^2}}})

{–:}(7-4)

只要计算出了r,计算径向基函数的值就很容易了,式7-4中的希腊字母\phi一般用来表示“径向基函数”。

高斯函数并非唯一的径向基函数,还有一些其他的径向基函数,其函数图像也各不相同。如果使用径向基函数来进行数据放缩的话,不同的函数图像则意味着不同的放缩方式。图7-2所示是Ricker小波的函数图像。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enggJ2wP-1579520478259)(http://write.epubit.com:9000/api/storage/getbykey/original?key=19115d9425ecd19e5527)]

图7-2 Ricker小波(墨西哥帽函数)

Ricker小波函数也经常被用作径向基函数,由于其函数图像与墨西哥的宽边帽形状十分相似,因此又被称作“墨西哥帽函数”,如式7-5所示。

![\boldsymbol{\phi} \left( \boldsymbol{r}\right)=\left(1-r2\right)\cdot\text{e}{-\boldsymbol{r}2/2}](http://private.codecogs.com/gif.latex?\boldsymbol{\phi}%20\left(%20\boldsymbol{r}\right%29=\left(1-r2\right%29\cdot\text{e}{-\boldsymbol{r}2/2})

{–:}(7-5)

从图7-2可以看出,Ricker小波函数实际上是在两边进行负向放缩,继续增大“距离”r的绝对值则放缩幅度逐渐回归到0值。

不同的径向基函数适用于不同的情况,还有一些常用的径向基函数包括:

  • 多二次函数(Multiquadric);
  • 逆二次函数(Inverse quadratic);
  • 逆多二次函数(Inverse multiquadric);
  • 多重调和样条(Polyharmonic spline);
  • 薄板样条(Thin plate spline)。

使用径向基函数可以实现被称作“径向基函数网络”的统计模型,并且可以使用任何此前讨论过的方法来训练这个模型。

7.3.2 径向基函数网络

径向基函数网络是一种既可以用于分类问题,也可以用于回归问题的统计模型。该网络本质上就是一至多个径向基函数的加权求和,其中每个径向基函数均接受一个带权重的输入,从而对输出进行预测。式7-6描述了一个径向基函数网络:

![f\left( \boldsymbol{X} \right) = \mathop \sum \limits_{i = 1}^N {a_i}p\left(|{{b_i}X - {c_i}}|\right)](http://private.codecogs.com/gif.latex?f\left(%20\boldsymbol{X}%20\right%29%20=%20\mathop%20\sum%20\limits_{i%20=%201}^N%20{a_i}p\left(|{{b_i}X%20-%20{c_i}}|\right%29)

{–:}(7-6)

注意其中双竖线表示运算结果是“距离”,但并未规定计算距离的算法,也就是说选取哪种距离参与运算需要视情况而定。上式中X指的是输入向量;c是径向基函数的中心向量;p是所选的径向基函数(比如高斯函数);a是每个径向基函数对应的系数,一般为向量形式,也称“权重”;b则是每个输入对应的权重系数。本章稍后会给出式7-6对应的伪代码实现。

下面以鸢尾花数据集为例,应用径向基函数网络,图7-3即为该网络的图形化表示。

图7-3所示的网络有4项输入(包括花萼宽、花萼长、花瓣宽、花瓣长),分别对应于描述鸢尾花种属的各项特征。为简单起见,图7-3中假定3个鸢尾花种属的编码方式为独热编码法;当然也可以用等边编码法,不过输出项就应该只有两个了。示例中需要选取3个径向基函数——这一选择没有什么限制条件,全凭个人喜好。增加径向基函数的数目能够使模型学习更加复杂的数据集,但也会耗费更多的时间。

图7-3中的箭头代表的是式7-6中全部的系数:输入和径向基函数之间的箭头表示的是式7-6中的系数b;径向基函数和求和号之间的箭头则表示系数a。可能你也注意到了图7-3中的“偏置框”,这是人为添加的一个返回值总是1的函数;由于输出是一个常数,因此也就不需要输入。偏置项到求和号之间的权重起着类似于线性回归中“截距”的作用,因此偏置的存在并不总是坏事儿,在本例中,偏置就是径向基函数网络的一个重要组成部分。在神经网络中,也经常会用到“偏置节点”。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uGSYOIMW-1579520478278)(http://write.epubit.com:9000/api/storage/getbykey/original?key=191171c6fa085bd0c529)]

图7-3 以鸢尾花数据集为输入的径向基函数网络

从图7-3中的求和号有多个可以看出,这是一个分类问题,几个求和运算的最大值所对应项即预测结果。而如果是一个回归问题,则输出应当只有一项。该输出即回归问题的预测结果。

你肯定注意到了图7-3中的偏置节点,其所在位置与径向基函数同一层级,就像是另一个径向基函数,只不过不像径向基函数那样需要接受输入而已。这个偏置节点总是输出常数1,然后这个1再乘以对应的系数,就相当于无论输入是什么情况,都把对应系数直接加到了输出项中。尤其在输入为0的时候,偏置节点就会很有用,因为它使得即使输入为0,径向基函数层也依然有值可以输出。

径向基函数网络的长期记忆向量由几个不同的部分组成:

  • 输入系数;
  • 输出系数(求和系数);
  • 径向基函数放缩范围(在各维度上范围相同);
  • 径向基函数中心向量。

径向基函数网络把这所有的元素保存为一个向量,这个向量即为该径向基函数网络的“长期记忆向量”。稍后我们会使用贪心随机训练算法或爬山算法来训练网络,以使其长期记忆向量的值达到能够根据提供的特征数据正确判断鸢尾花类别的程度。

这个模型的工作原理与此前的多项式相差无几,仅有的不同在于表达式更加复杂,因为现在需要计算多个输出值以及径向基函数的函数值了。

7.3.3 实现径向基函数网络

本节要给出作为示例的径向基函数网络中,两个主要函数的伪代码实现。首先来看径向基函数网络的初始化函数,该函数的主要作用是在生成径向基函数的时候,给网络分配长期记忆向量。要创建一个径向基函数网络,需要提供下列3项信息:

  • 输入通道数目;
  • 径向基函数数目;
  • 输出通道数目。

输入和输出的数目决定于输入和输出向量的大小,对于选定数据集,这些值也是给定的。径向基函数的数目就稍微主观一些,使用的径向基函数越多,模型得到预期结果的性能就越好,但同时也会导致模型的时间效率下降。

清单7-4给出了初始化一个径向基函数网络的伪代码。

清单7-4 初始化径向基函数网络

function initRBFNetwork(
 theInputCount, // 网络的输入通道数目
 rbfCount, // 网络中径向基函数的数目
 theOutputCount // 网络的输出通道数目
)
{
 result = new RBFNetwork();
 // 给该网络设置几个简单的参数
 result.inputCount = theInputCount;
 result.outputCount = theOutputCount;
 // 计算输入和输出权重的数目
 // 由于额外的偏置节点,因此要在输出中加1
 inputWeightCount = inputCount∗rbfCount;
 outputWeightCount = (rbfCount + 1) ∗outputCount;
 rbfParams = (inputCount + 1) ∗rbfCount;
 // 为长期记忆向量分配足够的空间
 result.longTermMemory = alloc(inputWeightCount
 + outputWeightCount + rbfParams);
 // 设置网络的其他参数
 result.indexInputWeights = 0;
 result.indexOutputWeights = inputWeightCount + rbfParams;
 // 分配径向基函数
 result.rbf = new FnRBF[rbfCount];
 // 设置每一个径向基函数
 for i from 0 to rbfCount
 {
 // 获取当前径向基函数(在整个长期记忆向量中)对应的索引
 rbfIndex = inputWeightCount + ((inputCount + 1) ∗i);
 // 分配一个高斯函数,并指定输入数目和
 // 该径向基函数参数在长期记忆向量中的存储位置。
 // 高斯函数的参数是宽度和中心点位置
 result.rbf[i] = new GaussianFunction(
  inputCount, result.longTermMemory, rbfIndex);
 }
 // 返回新生成的网络
 return result;
}

上述方法开头分配了一个名为“result”的对象来保存径向基函数网络,其中保存的内容包括长期记忆向量和网络的其他基本参数。

上述代码精确计算了保存各个系数和径向基函数参数这些长期记忆需要多大的空间,且每个径向基函数都被分配了一段长期记忆对应的存储空间来保存相应的函数参数。本例中,径向基函数的参数是:① 宽度;② 中心点位置。

上述代码实际上并未给长期记忆赋值,因此在网络构造完成之后,一般会赋给一组随机值,称之为“初始化点”。之后,“训练”的过程会调整长期记忆的值,以向能够产生接近预期输出的值靠拢。就本例的鸢尾花数据集而言,输出指的就是网络判断出的输入数据对应的鸢尾花种属。

径向基函数网络构建完毕,且长期记忆设置好之后,就可以开始训练网络了。首先就需要调用径向基函数网络模型,并评估其初始化的输出——由于初始化点是一组随机值,因此最初的输出结果表现不会很好,但训练毕竟还是需要从某组值开始,也就无所谓是不是随机值了。

跟多项式的情况一样,我们也必须计算径向基函数网络的输出,清单7-5中的伪代码就体现了这一计算过程。

清单7-5 计算径向基函数网络的输出

function computeRBFNetwork(
  input,//输入向量
  network // 径向基函数网络
)
{
  // 首先,计算每个径向基函数的输出值
  // 添加一个额外的径向基函数输出值作为偏置
  // (偏置值总为1)
  rbfOutput = alloc(network.rbf.length + 1);
  // 偏置值总为1
  rbfOutput[rbfOutput.length − 1] = 1;
  for rbfIndex from 0 to network.rbf.length
{
   // 输入加权
   weightedInput = alloc(input.length);
   for inputIndex from 0 to input.length
   {
    memoryIndex = network.indexInputWeights
     +(rbfIndex∗network.inputCount) + inputIndex;
    weightedInput[inputIndex] = input[inputIndex]
∗network.longTermMemory[memoryIndex];
  }
  // 计算当前径向基函数的值
  rbfOutput[rbfIndex] =
  network.rbf[rbfIndex].evaluate(weightedInput);
  }
  // 计算输出值
  // 其值为各径向基函数输出的加权结果
  result= alloc(network.outputCount);
  for outputIndex from 0 to result.length
  {
   sum = 0;
   for rbfIndex from 0 to rbfOutput.length
   {
    // 径向基函数个数在原来的基础上加1,作为偏置项
    memoryIndex = network.indexOutputWeights
     +(outputIndex∗(network.rbf.length + 1)) + rbfIndex;
    sum += rbfOutput[rbfIndex]
     ∗network.longTermMemory[memoryIndex];
   }
   result[outputIndex] = sum;
  }
  // 最后,返回计算结果
  return result;
}

上述代码计算出了多层网络的最终输出,下面简单介绍代码逻辑。首先创建名为rbfOutput的变量,顾名思义,该变量用以保存各径向基函数的输出。接下来依次遍历径向基函数,并计算出每个径向基函数的加权输入——所谓“加权输入”,其实就是将输入与径向基函数的输入系数相乘得到的向量。在图7-3中,最左边的一列箭头代表的就是这些输入系数。依次计算出径向基函数的值,就得到了除最后一个元素以外的整个rbfOutput向量,而这最后一个元素作为偏置节点,其值恒为1。

得到rbfOutput向量之后,将其乘以网络的输出系数,也就是图7-3中最右边一列箭头所代表的系数(实际上是中间那一列箭头)。最后把计算出的输出值保存到结果向量中,并将结果向量的值返回给主调函数。

7.3.4 应用径向基函数网络

下面分别给出了在XOR(异或)数据集和鸢尾花数据集上应用径向基函数网络的示例,可以清楚地看到径向基函数是如何拟合数据集的预期输出的。我们先来看看在XOR数据集上,经过随机训练算法训练后模型的输出效果。

Iteration #999996, Score = 0.013418057671024912,
Iteration #999997, Score = 0.013418057671024912,
Iteration #999998, Score = 0.013418057671024912,
Iteration #999999, Score = 0.013418057671024912,
Iteration #1000000, Score = 0.013418057671024912,
Final score:  0.013418057671024912
[0.0, 0.0] −> [−0.16770550224628078], Ideal: [0.0]
[1.0, 0.0] −> [0.9067663351025073], Ideal: [1.0]
[0.0, 1.0] −> [0.8703332321473845], Ideal: [1.0]
[1.0, 1.0] −> [0.0064115711694006094], Ideal: [0.0]

经过大量的迭代,最后终于把评估得分降到了0.01,在上述输出效果中,显然我们略过了大部分的训练迭代,并且从上面的输出也可以看出,实际输出与理想输出并不严格相等。比如第一个输入[0, 0]对应的理想输出是[0],而实际输出则是一个与之相当接近的值,-0.16。理想输出本应均为1的两个输入,对应的实际输出则是与1相近的两个值,分别为0.906和0.87。

在鸢尾花数据集上训练的输出结果如下:

Iteration #99971, Score = 0.08747428121794937,
Iteration #99972, Score = 0.08747428121794937,
Iteration #99973, Score = 0.08747428121794937,
Iteration #99974, Score = 0.08747428121794937,
Iteration #99975, Score = 0.08747428121794937,
Iteration #99976, Score = 0.08747428121794937,
Iteration #99977, Score = 0.08747428121794937,
Iteration #99978, Score = 0.08747428121794937,
Iteration #99979, Score = 0.08747428121794937,
Iteration #99980, Score = 0.08747428121794937,
Iteration #99981, Score = 0.08747428121794937,
Iteration #99982, Score = 0.08747428121794937,
Iteration #99983, Score = 0.08747428121794937,
Iteration #99984, Score = 0.08747428121794937,
Iteration #99985, Score = 0.08747428121794937,
Iteration #99986, Score = 0.08747428121794937,
Iteration #99987, Score = 0.08747428121794937,
Iteration #99988, Score = 0.08747428121794937,
Iteration #99989, Score = 0.08747428121794937,
Iteration #99990, Score = 0.08747428121794937,
Iteration #99991, Score = 0.08747428121794937,
Iteration #99992, Score = 0.08747428121794937,
Iteration #99993, Score = 0.08747428121794937,
Iteration #99994, Score = 0.08747428121794937,
Iteration #99995, Score = 0.08747428121794937,
Iteration #99996, Score = 0.08747428121794937,
Iteration #99997, Score = 0.08747428121794937,
Iteration #99998, Score = 0.08747428121794937,
Iteration #99999, Score = 0.08747428121794937,
Iteration #100000, Score = 0.08747428121794937,
Final score: 0.08747428121794937

上述输出表明,通过使用贪心随机训练算法并经过大量迭代,整个训练过程一直持续到评分降到了0.08的等级,这意味着大多数鸢尾花都能够被正确地分类。在第8章,我们会使用更先进的算法,在更少的迭代次数内得到更好的结果。

7.4 本章小结

本章介绍了训练机器学习算法的基础知识,正常来说,在训练过后,对于特定输入,机器学习算法都能够产生与预期结果接近的输出。而带有预期输出的给定输入就是被用来训练模型的所谓“训练集”。

大多数机器学习算法有“长期记忆”这个属性,并在训练过程中不断调整。“长期记忆”还有个名字叫作“权重”,有时也被称作“系数”,一般被保存为向量形式。

本章还介绍了贪心随机训练算法,这是一种很简单的训练算法,其实就是给长期记忆随机赋值,不断尝试新的参数组合,并保存表现最佳的参数组合。同时,该算法也经常作为一个基准,用以衡量比较其他算法的性能。

在本章中我们训练了两个不同的模型:一个简单的多项式和一个径向基函数网络模型。多项式的例子展示了贪心随机训练算法如何用于拟合简单公式,并用该算法估计了示例多项式中的3个系数。

径向基函数网络模型的基础就是径向基函数,这种函数具有关于中点对称的特性。每个径向基函数都具有多维的中心点,和可变的宽度值;但要注意的是,对指定的径向基函数而言,在各个维度上,宽度的大小是一致的。本章中,我们使用的是高斯径向基函数。

径向基函数网络使用训练算法来调整长期记忆的值,模型最终可以用于分类或回归问题。其中模型的长期记忆包括系数、径向基函数宽度和径向基函数的中心点向量。本章中构建出的模型用来拟合了鸢尾花数据集。

第8章会介绍其他的一些优化算法,均可用于调整径向基函数网络的长期记忆值。实际上只要模型保存了类似于长期记忆向量这样的状态属性,都可以应用这些优化算法。具体来说,这些算法包括爬山算法、模拟退火算法和Nelder-Mead训练算法。


[1] 也称“下坡单纯形法”。——译者注

[2] Lial, 2010。

[3] Bishop,1996。

本文摘自《人工智能算法 卷1 基础算法》,[美] 杰弗瑞·希顿(Jeffery Heaton) 著,李尔超 译。

  • AI算法入门教程书籍,人人都能读懂的人工智能书
  • 全彩印刷,实例讲解易于理解的人工智能基础算法
  • 多种语言版本示例代码、丰富的在线资源,方便动手实战与拓展学习

欲建高楼,必重基础。本书讲授诸如维度法、距离度量算法、聚类算法、误差计算、爬山算法、模拟退火算法、Nelder-Mead算法和线性回归算法等人工智能基础算法。

本书中所有算法均配以具体的数值计算示例。“人工智能算法”系列图书的目标读者是那些没有良好数学基础,又对人工智能感兴趣的人。本书读者只需具有基本的大学代数和计算机编程知识,任何超出这个范围的内容都会在书中详细说明。本书为读者提供配套的示例程序代码, 当前已有Java、C#、R、C/C++和Python的语言版本,还有社区支持维护的Scala语言版本。

发布了496 篇原创文章 · 获赞 280 · 访问量 87万+

猜你喜欢

转载自blog.csdn.net/epubit17/article/details/104055677