多输出神经网络

13

我在python中建立了我的第一个神经网络,并且尝试着使用一些数据集;到目前为止进展顺利!

我关于建模具有多个结果的事件有一个快速的问题:

比如说我想要训练一个神经网络,告诉我每位参赛选手赢得100米短跑的概率。我将提供每个选手相关的所有数据,而输出的数量将等于比赛中的选手数量。

我的问题是,使用sigmoid函数,如何确保输出总和等于1.0?网络会自然地学会这样做吗,还是我需要明确地让它发生?如果是这样,我该如何做到呢?

非常感谢。


1
只是一个提醒,除非你有充分的理由使用逻辑斯蒂函数在隐藏层中,否则不要使用它。使用tanh代替它,因为这样会使你的网络更好地适应。逻辑斯蒂函数主要是出于历史原因而被使用。 - Niclas
3个回答

18

你的神经网络输出将会逐渐趋近于1,但我认为它不会完全达到1。

实际上,你并不需要知道哪一个输出等于1。一旦你将网络训练到特定的误差水平,当你提供输入时,只需查找输出中的最大值即可。例如,假设你的输出层呈现以下输出: [0.0001, 0.00023, 0.0041, 0.99999412, 0.0012, 0.0002],那么赢得比赛的选手是第四个。

因此,是的,你的网络将“学习”产生1,但它不会完全等于1。这就是为什么要在某个误差率范围内进行训练的原因。我最近创建了一个用于识别手写数字的神经网络,这就是我使用的方法。在我的输出层中,我有一个具有10个组成部分的向量。第一个组成部分代表0,最后一个组成部分代表9。因此,当我将4提供给网络时,我希望输出向量看起来像[0, 0, 0, 0, 1, 0, 0, 0, 0, 0]。当然,这不是我确切得到的,但这是我训练网络提供的结果。因此,为了找出是哪个数字,我只需检查哪个组成部分具有最高的输出或得分。

现在在你的第二个问题中,我相信你正在问网络如何学习提供正确的答案?为了做到这一点,您需要向网络提供一些训练数据,并将其训练直到输出在某个误差阈值以下。所以你需要一组包含输入和正确输出的数据。最初,你的神经网络会设置随机权重(有一些算法可以帮助你选择更好的权重来最小化训练时间,但那是更高级的内容)。接下来,你需要一种方法告诉神经网络从提供的数据中学习。基本上,你把数据给神经网络,它提供一个输出,很可能是错误的。然后,将该数据与期望(正确)输出进行比较,并告诉神经网络更新其权重,使其更接近正确答案。你要一遍又一遍地做这件事,直到错误低于某个阈值。

最简单的方法是实现随机反向传播算法。在此算法中,您计算神经网络的实际输出与期望输出之间的误差。然后,您将误差从输出层向上反向传播到隐藏层的权重,同时调整权重。然后您重复此过程,直到计算出的误差低于某个阈值。因此,在每个步骤中,您都越来越接近解决方案。

您可以使用描述在这里的算法。其中有相当多的数学涉及,所以请做好准备!如果您想查看此算法的实现示例,可以查看我在github上的Java代码。该代码还使用了动量和简单形式的模拟退火,但标准反向传播算法应该很容易辨别。维基百科关于反向传播的文章中有一个Python中反向传播算法的实现链接
您可能不能立即理解该算法;需要花费一些时间来理解它并通过一些数学运算进行工作。在编码时我用笔和纸坐下来,那是我最终理解发生的方式。
以下是一些资源,应该帮助您更好地理解反向传播: 如果您需要更多资源,还可以查看我在这里的答案

非常感谢您提供的有用资源。在我编写的网络中,我正在使用遗传算法进行训练。我还没有研究反向传播,但我会查看您提供的资源。 - Sherlock
反向传播比遗传算法容易 - 这是一个不错的起点。 - Vivin Paliath
纯反向传播仅适用于可以计算导数的误差函数,即使如此,它也面临着可能陷入局部最优解的问题。遗传算法有其自身的缺点,但它们没有这些问题。 - Predictor
2
我不明白这怎么会导致负评。原帖没有指定要使用什么算法。我也很清楚反向传播需要一个存在导数的激活函数,并且反向传播可能会陷入局部最小值。仅仅因为标准反向传播算法存在这些缺点,就不能说明我的答案是错误的。 - Vivin Paliath
是否可以激活多个输出?例如,您是否可以使用类似 [0, 1, 0, 1] 的东西来训练您的网络?还是最好为每个独立的输出创建不同的神经网络?例如,我想要一张有四扇门的图片,如果门关闭则输出0,如果门打开则输出1。如果这些门看起来不同,那么我应该为每个单独的门创建一个神经网络吗?谢谢! - XCS

2
基本上,您需要一个多个实数的函数,将这些实数转换为概率(每个概率在0到1之间,总和为1)。您可以通过后处理网络输出来轻松实现此操作。
您的网络会给出实数r1,r2,...,rn,它们随着每个选手赢得比赛的概率而增加。
然后计算exp(r1),exp(r2),...,并将它们加起来以获得ers = exp(r1)+ exp(r2)+ ... + exp(rn)。然后第一个选手获胜的概率是exp(r1)/ ers。
这是Boltzmann分布的一种用法。 http://en.wikipedia.org/wiki/Boltzmann_distribution

1

你的网络应该围绕这个问题工作,并最终自然地学会它。

为了让网络更快地学习,以下是我首先想到的:

  • 添加一个名为“sum”的附加输出(将所有其他输出神经元相加)--如果您希望所有输出神经元位于单独的层中,只需添加一层输出,前numRunners个输出连接到上一层中对应的神经元,而最后一个numRunners+1个神经元则连接到上一层的所有神经元,并将权重固定为1)

  • 训练集将包含每个赛跑者的0-1向量(是否参加比赛),而“预期”结果将是一个0-1向量00..00001000..01,第一个1标记赢得比赛的赛跑者,最后一个1标记“概率”的“总和”

  • 对于未知的比赛,网络将尝试预测哪个赛跑者会获胜。由于输出具有连续的值(或多或少:D),它们可以被解读为“网络确信赛跑者会赢得比赛的程度”--这正是您要寻找的

即使没有额外的sum神经元,这仍然是训练数据应该排列的大致描述。

很酷,非常感谢您的快速回复,非常感激 :) - Sherlock
实际上,神经网络永远不会学习输出仅总和为1.0的值。 - Predictor

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