神经网络的层与神经元

3
我想了解更多关于神经网络的信息,我正在开发一个用C++编写的NN程序,但是我被反向传播算法卡住了,抱歉我没有提供一些工作代码。
我知道有很多库可以在许多语言中创建NN,但我更喜欢自己制作。问题在于,我不知道为了实现特定目标(如模式识别或函数逼近等)需要多少层和多少神经元。
我的问题是:如果我想要识别一些特定的模式,比如图像检测,需要多少层和每层多少个神经元?假设我所有的图像都是8x8像素,我会从一个64个神经元的输入层开始,但我不知道隐藏层和输出层需要放多少神经元。假设我要区分猫和狗,或者你认为的任何东西,输出层该怎么办?我可以想象一个只有一个神经元的输出层,输出0到1之间的值,具有经典的逻辑函数(1/(1+exp(-x)),当它接近0时,输入是一只猫,当它接近1时,输入是一只狗,但是......这是正确的吗?如果我添加一个新的模式,比如鱼怎么办?如果输入包含一只狗和一只猫(...和一条鱼)怎么办?这让我想到,输出层中的逻辑函数并不非常适合这样的模式识别,只是因为1/(1+exp(-x))在(0, 1)范围内。我必须更改激活功能或者在输出层添加其他神经元吗?是否有其他更准确的激活函数来完成这项工作?每个层的每个神经元的激活功能是否相同,还是不同?
对于我来说,这个话题不是很清晰。我在互联网上读了很多资料,发现许多库都未被实现且难以理解,并且有很多对神经网络能做什么的解释,但没有说明如何实现它。
我从https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/http://neuralnetworksanddeeplearning.com/chap1.html中读取了很多内容,在这里我理解了如何近似一个函数(因为每个层中的每个神经元都可以被认为是一个带有特定权重和偏置的阶跃函数),以及反向传播算法的工作原理,但其他教程则更关注预先存在的库。我还阅读了这个问题Determining the proper amount of Neurons for a Neural Network,但我想涉及NN的激活函数,哪种最好,以及哪种最适合。 谢谢您提前的答案!

2
如果你的问题更加聚焦和简明扼要,我认为你在这里会做得更好。另外,如果你移除 C++ 标签,因为这个问题与 C++ 无关。 - John Zwinck
为什么不尝试在一个更简单的模型上实现反向传播,比如逻辑回归(本质上是没有任何隐藏层的人工神经网络),然后再扩展到更复杂的模型呢?这只是一个想法。此外,Coursera(谷歌一下)正在提供由斯坦福大学教授Andrew Ng主讲的深度学习专项课程。非常有价值。 - Free Url
@Zroach 感谢您的评论,我会查找 Coursera 关于 DNN 的相关内容。我想知道 DNN 的主要特征以及如何通过实现一个特定的目标来构建一个 DNN。无论如何,从一个简化的问题开始是最好的方法。 - pippo
2个回答

2

您的问题比较泛化,因此我只能给出一些通用建议:

所需层数取决于您想要解决的问题的复杂性。从给定输入获得输出所需要的计算量越大,就需要更多的层数。

只有非常简单的问题可以使用单层网络来解决。这些问题被称为线性可分,通常很容易解决。使用两层就会更好,使用三层,至少在理论上,如果您在层内有足够的单元,就可以执行各种分类任务。然而,在实践中,通常最好将第四或第五层添加到网络中,并减少单层内的单元数量。

请注意,标准反向传播算法在超过4或5层时表现不佳。如果您需要更多层数,请查看深度学习

每个层中的单元数主要取决于输入数量以及(如果您解决分类任务)要检测的类别数量。在实践中,通常会逐层减少单元数,但也有例外。

关于您对输出函数的问题:在大多数情况下,您应该坚持使用一种类型的sigmoid函数。您描述的情况并不是真正的问题,因为您可以为“fish”类添加另一个输出单元。选择特定的激活函数并不那么关键。基本上,您使用可以高效计算值和导数的函数。


谢谢你的回答。所以你的意思是,如果我要识别15个模式,我可以添加15个带有Sigmoid函数的输出单元,对吗?是否有规则或方法可以知道我需要放置多少层和每层的单元格,还是只是启发式的?如果我超过了层数,深度学习中用于训练和升级权重的算法是什么?抱歉问题这么开放,但我正在努力弄清楚它是如何工作的。 - pippo

2
@Frank Puffer已经提供了一些不错的信息,但是让我再补充一下。首先,你所问的大部分内容都属于超参数优化领域。虽然有各种“经验法则”,但实际上确定最佳架构(层数/大小、连接结构等)和其他参数,如学习率通常需要进行广泛的实验。好消息是,这些超参数的参数化是神经网络实现中最简单的方面之一。因此,我建议专注于构建软件,使得层数、层大小、学习率等都可以轻松配置。
现在你具体问到了如何检测图像中的模式。值得一提的是,使用标准的多层感知器(MLP)对原始图像数据执行分类可能会非常耗费计算资源,特别是对于更大的图像来说。通常使用旨在提取有用的空间局部特征的架构(即:卷积神经网络或CNN)。
您可以仍然使用标准的MLPs来实现这个,但是计算复杂度可能会使它成为不可行的解决方案。例如,CNNs中的稀疏连接显著减少了需要优化的参数数量,并同时构建了一个更适合图像分类的概念层次结构。
无论如何,我建议使用随机梯度下降来实现反向传播进行优化。这仍然是训练神经网络、CNNs、RNNs等的典型方法。
关于输出神经元的数量,这是一个有简单答案的问题:使用“one-hot”编码。对于每个要识别的类别,都有一个输出神经元。在您的例子中,狗、猫和鱼类别,您有三个神经元。对于代表狗的输入图像,您期望“狗”神经元的值为1,其他神经元的值为0。然后,在推理过程中,您可以将输出解释为反映NN置信度的概率分布。例如,如果您得到输出dog:0.70,cat:0.25,fish:0.05,则表示您有70%的置信度该图像是一只狗,以此类推。
对于激活函数,我最近看到的研究似乎表明修正线性单元通常是一个不错的选择,因为它们易于求导和计算,并且避免了深度网络中普遍存在的“梯度消失问题”。

祝你好运!


非常感谢,你让我对CNNs以及它们的工作方式产生了好奇心,也许我可以发现它们更适合我的目标。我会像你建议的那样学习更多关于修正线性单元的知识。谢谢! - pippo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接