多层神经网络无法预测负值。

21

我已经实现了一个多层感知器来预测输入向量的正弦值。向量由四个随机选择的-1、0、1组成,并且有一个偏置设置为1。该网络应该预测向量内容总和的正弦值。

例如,输入=<0,1,-1,0,1> 输出= Sin(0+1+(-1)+0+1)

我面临的问题是,该网络永远不会预测负值,并且许多向量的正弦值为负数。它完美地预测所有非负输出。我认为权重更新存在问题,这些权重在每个周期后更新。是否有人遇到过神经网络的这个问题?任何帮助都将是很好的!

注:该网络有5个输入,在1个隐藏层中有6个隐藏单元和1个输出。我在激活隐藏层和输出层时使用sigmoid函数,并尝试了大量的学习速率(目前为0.1)。

3个回答

13

我已经很久没研究过多层感知机了,所以这个结论仅供参考。

我建议将问题域缩放到[0,1]范围内而不是[-1,1]。如果你看一下逻辑函数图:

enter image description here

它生成的值介于[0,1]之间。我不希望它产生负结果,不过我可能是错的。

编辑

实际上您可以将逻辑函数扩展到你的问题域。使用广义逻辑曲线,将A和K参数设置为您的问题域的边界。

另一个选择是双曲正切函数,其取值范围为[-1,+1],无需设置任何常数。


非常感谢,这很有道理!我得找一个可以允许负值的函数。不幸的是,我不能改变问题域,因为这是大学的作业。再次感谢! - B. Bowles
@B. Bowles 我更新了我的答案,并提供了可能的解决方案。 - Vitor Py
太棒了,我现在就试试!那个公式中有很多参数不适用于这个网络,而数学绝对不是我的强项。不过这肯定是未来的发展方向。 - B. Bowles
1
@B. Bowles 双曲正切函数的取值范围为[-1,+1],且无需设置任何常数。我现在才想起来。 - Vitor Py
太好了,而且实现起来容易得多!!我的 $a = exp($activation); 我的 $b = exp(-$activation); $output = ($a-$b)/($a+$b); ……以防有人将来想使用它。非常感谢! - B. Bowles

4

有许多不同种类的激活函数,其中许多被设计为输出0到1之间的值。如果您正在使用一个只输出0到1之间的函数,请尝试调整它,使其输出1到-1之间的值。如果您正在使用 FANN,我会建议您使用 FANN_SIGMOID_SYMMETRIC 激活函数。


不幸的是,我不能在这个任务中使用任何库,真是遗憾!不过我会研究一下它的工作原理,非常感谢。 - B. Bowles

0

虽然这个问题已经有答案了,但是让我分享一下我的经验。我一直在尝试使用1--4--1神经网络来近似正弦函数。即, enter image description here 和你的情况类似,我不能使用任何高级API,如TensorFlow。此外,我必须使用C++而不是Python3!(顺便说一句,我更喜欢C++)。

我使用了Sigmoid激活函数及其导数定义:

double sigmoid(double x) 
{ 
   return 1.0f / (1.0f + exp(-x)); 
}

double Sigmoid_derivative(double x)
{
   return x * (1.0f - x);
}

在训练了20个训练样例的网络进行10,000次迭代后,我得到了以下结果。 enter image description here

可以看出,网络并没有学习到负曲线。因此,我将激活函数改为了Tanh

double tanh(double x)
{
   return (exp(x)-exp(-x))/(exp(x)+exp(-x));
}

double tanh_derivative(double x)
{
   return 1.0f - x*x ;
}

令人惊讶的是,在一半的迭代次数(即5000)之后,我得到了一个更好的曲线。 enter image description here 我们都知道,使用更多的隐藏神经元、更多的迭代次数和更好(更多)的训练示例会显著改善它。此外,洗牌数据也很重要!


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