机器学习中快速修补构建神经网络的选择可以是它

通用近似定理

机器学习中快速修补构建神经网络的选择可以是它

神经网络在1989年首次被证实,它可以被归类为通用函数近似器。给定任意连续的N维函数f(x),只有一个隐含层和有限数量的神经元的神经网络能够在x的固定范围内和一个有限误差ε内近似这样的函数。

本文将利用这个定理评估一个关于多重非平凡函数的简单体系结构,以证明我们的网络能够从数据中学习。

一些辅助函数

机器学习中快速修补构建神经网络的选择可以是它

让我们定义这些辅助函数,这些辅助函数将帮助我们进行训练和评估:

· genDataSet1D:使用开始、结束和步骤信息,此函数生成一个向量元组数组,每个元组对应一个(x,y)对。请注意,根据需要,这可以是任何维度,但为了简单起见,本教程中的输入和输出都将是一维的。

· yRealFn:这是我们定义目标函数的地方。来自该函数的数据点将被采样并绘制在最终图上,以显示我们试图建模的实际底层函数。

· yRealFnAndNoise:该函数简单地将一个概率项添加到yRealFn的输出中,模拟数据中存在的噪音。但是,如果这个错误没有被适当地缩放,它将会比确定性项(yRealFn)大得多,从而导致网络学习的不是实际的函数。

· meanFeatureSqErr&evalAngEpochErr:这些函数将在本教程的训练部分进行说明。

初始化网络

定义架构

机器学习中快速修补构建神经网络的选择可以是它

为了测试我们的网络,只有一个隐藏层的简单神经网络就足够了。作者研究了一些必要的隐藏节点,以便学习任何合理的平滑函数,发现8个节点就足以完成这项工作。

根据经验,选择太少的隐藏节点可能会导致拟合不足,反之则会导致过度拟合。

当选择一个激活函数时,有很多常用的方法:tanh,sigmoid,ReLU等等。作者决定采用tanh,因为它非常适合学习平滑函数中存在的非线性。

机器学习中快速修补构建神经网络的选择可以是它

tanh(x)(红色)及其衍生物(绿色)。

选择超参数

如果你一直关注机器学习,从一开始你就会意识到超参数搜索或多或少的尝试和错误。当然,你还可以查看几个时期的成本函数图,并对你认为的最佳值进行有根据的估计。

目标函数

在开始训练之前,还有最后一步:选择合理复杂的函数,可以用来生成良好规划的数据集,同时可以在视觉上进行比较。

你会注意到,对于处于相同范围内的所有输入,输出都受闭区间[0,1]的限制。这是一个深思熟虑的决定,可以避免使用均值标准化,通过保持所有特征在相似范围内,有助于防止过度的权重。

机器学习中快速修补构建神经网络的选择可以是它

三个测试函数以及它们的图的定义。

我们将使用步长为0.01的x∈[0,1]来训练我们的网络。因此,在这个范围内将产生101个等间距样本,我们将保留约6%用于验证(统一选择)。

机器学习中快速修补构建神经网络的选择可以是它

训练我们的网络

概述

让我们首先从顶层收集我们需要训练的函数:

•对于每个时期,我们需要执行梯度下降,在我们的情况下,将随机完成(每个样本一次)。然后,我们会在下一个时期使用更新后的网络进行进一步的训练。

•在此过程中,通过在每个时期结束时评估我们的网络并获得误差度量(例如平方误差)来跟踪我们的训练误差。

使用MapFold

保持接近函数范例,而不是使用传统的for循环,我们将利用List.mapFold进行训练。

那么mapFold如何工作?

简而言之,它是List.fold和List.map的有效组合。它允许在给定当前列表元素和先前状态的情况下来计算新状态,同时使用我们选择的函数转换当前列表元素。这个函数的最终输出是一个由变换列表和最终状态组成的元组。

实现

在trainEpoch函数中,训练数组首先随机被打乱。这个新重组的数组被输入到perfGradDesc。该函数通过使用Array.fold传播网络更新,在整个训练数据集(单次传递)上执行样本的梯度下降。

一旦我们对网络进行了一次训练,并从trainEpoch获得最终网络后,我们需要使用我们选择的成本函数来评估该时期的训练误差。每个样本的误差需要与lastLayerDeriv函数一致。因此,对于由themeanFeatureSqErr函数实现的错误度量,平方误差是最合适的选择。

注意:尽管我们的网络可以支持任何维度的输出,但在涉及成本函数时,每个样本只有一个标量度量值是有用的。因此,每个样本的误差将是每个输出特征的平方误差的平均值。这不会影响一维输出的误差,并且如果所有输出维度都具有大致相同的比例,则这是合理的选择。

在对整个训练集进行平均误差后,我们得到均方误差。该值由evalAvgEpochErrfunction计算。

最后,在每个时期结束时,(xAndyShuffArr,newNet)是传播到下一时期的新状态,而err是替换原始列表中时期数的映射对象。

机器学习中快速修补构建神经网络的选择可以是它

训练我们的网络的代码

结果

机器学习中快速修补构建神经网络的选择可以是它

y = 0.4x 2 + 0.2 + 0.3x * sin8x的结果跨越多个时期。

这里有一些视觉证据表明网络实际上正在训练!为了绘制数据,本文将使用过去用于F#绘图的PLplot库。绘制这些图需要一些额外的代码量,但这可以在本文结尾处链接的此项目的Github存储库中找到。

传说

· 粉红色的线代表没有噪音的底层真实函数。这仅用于绘图,但从未用于任何计算。

· 青色点是包括训练和测试数据点的整个数据集。所有误差都是参考这些点来计算的。

· 绿色圆圈表示对训练数据进行评估的最终假设。随着训练周期的增加你可以观察到它们越来越接近真实的函数曲线。

· 最后,粉红色十字代表在测试数据上评估的最终假设。如果仔细观察,你可以注意到它们很好地跟踪了训练数据点,并且这通过MSE的训练测试分数得到了证实。

评估目标函数

机器学习中快速修补构建神经网络的选择可以是它

机器学习中快速修补构建神经网络的选择可以是它

机器学习中快速修补构建神经网络的选择可以是它

从上到下:f(x)= 0.4x 2 +0.2 + 0.3x * sin8x、g(x)= 0.6e ^ - (0.3sin12x /(0.3 + x))、h(x)= 0.4-0.1log x + 0.1)+ 0.5x * cos12x

这里是三个测试函数的结果,你可以点击其中的每一个来更详细地查看它们。只需一眼就能看出,网络通常在更平滑的函数上运行的更好。随着每个函数静止点附近的梯度增加,神经网络训练变得更加困难(观察损失曲线)。这与我们使用tanh(x)作为激活函数有关。

尽管如此,我们现在已经有了通用近似定理成立的直观证明!

结论

现在我们已经定义了我们的基本架构,并且能够训练任何任意数据,我们可以使用网络来训练和测试常用数据集。

通用近似定理在机器学习领域还有很长的路要走。它甚至可以扩展用来实现最简单的神经网络以提高收敛性:批量标准化,小批量梯度下降,自定义权重初始化等等。

不用担心,F#上进行3000次训练需要大约3秒的时间,这使得它成为快速神经网络修补和评估的潜在候选者。使用类似设计原理和类似参数选择的脚本的python版本需要大约168秒!

正如所承诺的,所有的源代码都可以在Github上找到。(https://github.com/hsed/funct-nn)

相关推荐