如何选择前馈神经网络中隐藏层和节点的数量?

机器算法验证 模型选择 神经网络
2022-01-16 09:55:35

在前馈神经网络中,是否有标准且可接受的方法来选择层数和每层中的节点数?我对构建神经网络的自动化方式很感兴趣。

4个回答

我意识到这个问题已经得到回答,但我认为现存的答案除了指向通常与问题主题相关的链接之外,并没有真正涉及到这个问题。特别是,该链接描述了一种用于程序化网络配置的技术,但这不是网络配置的“ [a] 标准和公认方法”。

通过遵循一小组明确的规则,可以以编程方式设置一个称职的网络架构(即神经元层的数量和类型以及构成每一层的神经元的数量)。遵循此架构,这将为您提供一个称职的架构,但可能不是最佳架构。

但是一旦这个网络被初始化,你可以在训练期间使用一些辅助算法迭代地调整配置;其中一个家族通过在一定数量的训练时期后基于权重向量的(小)值修剪节点 - 换句话说,消除不必要的/冗余节点(更多内容见下文)。

所以每个 NN 都有三种类型的层:输入隐藏输出


因此,创建 NN 架构意味着为每种类型的层数和每个层中的节点数计算值。

输入层

很简单——每个 NN 都有其中的一个——我知道没有例外。

关于构成该层的神经元数量,一旦您知道训练数据的形状,该参数就会完全且唯一地确定。具体来说,构成该层的神经元数量等于数据中特征(列)的数量一些 NN 配置为偏置项添加了一个额外的节点。


输出层

与输入层一样,每个 NN 都只有一个输出层。确定其大小(神经元数量)很简单;它完全由所选模型配置决定。

您的 NN 是在机器模式还是回归模式下运行(使用统计中也使用的术语但为其分配不同含义的 ML 约定非常令人困惑)。机器模式:返回一个类标签(例如,“Premium Account”/“Basic Account”)。回归模式返回一个值(例如,价格)。

如果 NN 是回归器,则输出层只有一个节点。

如果 NN 是分类器,那么它也只有一个节点,除非使用softmax,在这种情况下,输出层在模型中的每个类标签都有一个节点。

隐藏层

因此,这几条规则设置了输入层和输出层的层数和大小(神经元/层)。这留下了隐藏层。

有多少隐藏层?好吧,如果您的数据是线性可分的(在您开始编写 NN 时您通常知道这一点),那么您根本不需要任何隐藏层。当然,您也不需要 NN 来解析您的数据,但它仍然可以完成这项工作。

除此之外,您可能知道,还有大量关于 NN 中隐藏层配置问题的评论(有关该评论精彩摘要,请参阅疯狂透彻和富有洞察力的NN FAQ)。该主题中达成共识的一个问题是与添加额外隐藏层的性能差异:通过第二个(或第三个等)隐藏层提高性能的情况很少。对于大多数问题,一个隐藏层就足够了。

那么隐藏层的大小呢——多少个神经元?有一些经验得出的经验法则,其中最常依赖的是“隐藏层的最佳大小通常介于输入层的大小和输出层的大小之间”。Jeff Heaton,《Java 神经网络简介》一书的作者提供了更多内容。

总而言之,对于大多数问题,通过仅使用两条规则设置隐藏层配置可能会获得不错的性能(即使没有第二个优化步骤):(i)隐藏层的数量等于 1;(ii) 该层中神经元的数量是输入和输出层中神经元的平均值。


网络配置优化

修剪描述了一组技术来修剪网络大小(通过节点而不是层)以提高计算性能,有时甚至是分辨率性能。这些技术的要点是在训练期间通过识别那些如果从网络中移除不会显着影响网络性能(即数据的分辨率)的节点来从网络中移除节点。(即使不使用正式的剪枝技术,您也可以通过在训练后查看权重矩阵来粗略了解哪些节点不重要;查看非常接近于零的权重——通常是这些权重两端的节点修剪期间删除。)显然,如果您在训练期间使用修剪算法,那么从更可能有多余(即“可修剪”)节点的网络配置开始 - 换句话说,

换句话说,通过在训练期间对网络应用剪枝算法,您可以接近最优网络配置;您是否可以在单个“预先”(例如基于遗传算法的算法)中做到这一点我不知道,尽管我现在知道,这种两步优化更常见。

@doug 的回答对我有用。还有一个额外的经验法则可以帮助解决监督学习问题。如果将神经元数量保持在以下,通常可以防止过度拟合:

Nh=Ns(α(Ni+No))

Ni= 输入神经元的数量。
No= 输出神经元的数量。
Ns= 训练数据集中的样本数。
α= 任意比例因子,通常为 2-10。

其他推荐设置α到 5 到 10 之间的值,但我发现 2 的值通常不会过拟合。你可以想到α作为每个神经元的有效分支因子或非零权重的数量。Dropout 层会将“有效”分支因子从网络的实际平均分支因子中降低。

