【问题标题】:Neural network toy model to fit sine function fails, what's wrong?拟合正弦函数的神经网络玩具模型失败,出了什么问题?
【发布时间】:2017-10-29 09:26:06
【问题描述】:

研究生,刚接触Keras 和神经网络试图将一个非常简单的前馈神经网络拟合到一维正弦

以下是我能找到的最合适的三个示例。在图上,您可以看到网络与地面实况的输出


完整的代码,短短几行,贴在这里example Keras


我正在考虑层数、不同的激活函数、不同的初始化以及不同的损失函数、批量大小、训练样本的数量。除了上述示例之外,似乎没有一个能够改善结果。

如果有任何 cmets 和建议,我将不胜感激。正弦是神经网络拟合的硬函数吗?我怀疑答案不是,所以我一定是做错了什么……


5 年前有一个类似的问题here,但是那里的 OP 没有提供代码,仍然不清楚出了什么问题或他如何解决这个问题。

【问题讨论】:

  • 您的网络有多“深”?当且仅当网络的深度和宽度足够大时,ANN 通常擅长处理非线性问题。两三层是优秀的,但单层是愚蠢的。此外,在处理信号(或宽度)的给定层中,您可能没有足够的“分辨率”
  • @PatrickSturm 我尝试了 3 到 10 层之间的任何东西,每层有 10 个或更多神经元。上面说〜4层差异很小。
  • 这绝对够了,所以我很难过。请问一下给了多少个训练样例?
  • @PatrickSturm 1000 到 10000,没有区别...代码在这里gist.github.com/anonymous/c816eb15daf949543e96dd2c64174670
  • 尝试规范化输入值,例如从 -1 到 1。还按比例缩小输出值,因为 tanh 难以处理接近 +/- 1 的值

标签: python machine-learning neural-network deep-learning keras


【解决方案1】:

为了使您的代码正常工作,您需要:

  • 在 [-1, +1] 范围内缩放输入值(神经网络不喜欢大值)
  • 也可以缩放输出值,因为 tanh 激活在接近 +/-1 时效果不佳
  • 在除最后一层外的所有层中都使用 relu 激活而不是 tanh(收敛速度方式更快)

通过这些修改,我能够使用 10 和 25 个神经元的两个隐藏层来运行您的代码

【讨论】:

  • 谢谢,我尝试了你的建议,但这没有帮助。
  • @them 我从你的代码开始.. 我不知道还有什么可以帮助的
  • 感谢您的建议!那么,您是否能够通过建议的更改从我的代码开始近似正弦?我尝试了您的建议,但没有帮助...
  • 能否请您发布您的代码,非常感谢!
  • 谢谢!造成所有差异的变化是我将 X 的范围设置为 [0, 1], 'X = numpy.arange(-1, 1, 0.001)' 的那一行。
【解决方案2】:

由于已经有提供解决方法的答案,因此我将重点关注您的方法存在的问题。

输入数据比例

正如其他人所说,您的输入数据值范围从 0 到 1000 相当大。这个问题可以通过将输入数据缩放到零均值和单位方差 (X = (X - X.mean())/X.std()) 轻松解决,这将提高训练性能。对于tanh,这种改进可以用饱和度来解释:tanh 映射到 [-1;1],因此对于几乎所有足够大的 (>3)x,将返回 -1 或 1,即饱和。在饱和状态下,tanh 的梯度将接近于零,并且不会学到任何东西。当然,您也可以改用ReLU,它不会在值 > 0 时饱和,但是您会遇到类似的问题,因为现在渐变(几乎)仅依赖于x,因此以后的输入总是会产生更大的影响比早期的输入(除其他外)。

虽然重新缩放或归一化可能是一种解决方案,但另一种解决方案是将您的输入视为分类输入并将您的离散值映射到一次性编码向量,而不是

>>> X = np.arange(T)
>>> X.shape
(1000,)

你会的

>>> X = np.eye(len(X))
>>> X.shape
(1000, 1000)

当然,如果您想学习连续输入,这可能是不可取的。

建模

您当前正在尝试对从线性函数到非线性函数的映射建模:您将 f(x) = x 映射到 g(x) = sin(x)。虽然我知道这是一个玩具问题,但这种建模方式仅限于这条曲线,因为f(x)g(x) 没有任何关系。只要您尝试对不同的曲线进行建模,例如sin(x)cos(x),使用相同的网络,您的X 就会出现问题,因为两条曲线的值完全相同。对此问题进行建模的更好方法是预测曲线的下一个值,即代替

X = range(T)
Y = sin(x)

你想要的

X = sin(X)[:-1]
Y = sin(X)[1:]

因此,对于时间步 2,您将获得时间步 1 的 y 值作为输入,而您的损失预计时间步 2 的 y 值。这样您就可以隐式模拟时间。

【讨论】:

  • 感谢您的解释!我想我理解了你所有的 cmets,除了我不完全理解为什么输入的重新调整总是零均值和单位方差。由于输入乘以第一个节点中的权重,因此重新缩放不应该与权重的随机初始化相匹配?
  • 使用 z-score 重新缩放只是实现输入范围的一种方法,该输入范围为您提​​供范围(接近)[-1;1],还有其他技术,例如Min-Max-Scaling,这将根据数据的性质更好地工作(使用 min-max-scaling 更好地执行硬最大值)。这主要取决于您的 数据,只要您的输入数据不失真,您的权重就会(在一定程度上)适应。因此,选择一种不会引入扰动的缩放方法比摆弄初始化更重要。
猜你喜欢
  • 1970-01-01
  • 2020-03-14
  • 2018-10-22
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 2011-08-02
  • 2018-09-10
  • 2019-06-27
相关资源
最近更新 更多