2011-05-01 48 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