正如这篇出色的 NN 设计文本所解释的,您希望将模型中的自由参数的数量(其程度或非零权重的数量)限制为数据中自由度的一小部分。数据中的自由度是每个样本中的样本数 * 自由度(维度)或Ns(Ni+No)(假设它们都是独立的)。所以α是一种表示您希望模型有多通用,或者您希望防止过度拟合的方法。

对于自动化程序,您将从α2(训练数据的自由度是模型的两倍),如果训练数据集的误差(损失)明显小于测试数据集,则可以达到 10。

来自Jeff HeatonJava 神经网络简介 (第二版) ——可在Google Books和之前在作者的网站上免费预览:

隐藏层数

关于隐藏层实际上必须做出两个决定:神经网络中实际有多少隐藏层,以及每个层中有多少神经元。我们将首先研究如何确定与神经网络一起使用的隐藏层数。

很少遇到需要两个隐藏层的问题。然而,具有两个隐藏层的神经网络可以表示任何形状的函数。目前没有理论上的理由使用具有两个以上隐藏层的神经网络。事实上,对于许多实际问题,没有理由只使用一个隐藏层。表 5.1 总结了具有各种隐藏层的神经网络架构的能力。

表 5.1:确定隐藏层的数量

| 隐藏层数 | 结果 |

 0 - 仅能够表示线性可分离函数或决策。

 1 - 可以逼近任何包含连续映射的函数
从一个有限空间到另一个。

 2 - 可以以任意精度表示任意决策边界
具有合理的激活函数,可以逼近任何平滑
映射到任何精度。

确定隐藏神经元层的数量只是问题的一小部分。您还必须确定每个隐藏层中有多少神经元。此过程将在下一节中介绍。

隐藏层中的神经元数量

决定隐藏层中神经元的数量是决定整个神经网络架构的一个非常重要的部分。尽管这些层不直接与外部环境交互,但它们对最终输出有巨大的影响。必须仔细考虑隐藏层的数量和每个隐藏层中的神经元数量。

在隐藏层中使用太少的神经元会导致所谓的欠拟合。当隐藏层中的神经元太少而无法充分检测复杂数据集中的信号时,就会发生欠拟合。

在隐藏层中使用过多的神经元会导致几个问题。首先,隐藏层中的神经元过多可能会导致过拟合。当神经网络具有如此多的信息处理能力,以至于训练集中包含的有限信息量不足以训练隐藏层中的所有神经元时,就会发生过拟合。即使训练数据足够,也会出现第二个问题。隐藏层中大量神经元会增加训练网络所需的时间。训练时间可能会增加到无法充分训练神经网络的程度。显然,隐藏层中神经元过多和过少之间必须达成某种妥协。

有许多经验法则可用于确定要在隐藏层中使用的正确神经元数量,例如:

  • 隐藏神经元的数量应该在输入层的大小和输出层的大小之间。
  • 隐藏神经元的数量应该是输入层大小的 2/3,加上输出层的大小。
  • 隐藏神经元的数量应小于输入层大小的两倍。

这三个规则为您提供了一个考虑的起点。最终,为您的神经网络选择架构将归结为反复试验。但是试错究竟是什么意思呢?你不想开始在你的网络上扔随机数量的层和神经元。这样做将非常耗时。第 8 章“修剪神经网络”将探讨各种确定神经网络最佳结构的方法。


我也喜欢我在 researchgate.net 上找到的答案中的以下片段,它仅用几句话就传达了很多信息:

Steffen B Petersen · 奥尔堡大学

[...]

为了确保网络的泛化能力,节点的数量必须保持尽可能低。如果您有大量多余的节点,您的网络就会成为一个记忆库,可以完美地回忆训练集,但在不属于训练集的样本上表现不佳。

我目前正在对此进行实证研究(在我们的 HPC 设施上进行一个处理器世纪的模拟!)。我的建议是使用“大型”网络和正则化,如果你使用正则化,那么网络架构变得不那么重要(只要它足够大以表示我们想要捕获的底层功能),但你确实需要调整正则化参数正确。

架构选择的一个问题是它是对模型复杂性的离散而非连续控制,因此可能有点生硬,尤其是在理想复杂度较低的情况下。

然而,这一切都受制于“没有免费的午餐”定理,虽然正则化在大多数情况下是有效的,但总会有架构选择效果更好的情况,这是找出手头问题是否属实的唯一方法是尝试两种方法并交叉验证。

如果我要构建一个自动化的神经网络构建器,我会使用 Radford Neal 的基于混合蒙特卡罗 (HMC) 采样的贝叶斯方法,并使用大型网络并整合权重,而不是优化单个网络的权重。然而,这在计算上是昂贵的,而且有点像“魔法”,但尼尔教授取得的结果表明这是值得的!