如何在神经网络中转换输入并提取有用的输出?


9

因此,自从我碰到Adam Geitgey关于机器学习博客以来,我就一直试图理解神经网络。我已经读了尽可能多的关于该主题的文章(我能理解),并且相信我理解所有广泛的概念和一些工作原理(尽管数学上很弱),神经元,突触,权重,成本函数,反向传播但是,我还无法弄清楚如何将现实世界中的问题转化为神经网络解决方案。

典型的例子,亚当Geitgey给出作为一个例子使用,其中给定的包含数据集的房子的价格预测系统的卧室号平方。脚邻居销售价格,你可以训练神经网络,以能够预测的房子的价格。但是,他没有在代码中实际实现可能的解决方案。举例来说,他得到的最接近的是一个基本函数,该函数演示了如何实现权重:

def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
  price = 0

  # a little pinch of this
  price += num_of_bedrooms * 1.0

  # and a big pinch of that
  price += sqft * 1.0

  # maybe a handful of this
  price += neighborhood * 1.0

  # and finally, just a little extra salt for good measure
  price += 1.0

  return price 

其他资源似乎更多地集中在数学上,我可以发现我理解的唯一基本代码示例(即,不是所有唱歌,所有跳舞图像分类代码库)都是将神经网络训练为XOR的实现。仅处理1和0的门。

因此,我的知识差距似乎无法弥合。如果我们回到房价预测问题,那么如何使数据适合于馈入神经网络呢?例如:

  • 卧室数量:3
  • 平方 脚:2000
  • 邻里:师范大学城
  • 成交价:$ 250,000

您可以将32000直接输入神经网络吗,因为它们是数字?还是您需要将它们转换成其他东西?同样,Normaltown值(即字符串)又如何处理,将其转换为神经网络可以理解的值呢?只要在整个数据中保持一致,您是否可以选择一个数字,例如索引?

我看到的大多数神经网络示例在层之间传递的数字都是0到1或-1到1。因此,在处理结束时,如何将输出值转换为可用的值,例如$ 185,000

我知道房价预测示例可能并不是一个特别有用的问题,因为它已经大大简化了三个数据点。但是我只是觉得,如果我能克服这个障碍,编写一个非常基本的应用程序,使用伪真实的数据进行训练,并给出伪真实的答案,那我将不为所动。继续深入研究机器学习。

Answers:


10

这是一个很好的问题,当我第一次尝试编写ANN时,我曾为之奋斗。

下面是一个很好的通用解决方案,它是我在我的代码中实现的一种用于尝试预测行为良好的数值数据的解决方案。如果您的数据表现不佳(即充满异常值),则可能需要做更多的工作来标准化输入和输出。这里描述一些更高级的方法。

注意:我假设您使用f(x)= tanh(x)作为激活函数。如果不是这样,那么在阅读本文之后,您仍然应该能够推理出如何规范化数据。

如何准备输入数据:

基本思想是,您希望每个输入参数的显着变化都可以通过将这些输入馈入的神经元的激活变化来反映出来。通过查看tanh(x)激活函数的导数图,您会看到明显斜率的区域位于距原点一或两个距离之内。这意味着无论激活函数的输入是2000还是3000(x的导数很小的值),激活的输出都几乎相同...因此您的神经元状态将独立于2000和3000,您的网络将永远不会根据该范围内的值产生任何预测能力。

因此,如果要将房屋的平方英尺输入到神经元中,则需要对平方英尺进行归一化,以便网络可以分辨出2000年和3000年之间的差异。这样做的一种方法是,使您的所有显着变化神经元“注意到”数据是对输入进行z分数归一化

  • 收集所有平方英尺值(来自您的训练集),然后计算均值和标准差。存储平均值和标准偏差 -测试时,您将需要此信息来标准化新的平方英尺值。

  • 通过减去平均值,然后将结果除以标准偏差,对平方英尺长度值的向量进行归一化(当然,所有操作都是逐元素方式)。减去均值会将您的数据以原点为中心,然后除以标准差,可以确保大多数数据都在-1和1之间,此时神经元的输出对其输入最敏感。之所以称为z分数标准化,是因为每个输入值都被其z分数替换。

  • 对每个输入变量执行上述操作。

