Perl 多层神经网络;不要预测负值

Perl 多层神经网络;不要预测负值,perl,neural-network,classification,backpropagation,Perl,Neural Network,Classification,Backpropagation,我已经实现了一个多层感知器来预测输入向量的sin。向量由随机选择的四个-1,0,1和设置为1的偏差组成。网络应该预测向量内容和的sin eg输入=输出=正弦(0+1+(-1)+0+1) 我遇到的问题是,网络永远不会预测负值,而且很多向量的sin值都是负值。它完美地预测了所有正输出或零输出。我假设在更新权重时存在问题,权重在每个历元之后都会更新。以前有人遇到过NN的这个问题吗?任何帮助都会很好 注意:网络有5个输入,6个隐藏单元,1个隐藏层和1个输出。我在激活隐藏层和输出层上使用了一个sigmoi

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

eg输入=输出=正弦(0+1+(-1)+0+1)

我遇到的问题是,网络永远不会预测负值,而且很多向量的sin值都是负值。它完美地预测了所有正输出或零输出。我假设在更新权重时存在问题,权重在每个历元之后都会更新。以前有人遇到过NN的这个问题吗?任何帮助都会很好


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

我已经很久没有研究多层感知器了,因此对此持保留态度

我会将您的问题域重新缩放到[0,1]域,而不是[-1,1]。如果您查看逻辑函数图:

它生成的值介于[0,1]之间。我不期望它会产生负面结果。我可能错了,坚强

编辑

实际上,您可以将逻辑功能扩展到您的问题域。使用设置域边界的A和K参数


另一个选项是双曲正切,它从[-1,+1]开始,没有常数可设置。

有许多不同类型的激活函数,其中许多函数设计用于输出从0到1的值。如果您使用的函数只输出0到1之间的值,请尝试对其进行调整,使其输出值介于1到-1之间。如果您正在使用,我会告诉您使用激活功能。

虽然问题已经回答,但请允许我分享我的经验。我一直在尝试使用1--4--1神经网络来近似正弦函数。即, 与您的情况类似,我不允许使用任何像TensorFlow这样的高级API。此外,我还必须使用Python 3上的C++!(顺便说一句,我更喜欢C++)

我使用了Sigmoid激活及其衍生物,定义如下:

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

double Sigmoid_derivative(double x)
{
   return x * (1.0f - x);
}
这是我在10000个时代之后得到的,在20个培训示例上对网络进行培训。

正如你所看到的,网络并不像是一条负曲线。因此,我将激活函数更改为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),我得到了一条更好的曲线。
我们都知道,使用更多隐藏的神经元、更多的时间和更好的(和更多的)训练范例,这将显著提高。此外,对数据进行洗牌也很重要

非常感谢,这是有道理的!我必须四处寻找一个可以允许负值的函数。不幸的是,我不能改变这个问题领域,因为它是大学的一项作业。再次感谢@鲍尔斯用一个可能的解决方案更新了我的答案。太好了,我现在就试试看!这个公式中有很多参数不适用于这个网络,数学肯定不是我的强项。当然,这听起来像是前进的方向。@B.Bowles双曲正切也从[-1,+1]开始,没有常数可设置。我现在才想起来。那太棒了,而且更容易实现!!我的$a=exp($activation);my$b=exp($activation)$输出=($a-$b)/($a+$b)。。。以防万一将来有人对它感兴趣。非常感谢,很幸运,我不能在这个任务中使用任何LIB,如果有的话!不过,我已经了解了它的工作原理,非常感谢