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

人工智能 神经网络 机器学习
2021-10-26 22:39:07

所以自从我看到Adam Geitgey 的机器学习博客以来,我一直在尝试理解神经网络。我已经尽可能多地阅读了这个主题(我能掌握),并相信我理解所有广泛的概念和一些工作原理(尽管数学很弱)、神经元、突触、权重、成本函数、反向传播等等。但是,我无法弄清楚如何将现实世界的问题转化为神经网络解决方案。

举个例子,Adam Geitgey 给出了一个例子,一个房价预测系统,其中给定一个包含卧室数量,Sq 的数据集。英尺邻域销售价格,您可以训练神经网络来预测房屋价格。然而,他没有在代码中实际实现可能的解决方案。举个例子,他得到的最接近的是基本的一个函数,演示了如何实现权重:

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

我知道房价预测示例可能不是一个特别有用的问题,因为它被大量过度简化为仅三个数据点。但我只是觉得,如果我能克服这个障碍并编写一个非常基本的应用程序,使用伪现实生活数据进行训练并吐出一个伪现实生活的答案,那么我就会打破它并能够踢继续深入研究机器学习。

1个回答

这是一个很好的问题,当我第一次尝试编写 ANN 时,我一直在与自己搏斗。

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

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

如何准备输入数据:

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

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

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

  • 通过减去平均值然后将结果除以标准偏差来标准化平方英尺值的向量(当然,所有操作都是按元素计算的)。减去平均值将您的数据集中在原点,然后除以标准差,确保大部分数据在 -1 和 1 之间,其中神经元的输出对其输入最敏感。这称为 z-score 归一化,因为每个输入值都被其z-score替换。

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

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

当您到达最后一层(输出神经元)时,您再次获得介于 -1 和 1 之间的另一个激活值。您必须将其转换回相关房屋的值,该值是否将用作测试集中的预测或在训练期间计算错误。不管你怎么做,你只需要保持一致并在训练和测试中使用相同的反规范化过程。一种思考方式是:当输出神经元返回 1 时,这意味着网络正在返回最大可能的房屋价值作为其预测。网络可以估计的最高值应该是多少?此处正确的方法仅取决于您的应用程序。这就是我所做的:

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

你可以做两个基本的快速检查,看看你的规范化重规范化方案是否合适(这些是必要的,但可能不是充分的条件):

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

注意这里提出的方案满足这两个条件。

请注意,此方案将允许您的网络仅预测训练数据集中房屋价值范围的房屋价值。根据应用程序,此行为可能是可取的或不可取的。

例如:您可能希望您的网络无法预测负房屋价值。想想你会怎么做。对输出进行反规范化,使 -1 映射到 0。

如果您想对网络可以预测的值没有限制,那么您可以通过将 [-1,1] 范围映射到所有实数的函数来运行网络的输出......比如 arctanh(x)!只要您在训练期间这样做,您的网络就会调整其权重以适应这种情况。

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