现在,当您通过神经元输入每个输入值时,神经元的输出是介于-1和1之间的激活(请看tanh(x)的图像)。由于这已经处于激活功能的“敏感”范围内,因此您无需担心在将输入层神经元发送到第一个隐藏层之前更改其输入层的输出。只需直接给任何隐藏层神经元上一层的输出 -他们就能很好地处理它们。

当到达最后一层(输出神经元)时,您得到的又是在-1和1之间的另一次激活。您必须将此值转换回所讨论房屋的值,该值是否将用作测试集中的预测或训练过程中的误差计算。无论您这样做是什么,您都必须保持一致,并在训练和测试中使用相同的去标准化过程。考虑它的一种方法是:当输出神经元返回1时,这意味着网络将返回最大可能的房屋价值作为其预测。网络可以估计的最高值是多少?正确的方法仅取决于您的应用程序。这是我所做的:

  • 计算[the / each]输出变量的平均值并存储它。
  • 计算输出变量与平均值的最大偏差。蟒蛇:MaxDev = max([abs(DataPoint-numpy.mean(TrainingData)) for DataPoint in TrainingData])
  • 当网络返回的输出在-1和1之间时,将其乘以MaxDev并加到平均值上。

您可以进行两项基本的快速检查,以查看您的归一化-再归一化方案是否合适(这些是必要条件,但可能还不够充分):

  1. 如果所有输入值都是平均值(例如平均卧室数,平均平方英尺等),则网络的输出是否也等于输出变量的平均值(例如房屋价值)?(它应该是。)
  2. 如果所有输入值都异常高/低,网络的输出也异常高/低吗?(这仅在所有输入与输出呈正相关时才有效...如果其中一些与输出呈负相关,则您需要多考虑一点)。

请注意,此处介绍的方案可以满足这两个条件。

请注意,该方案将允许您的网络只预测房屋的价值在你的训练数据集的房子值的范围。取决于应用,此行为可能是理想的还是不希望的。

例如:您可能想让网络无法预测房屋的负值。考虑一下您将如何做。对输出进行去规格化,以便将-1映射到0。

如果您不想对网络可以预测的值设置任何限制,则可以通过将[-1,1]范围映射到所有实数的函数来运行网络的输出,例如arctanh(x)!只要您在训练期间执行此操作,您的网络就会调整其权重以适应此情况。

我希望这可以帮到你。如果您还有其他问题,请告诉我。顺便说一下,我的ANN模块是使用Python编写的,所以我可能会针对特定语言提供建议。


这非常有用!我遇到的每个博客/教程似乎都避免(几乎是有意地)描述了此过程,但是是的,这一切都说得通。我需要一段时间才能正确消化,但是如果有任何后续问题,我会回来的。多谢!
大卫,

有几个问题。如果我的平方。脚训练数据为{2000,800,850,550,2000},那么我的{1900,1500,600}的z得分输入将为{1.0496,0.4134,-1.0177}(如果我计算正确的话)。所以这些值之一是> 1,一个是<-1,我该怎么办?是否将它们输入到输入层节点中,还是将它们四舍五入为1和-1?为什么1900和600在550-2000范围内时会产生这些值?因为有这么小的数据集,这仅仅是数据的把戏吗?
大卫,

0一个ñdŤHË一个X一世ü

请记住,输入不必严格在1到-1之间。您所需要的输入就是大部分数据都在该范围内。大于或小于1的值表示该点与平均值相差一个标准偏差以上,因此该点更接近数据的高端。您的数据不在[-1,1]之外的情况应该很少见,在[-2,2]之外的数据甚至在[-3,3]之外的情况都很少见。查看tanh(x),您会看到敏感范围不仅严格在-1和1之间,而且还远不止于此。
MarkoBakić17年

关于输出非规范化,最小-最大非规范化是我在实现中所做的,您的解释是正确的,但是您不必一定要这样做。您可以做到1等于最大房屋价值的两倍-这样,您的网络就可以预测超出培训范围的房屋价值。
MarkoBakić17年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.