如何将人工神经网络的输出转换为概率?

38

我之前了解过神经网络,尤其是通过反向传播学习的多层感知器如何学习将事件分类为真或假。

我认为有两种方法:

1)您可以获得一个输出神经元。 如果它的值> 0.5,则事件很可能是真实的,如果其值<= 0.5,则该事件很可能是虚假的。

2)您可以获得两个输出神经元,如果第一个值大于第二个值,则该事件很可能为真,反之亦然。

在这些情况下,神经网络告诉您事件可能是真实的或可能是虚假的。 它并没有告诉您概率。

是否有一种方法将此值转换为某些概率或直接从ANN中获取概率。 我想要的输出是“事件有84%的可能性是真实的”。

8个回答

22

一旦神经网络训练完毕,例如使用本问题中提到的反向传播(通过反向传播逻辑“推动”权重以最小化误差函数),所有个别输入(“外部”输入或神经网络内部输入)所关联的权重都被固定。此时,神经网络可以用于分类目的。

在学习阶段可能会涉及到较为复杂的数学(和“选项”),但在作为分类器运行时,它相对简单和直接。主要算法是计算每个神经元的激活值,即该神经元的输入x权重之和。然后将该值馈送到一个激活函数中,其目的是对其进行归一化并将其转换为布尔值(在典型情况下,某些网络对于某些层没有全有或全无规则)。激活函数可以比你所说的更复杂,尤其是它不必是线性的,但无论其形状如何,通常是S型的,它的操作方式相同:确定激活值在曲线上的位置,并如果适用,在阈值以上或以下。基本算法然后处理给定层的所有神经元,然后再进入下一层。

有了这个前提,利用感知器对其猜测(或确切地说,猜测-复数)进行评估的问题,找到了一个简单的答案:当我们使用激活函数和问题中描述的阈值/比较方法将其转换为离散值(布尔值或在几类别情况下的类别ID)之前,其输出是实值的(如果需要归一化)。

那么...我从哪里获取“我的百分比”?这完全取决于神经网络的实现,更重要的是,实现决定了可以使用哪些类型的归一化函数将激活值带入0-1范围内,并以使所有百分比“加起来”等于1的方式。在其最简单的形式中,可以使用激活函数来归一化权重的值,将其用作输入到输出层的因子,以保证它们自身的权重得到归一化(前提是这些权重自身已经归一化)。

Et voilà!

澄清: (根据Mathieu的笔记)
不需要改变神经网络本身的工作方式;唯一需要做的是某种方式"接入"输出神经元的逻辑,以访问它们计算的[实值]激活值,或者更好的是访问激活函数的实值输出,在其布尔转换之前(通常基于阈值或某些随机函数)。

换句话说,神经网络的工作方式与以前相同,既不改变其训练逻辑也不改变识别逻辑,NN的输入保持不变,各层之间的连接等都不变。我们只获取输出层神经元的实值激活的副本,并使用它来计算百分比。实际的百分比计算公式取决于激活值的性质及其相关函数(其规模、范围相对于其他神经元的输出等)。
以下是几个简单的情况(取自问题中建议的输出规则): 1)如果有一个输出神经元:相对于该函数范围提供的值的比率即可。 2)如果有两个(或更多)输出神经元,例如分类器:如果所有输出神经元具有相同的激活函数,则给定神经元的百分比是其激活函数值与所有激活函数值之和的比率。如果激活函数不同,则成为一种情况,因为不同的激活函数可能表明有意在一些神经元上给予更多权重,并且百分比应该尊重这一点。


