2014-07-20 79 views
3

我剛剛創建了我的第一個神經網絡,它使用了梯度法和反向傳播學習算法。它使用雙曲正切作爲激活函數。代碼很好地測試了單元,所以我充滿了希望網絡能夠真正工作的良好願望。然後我決定創建一個集成測試,並嘗試教我的網絡來解決一些非常簡單的功能。基本上我正在測試體重是否會提高(只有一個,因爲這是一個非常小的網絡輸入加上一個神經元)。神經網絡是否只能解決0..1個輸入值和0..1個期望輸出值的問題?

// Combinations of negative sign for values greater than 1 
    [TestCase(8, 4)] // FAIL reason 1 
    [TestCase(-8, 4)] // FAIL reason 1 
    [TestCase(8, -4)] // FAIL reason 1 
    [TestCase(-8, -4)] // FAIL reason 1 
    // Combinations of negative sign for values lesser than 1 
    [TestCase(.8, .4)] // OK 
    [TestCase(-.8, .4)] // FAIL reason 2 
    [TestCase(.8, -.4)] // FAIL reason 2 
    [TestCase(-.8, -.4)] // OK 
    // Combinations of negative sign for one value greater than 1 and the other value lesser than 1 
    [TestCase(-.8, 4)] // FAIL reason 2 
    [TestCase(8, -.4)] // FAIL reason 2 
    // Combinations of one value greater than 1 and the other value lesser than 1 
    [TestCase(.8, 4)] // OK 
    [TestCase(8, .4)] // FAIL reason 1 
    public void ShouldImproveLearnDataSetWithNegativeExpectedValues(double expectedOutput, double x) 
    { 
     var sut = _netBuilder.Build(1, 1); // one input, only one layer with one output 
     sut.NetSpeedCoefficient = .9; 

     for (int i = 0; i < 400; i++) 
     { 
      sut.Feed(new[] { x }, new[] { expectedOutput }); 
     } 

     var postFeedOutput = sut.Ask(new[] { x }).First(); 
     var postFeedDifference = Math.Abs(postFeedOutput - expectedOutput); 
     postFeedOutput.Should().NotBe(double.NaN); 
     postFeedDifference.Should().BeLessThan(1e-5); 
    } 

我非常失望,因爲大多數測試用例失敗(只有3個標記爲'// OK')。我深入瞭解代碼並發現了一些有趣的事實。

  1. 雙曲線正切最大值爲1,所以不管有多大重量的總和*輸入,神經元的輸出絕對值總是會< = 1,換句話說淨永遠也學不會解決函數,如果它的返回絕對值大於1.這就解釋了8,8個預期輸出的測試用例的所有失敗。
  2. 在其中一個數字爲負的測試案例中,最終權重也應該是負數。首先它會減少,但它永遠不會變成負面的。它要麼停止在0左右,要麼跳到0左右。

神經網絡是否只能解決0..1個輸入值和0..1個預期輸出值的問題或者我的實現有問題?

回答

2

您可以從NN獲得其他輸出。如果您想要離散輸出(分類),請使用Softmax Regression。相反,如果你想連續輸出(迴歸),那麼你必須在輸出範圍(min,max)和(0,1)之間創建一個雙射映射。在大多數情況下,映射f:(min,max) - >(0,1),f(x)=(x-min)/(max-min)就足夠了。

在試驗情況下的數字之一是負的,最終權重也應該是否定的

爲什麼最終權重也應該是否定的?

你可以有任何數字作爲輸入。 (儘管將特徵歸一化到較小範圍是很好的做法,通常通過使它們具有均值0和標準差1)

+0

我的意思是如果我只有一個權重(這是一個非常小的網絡)將負向輸入轉變爲正向輸出的方式是重量變爲負值時。在我的淨重中,體重會在0左右波動,但不會顯着負面。 – gisek

+0

你定義的輸入和輸出值的範圍是什麼,映射規則是什麼(我的意思是,如果輸入是8,我應該輸出什麼,我不明白) – Ranic

+0

這個網絡中有一個神經元,它有一個重量到唯一的輸入。首先,權重用0..1的隨機數初始化 - 我們稱之爲'X'。然後,當我將0.4輸入到輸入時,我試圖教網輸出-0.8。首先輸出是0.4 * X(記住,X是正數)。在迭代過程中,X的權重不斷減小(這是好的),直到它達到0爲止。它在零的正負邊上波動(這是壞的),它永遠不會接近-2。 (0.4 *( - 2)= - 0.8)。 我正在使用此alg。 http://home.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html – gisek