多输出神经网络



我用python构建了我的第一个神经网络,我一直在摆弄一些数据集;到目前为止一切顺利!

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

假设我希望训练一个网络来告诉我每个跑步者赢得100米短跑的概率。我将向网络提供关于每个跑步者的所有相关数据,输出的数量将等于比赛中跑步者的数量。

我的问题是,使用sigmoid函数,我如何确保输出的总和等于1.0 ?网络会自然地学会做这件事吗,还是我必须以某种方式明确地让它发生?如果是的话,我该怎么做呢?

多谢。

神经网络的输出将接近 1。我不认为它真的会达到1。

您实际上不需要查看哪个输出等于1。一旦您将网络训练到特定的错误级别,当您呈现输入时,只需在稍后的输出中查找最大输出。例如,假设您的输出层呈现以下输出:[0.0001, 0.00023, 0.0041, 0.99999412, 0.0012, 0.0002],那么赢得比赛的跑步者是4号跑步者。

所以,是的,你的网络将"学习"产生1,但它并不完全是1。这就是为什么你训练要在一定的错误率之内。我最近创建了一个神经网络来识别手写数字,这就是我使用的方法。在我的输出层中,我有一个有10个分量的向量。第一个分量表示0,最后一个分量表示9。所以当我给网络一个4时,我期望输出向量看起来像[0, 0, 0, 0, 1, 0, 0, 0, 0, 0]。当然,这并不是我真正得到的,但这是我训练网络所提供的。因此,要找到它是哪个数字,我只需检查哪个组件具有最高的输出或分数。

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

最简单的方法是实现随机反向传播算法。在这个算法中,你计算神经网络的实际输出和预期输出之间的误差。然后将误差从输出层反向传播,一直到权重层,再到隐藏层,并在此过程中调整权重。然后重复这个过程,直到计算出的误差低于某个阈值。所以在每一步中,你都离你的解决方案越来越近。

您可以使用这里描述的算法。有相当数量的数学涉及,所以要做好准备!如果您想查看该算法实现的示例,可以查看我在github上提供的Java代码。代码也使用动量和一种简单形式的模拟退火,但是标准的反向传播算法应该很容易识别。维基百科关于反向传播的文章有一个链接,指向Python中反向传播算法的实现。

你可能不会马上理解这个算法;预计要花一些时间来理解它,并通过一些数学计算。我坐下来,拿着纸和笔在编码,这就是我最终明白发生了什么。

这里有一些资源可以帮助您更好地理解反向传播:

    学习过程:反向传播
  • 误差反向传播

如果你想要更多的资源,你也可以看看我的回答在这里

基本上你想要一个多个实数的函数,将这些实数转换为概率(每个在0到1之间,求和为1)。你可以很容易地通过后处理你的网络输出。

你的网络给你实数r1, r2,…, rn,随着每个选手赢得比赛的概率增加。

则计算exp(r1), exp(r2),…,并将它们相加得到ers = exp(r1) + exp(r2) +…+ exp (rn)。那么第一个选手获胜的概率是exp(r1)/ers。

这是玻尔兹曼分布的一种用法。http://en.wikipedia.org/wiki/Boltzmann_distribution

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

为了使网络更快地学习,首先想到的是:

  • 添加一个额外的输出称为'sum'(求和所有其他输出神经元)-如果你想要所有的输出神经元在一个单独的层中,只需添加一层输出,第一个numRunners输出只是连接到前一层的相应神经元,最后一个numRunners+1 -神经元连接到前一层的所有神经元,并将权值固定为1)

  • 训练集将包含0-1个向量,每个跑步者(有-没有跑),"预期"结果将是一个0-1向量00..00001000..01第一个1标记赢得比赛的跑步者,最后一个1标记"概率"的"one_answers"

  • 对于未知的比赛,网络会尝试预测哪位选手会赢。由于输出具有连续的值(或多或少:D),它们可以被读取为"网络中跑步者将赢得比赛的确定性"——这就是您要寻找的

即使没有额外的sum神经元,这也是对训练数据应该如何排列的粗略描述。