1
嗨,谢谢你的回答,我不确定我是否理解正确。你的意思是说你只把ANN的输出视为概率,并确保概率总和为1?ANN如何学习它应该输出概率。当我训练它时,我确实使用真实结果进行训练,因此训练集中的每个输出值都是0或1(0.05或0.95)。但是当我在实际工作中使用ANN时,我希望输出值为0.7表示事件为真(1)的概率为70%。你是告诉我我不需要做任何特殊的事情来获得这种输出吗? - Mathieu Pagé
@Mathieu 请看“澄清”。我希望它能有效地澄清事情,有时候我在试图做相反的事情时会让事情变得更加混乱;-) 我认为简而言之,这只是因为人们需要知道与神经元输出相关的实值数值的确切语义,才能够正确地对这些值进行归一化。 (我有多个值,因为它可以是激活值或激活函数的[实值]输出) - mjv
1
为什么这些值是概率? - ziggystar
@ziggystar 在这个问题和我的答案中,“Probabilities”这个词有些宽泛。更好的方式是将问题中的值命名为“百分比或置信度”(POC)或类似名称。虽然缺少对所代表的变量的正式声明,但这些值仍然具有概率的所有主要特征,特别是它们在0到1的范围内,它们加起来等于1(此分类的POC加上那个分类的POC加上...所有其他分类的POC,总和为1),而且POC(非X)= 1-POC(X)。 - mjv
@michel - tanh(x)函数的返回值始终在[-1..1]范围内,通常用于规范化“隐藏”层的值。而“输出”层可能需要在[0..1]范围内,因此会使用不同的规范化函数,例如https://en.wikipedia.org/wiki/Softmax_function。 - Jesse Chisholm
显示剩余4条评论

18
你可以在输出层节点上使用sigmoid转移函数(接受数据范围为(-inf,inf),并输出[-1,1]的值),然后通过使用 1-of-n输出编码(每个类别一个节点),你可以将[-1,1]范围映射到[0,1]并将其用作每个类别值的概率(请注意,这自然适用于不止两个类别)。

你的Sigmoid输出范围是错误的。Sigmoid转移函数的输出值在[0,1]之间。这在您提供的链接中有显示。 - Fabrice Dugas
@FabriceDugas sigmoid通常指的是一系列函数,其输出范围取决于约定,可以是[0,1]或[-1,1]。参见此链接以获取示例:https://dev59.com/ZknSa4cB1Zd3GeqPOoa0#1480075。 - Amro
啊,我的错。惯例惯例。谢谢你的例子! - Fabrice Dugas

10

在翻译神经网络(或任何机器学习分类器)的输出为概率时,我会非常谨慎。机器是经过训练来区分不同的类别,而不是用于估算概率密度。事实上,在数据中我们并没有这个信息,需要进行推断。从我的经验来看,我不建议直接将输出解释为概率。


10
单个输出神经元的激活值是一个线性加权和,如果网络被训练成将输出范围从0到1,则可以直接解释为近似概率。如果前一阶段的传递函数(或输出函数)和提供最终输出的传递函数也在0到1的范围内(通常是S形逻辑函数),那么这往往就是这种情况。但并不能保证会出现这种情况,但可以进行修复。此外,除非S形函数是逻辑函数并且权重被约束为正数且总和为1,否则不太可能出现这种情况。一般来说,使用tanh S形函数以及范围为正负的权重和激活方式会更平衡地训练神经网络(由于该模型的对称性)。另一个因素是类别的普遍性-如果为50%,则对于逻辑函数和tanh,0.5阈值可能是有效的,而0.0阈值适用于tanh。Sigmoid旨在将事物推向范围的中心(在反向传播中),并限制其超出范围(在前向传递中)。与Bernoulli分布相关的性能的重要性也可以解释为神经元进行实际预测而不是猜测的概率。理想情况下,预测器对于正面的偏见应该与现实世界中正面的普遍性相匹配(可能在不同的时间和地点变化,例如牛市与熊市,例如申请贷款的人的信用价值与未能偿还贷款的人)-校准到概率具有任意偏见的优势可以被轻松设置。

如果您有两个神经元分别代表两类,则每个神经元都可以像上面那样独立解释,并且它们之间的差值的一半也可以解释。这就像翻转负类神经元并进行平均。这些差异也可以产生重要性概率估计(使用T测试)。

Brier得分及其Murphy分解可给出正确答案的概率的更直接估计,而Informedness给出分类器做出知情决策而非猜测的概率,ROC AUC则给出正类将由正面预测器排名高于负类的概率,Kappa将给出一个类似的数字,当预测偏见=普遍性时与Informedness相匹配。

