2011-05-01 43 views
11

我想用简单的人工神经网络与反向传播算法一起工作。我创建了一个ANN,我相信我已经正确实施了BP算法,但我当然可能会错。简单的人工神经网络的问题 - 加入

现在,我试图通过给它两个随机数(a,b)在0和0.5之间来训练网络,并让它添加它们。然后,当然,每次网络输出的结果都与a + b的理论答案相比较(这总是可以通过sigmoid函数实现)。

奇怪的是,输出总是收敛到0和1之间的数字(因为它必须,因为sigmoid函数),但是我输入的随机数似乎对它没有影响。

编辑:对不起,它似乎没有收敛。下面是输出的图像:

enter image description here

的权重是随机分布的-1和1之间,但我还试图0和1之间

我还试图给它两个恒定数(0.35,0.9),并试图训练它吐出0.5。这工作并收敛到0.5。如果我给它0和1之间的任意两个随机数,我也训练它吐出0.5,这也是有效的。

如果相反,我的目标是:

vector<double> target; 
target.push_back(.5); 

然后收敛速度非常快,甚至与随机输入:

enter image description here

我已经尝试了几个不同的网络,因为我做到了非常容易为我的网络添加图层。我正在使用的标准一个是有两个输入,一个是2个神经元,另一个是只有一个神经元(输出神经元)。不过,我也尝试添加几个图层,并向它们添加神经元。它似乎没有改变任何东西。我的学习速率等于1.0,但我试过它等于0.5,并没有太大的不同。

有没有人有任何想法我可以尝试?

这甚至是ANN的能力吗?我无法想象它不会,因为他们可以被训练去做这样复杂的事情。

有什么建议吗?谢谢!

这里是我训练它:

//Initialize it. This will be one with 2 layers, the first having 2 Neurons and the second (output layer) having 1. 
vector<int> networkSize; 
networkSize.push_back(2); 
networkSize.push_back(1); 
NeuralNetwork myNet(networkSize,2); 

for(int i = 0; i<5000; i++){ 
    double a = randSmallNum(); 
    double b = randSmallNum(); 
    cout << "\n\n\nInputs: " << a << ", " << b << " with expected target: " << a + b; 

    vector<double> myInput; 
    myInput.push_back(a); 
    myInput.push_back(b); 

    vector<double> target; 
    target.push_back(a + b); 

    cout << endl << "Iteration " << i; 
    vector<double> output = myNet.backPropagate(myInput,target); 
    cout << "Output gotten: " << output[0]; 
    resultPlot << i << "\t" << abs(output[0] - target[0]) << endl; 
} 

编辑:设置我的网络,并从本指南中一直遵循:A pdf。我实现了“工作示例3.1”并得到了与他们相同的确切结果,所以我认为我的实现是正确的,至少就他们而言是如此。

+2

由于神经网络是建立在连接的神经元和每个神经元是加法器本身加权投入,我认为你试图达到的目标有点不明确。因此,要添加两个数字,必须将网络的权重设置为“1”,并且使用标准S形函数时,输出只能在0或1之间。 – 2011-05-01 12:09:37

回答

3

由于@macs的状态,标准sigmoid的最大输出是1,所以,如果你尝试从[0,1]中添加n个数字,那么你的目标应该归一化,即sum(A1,A2,.. An)/ n。

+0

@macs,@vines,对不起,我应该更具体。这两个数字在0和.5之间,所以他们的总和总是可以通过sigmoid函数实现。让我在我原来的帖子中解决这个问题。 – MasterZibZob 2011-05-01 16:49:02

3

在这样的模型中,sigmoid函数(无论是在输出层还是在中间层)主要用于生成类似于0/1切换的东西,同时仍然是一个连续函数,所以用它来表示一系列的数字并不是这种网络设计的目的。这是因为它的设计主要考虑到分类问题。当然,还有其他的NN模型可以做这样的事情(例如,在输出中放下S形,并将其保留为其子节点的总和)。

如果您可以根据对输入进行分类来重新定义模型,那么您可能会得到更好的结果。

的类似任务,其网络会更加适合一些例子:

  1. 测试输出是否比某个一定的放大或缩小 - 这应该是很容易的。
  2. 输出:一系列输出,每个输出表示一个不同的潜在值(例如,对于0到10之间的值,一个用于'大于10',一个用于'小于0')。你会希望你的网络将结果四舍五入到最接近的整数
  3. 一个棘手的问题是尝试通过拥有多个输出节点来创建输出的布尔表示。

这些都不会给你,你可能想,虽然精确,因为自然神经网络更“模糊”

+0

感谢您的回应! 嗯,好吧,我想我可能误解了人工神经网络。但我仍然想弄明白。 所以我尝试了你的第一个问题,如下所示: 'double a = randSmallNum2(); double b = 0; (max(a,.5)== a){ \t b = 1; } \t cout <<“\ n \ n \ n输入:”<< a <<“与预期目标:”<< b; vector myInput; myInput.push_back(a); vector target; target.push_back(b); vector output = myNet.backPropagate(myInput,target);' 当然,在for循环中。它不会给我0或1,每次都应该这样,对吧? 谢谢! – MasterZibZob 2011-05-01 17:11:16

+0

其实通过示例#1我的意思是输入参数的总和是否大于某个数字(不知何故,我从描述中删除了该部分)。你所做的甚至更简单一些,神经网络应该很容易学习。尽管如此,sigmoid函数几乎不会给你0或1,但应该给你非常接近的数字(所以,将0.95设为1,将0.05设为0.你可以选择0.5作为阈值)。 – winter 2011-05-02 11:15:11

+0

嗯...我打算在一些诊断中打印每个级别的信息,然后再回来看结果... 谢谢! – MasterZibZob 2011-05-03 22:52:17