我的神经网络可以学习 sin x ,但无法学习 cos x。

4
我已经构建了自己的神经网络,但是遇到了奇怪的问题。
这个网络是一个相当简单的前馈1-N-1网络,使用反向传播学习。Sigmoid被用作激活函数。
我的训练集由随机值生成,范围在[-PI,PI]之间,并且它们的[0,1]-缩放正弦值(这是因为"Sigmoid-net"只产生[0,1]之间的值,而未缩放的正弦函数产生[-1,1]之间的值)。
使用该训练集,并将网络设置为1-10-1,学习速率为0.5,一切都很好,网络按照应有的方式学习正弦函数。 但是..如果我完全相同地为余弦函数做所有事情,则网络无法学习它。 无论隐藏层大小或学习速率设置如何。
有任何想法吗? 我错过了什么吗?

编辑:我的问题似乎与this小程序中所见的问题相似。除非首先教一些“更容易”的内容(例如二次函数的1400个周期),否则它似乎无法学习正弦函数。小程序中的所有其他设置都可以保留为初始设置。因此,在正弦或余弦的情况下,似乎需要增强权重,至少在某种程度上正确方向,才能找到解决方案。为什么会这样呢?


1
它学到了什么?这可能会帮助我们猜测问题出在哪里。 - Phil H
我注意到sin(x+0.5*PI)(等于cos x)也不起作用。另外,幂函数(^2、^3等)似乎也不起作用。线性函数可以正常工作。代码中可能存在一些问题,而sin[-PI, PI]函数的成功只是一个奇怪的副作用。 - Simo Erkinheimo
发布一些代码可能有助于我们帮助您。 - g19fanatic
2个回答

1
我很难看出这个怎么能够工作。
据我所见,您有1个输入,1层中的N个节点,然后是1个输出。因此,在网络的隐藏层中,任何节点之间没有区别。假设您有一个输入x和一组权重wi。那么输出节点y将具有以下值:
y = Σiwix
= x . Σiwi 因此,这总是线性的。
为了使节点能够学习不同,它们必须被不同地连接或者/并且可以访问不同的输入。因此,您可以提供值、值的平方根(给予某种规模效应)等输入,并将不同的隐藏层节点连接到不同的输入上,我认为您至少需要另一个隐藏层。
神经网络并不是魔法。它产生一组特定的权重来进行加权求和。由于您可以推导出一组权重来近似正弦或余弦函数,这必须影响您对神经网络需要哪些输入才能有一些成功机会的想法。
一个明确的例子:指数函数的泰勒级数为:
exp(x) = 1 + x/1! + x^2/2! + x^3/3! + x^4/4! ...

如果您提供了6个输入注释,其中包括1、x1、x2等,则仅将每个输入发送到一个对应节点的神经网络,并将其乘以其权重,然后将所有这些输出馈送到输出节点,就能够实现指数函数的6项泰勒展开。

in     hid     out

1 ---- h0 -\
x   -- h1 --\
x^2 -- h2 ---\
x^3 -- h3 ----- y
x^4 -- h4 ---/
x^5 -- h5 --/

虽然不是一个真正的神经网络,但你明白了重点。

在泰勒级数的维基百科页面下面,有关于sin和cos的展开式,分别以x的奇次幂和偶次幂表示(想一想,sin是奇函数,cos是偶函数,是这么简单),所以如果你提供所有的x的幂,我猜测sin和cos版本看起来会非常相似,交替出现零权重。(sin:0、1、0、-1/6...,cos:1、0、-1/2...)


1
我对神经网络还不太熟悉,但是我必须表示不同意。反向传播学习方法会调整网络的所有权重,以便某些当前输入的“节点路径”比其他路径更朝向正确值进行调整。对多个样本执行此操作最终将导致某些隐藏节点对某些输入值更具接受性,而对于其他隐藏节点则有其他情况。这些节点之和+输出处的激活函数可以学习成为任何值(在act.func范围内)以适用于任何输入,假设在隐藏层中有足够的节点。 - Simo Erkinheimo

0

我认为你可以始终计算正弦,然后在外部计算余弦。我想你在这里关心的是神经网络为什么不能学习余弦函数,而它却可以学习正弦函数。假设这不是因为你的代码问题,我建议你尝试以下方法:

  1. 这明显是学习算法中的错误。可能是因为你的起点有误。尝试使用能够为第一个输入提供正确结果的权重开始,然后向前推进。
  2. 检查你的学习是否存在严重的偏差——正值比负值更多
  3. 由于余弦可以通过正弦90减角度来计算,你可以找到权重,然后在1步中重新计算余弦的权重。

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