通常您需要整体分类器的重要性概率(以确保您正在玩真实的领域,而不是在一个假设框架中猜测),以及对于特定示例的概率估计。有各种校准方法,包括对概率进行回归(线性或非线性)并使用其逆函数重新映射到更精确的概率估计。可以通过Brier得分的改进来看到这一点,其中校准组件向0减少,但判别组件保持不变,ROC AUC和Informedness应该保持不变(Kappa会受到偏差的影响而变得更糟)。

一种简单的非线性概率校准方法是使用ROC曲线 - 当单个神经元输出或两个竞争神经元之间的差异的阈值变化时,我们在ROC曲线上绘制真正和假正例率的结果(假负率和真负率自然是补充物,因为不是真正的阳性就是阴性)。 然后,您可以按点扫描ROC曲线(折线)点(每次梯度变化)样本,而正样本的比例给出了与产生该点的神经阈值相对应的阳性概率估计。 曲线上的点之间的值可以在线性插值之间插值,在校准集中表示的点之间进行插值 - 实际上,ROC曲线中的任何错误点,由非凸性(凹痕)表示,都可以通过凸包平滑 - 在凸包段的端点之间以概率方式插值。 Flach和Wu提出了一种技术,实际上翻转了该段,但这取决于使用信息的方式错误,并且尽管它可以针对校准集反复使用以进行任意改进,但它将越来越不可能推广到测试情况。

7

您尝试过Hinton教授的建议,使用softmax激活函数和交叉熵误差训练网络吗?

例如,创建一个具有以下内容的三层网络:

linear neurons   [ number of features ]
sigmoid neurons [ 3 x number of features ]
linear neurons   [ number of classes ]

然后使用您喜欢的优化器(随机下降/iprop加/梯度下降)进行交叉熵误差softmax传递训练。训练后,输出神经元应规范化为1的总和。

有关详细信息,请参见http://en.wikipedia.org/wiki/Softmax_activation_function。 Shark机器学习框架通过组合两个模型提供了Softmax功能。Hinton教授在http://coursera.com上提供了有关详细信息的在线课程。


老实说,经过4年的思考,我已经没有正确的回忆了。我不再认为计算神经网络后验概率是那么简单的事情了。你“可能”是对的。事实上,为了计算神经网络的概率,我建议阅读Bishop的贝叶斯处理。 - Steven Varga

4
我记得在《神经计算理论导论》(Hertz Krogh Palmer)这本书中看到了一个使用反向传播训练的神经网络来近似输出概率的例子。我认为这个例子的关键在于特殊的学习规则,使得你不必将单元的输出转换为概率,而是可以自动获得概率作为输出。
如果有机会,请尝试查阅这本书。
(顺便说一下,“Boltzman机器”虽然不如其他知名,但是它们是专门设计用于学习概率分布的神经网络,您也可以查阅相关资料。)

4
当使用ANN进行二分类和在输出层中使用逻辑Sigmoid激活函数时,输出值可以被解释为概率。
因此,如果你在两个类之间选择,你可以使用1-of-C编码进行训练,其中每个类别的2个ANN输出将具有训练值(1,0)和(0,1)。
要以百分比计算第一个类的概率,只需将第一个ANN输出乘以100。要得到另一个类的概率,请使用第二个输出。
这可用于使用softmax激活函数的多类分类。
你可以在这里阅读更多内容,包括概率解释的证明: [1]Bishop,Christopher M.神经网络用于模式识别。牛津大学出版社,1995年。

0
我知道这个问题并不完全相同,但对于我来说,我有一个涉及多个类别的分类问题,这个视频帮了我很大的忙(而且非常容易理解):

https://www.youtube.com/watch?v=SFsc2P240rw&ab_channel=KapilSachdeva

简而言之,通过指数运算使输出变为正数。要做到这一点,只需调用np.exp()函数。 然后,对输出进行归一化处理,使所有值的总和为1。 可以通过将指数化的输出除以指数化输出的总和来实现这一点。
所以,第一步:
exponentiated_output = np.exp(output)

第二步:
probabilistic_output = exponentiated_output / np.sum(exponentiated_output, axis=0)

现在,输出加起来等于1,是正数,并且值介于0和1之间。因此,概率分布的要求得到满足。
在视频中,他还解释了温度缩放,以便概率差异较小。希望这有所帮助。

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