2011-07-05 32 views
0

我想在我的應用程序中使用NeuronDotNet。 請考慮這個類:在c中的NeuronDotNet的麻煩#

using NeuronDotNet.Core; 

public class CostomNeuralNetwork 
     { 
      public static double[] SampleInput = new double[] {4, 2, 8, 6, 15, 49, 22}; 
      public static double[] SampleOutput = new double[] {4, 2}; 

      private BackpropagationNetwork network; 

      public CostomNeuralNetwork() 
      { 
       var inputLayer = new LinearLayer(7); 
       var hiddenLayer = new SigmoidLayer(20); 
       var outputLayer = new SigmoidLayer(2); 

       new BackpropagationConnector(inputLayer, hiddenLayer).Initializer = new RandomFunction(0d, 0.3d); 
       new BackpropagationConnector(hiddenLayer, outputLayer).Initializer = new RandomFunction(0d, 0.3d); 

       network = new BackpropagationNetwork(inputLayer, outputLayer); 
       network.SetLearningRate(0.3); 
      } 

      public void Train(double[] input,double []output) 
      { 
       var set = new TrainingSet(7, 2); 
       set.Add(new TrainingSample(input, output)); 
       network.Learn(set, 10000); 
      } 

      public double[] Estimate(double[] input) 
      { 
       var res = network.Run(input); 
       return res; 
      } 
     } 

,當我嘗試使用這個類與此代碼:

var costomNetwork = new CostomNeuralNetwork(); 
      costomNetwork.Train(CostomNeuralNetwork.SampleInput, CostomNeuralNetwork.SampleOutput); 
      costomNetwork.Estimate(CostomNeuralNetwork.SampleInput); 

百達答案從估算方法返回的是一個包含thow成員的值是1.0雙陣列或者像0.9999923之類的東西。 無論我傳遞給估計方法的數據如何,它都會返回與答案相同的內容。 我做錯了什麼,以便通過任何輸入返回相同的輸出?有沒有人有這個代碼相同的問題?

+0

qiback - 我有完全相同的問題,因爲你現在 - 如果你解決了這個問題,你可以發佈你的解決方案 – Johnv2020

+0

我無法找到解決這個問題... – qiback

回答

0

我看到你已經硬編碼了幾個東西(神經元的數量,層數,學習速率,S形函數等)。前一段時間,當我使用不同的圖書館與人工神經網絡一起工作時,發現對這些數值進行大量實驗是最有幫助的。我使用的庫提供了一個用戶界面,使我可以輕鬆調整和嘗試不同的值,直到網絡開始變得有用。

使用交互式GUI對網絡進行培訓要容易得多。在GUI中進行訓練後,我將它保存到磁盤,然後將網絡加載到我的軟件中。如果你可以開發這種工作流程,你可以節省一些頭痛。

我的第一個建議是嘗試一個低得多的訓練時間值。 10000對我來說似乎很重要。你不希望網絡過度學習。此外,如果您有一種方法可以查看每個神經元連接的權重,這可能會幫助您得出其他結論。

編輯: 你也一定會嘗試使用不同的樣本輸入和輸出進行訓練,而不僅僅是你在這裏給出的一個樣本。網絡應該學習各種數據。不要試圖在一個樣本上太透徹地教它。

+0

謝謝。但不管我用不同的值教我的網絡多少,它總是會爲任何輸入數據返回相同的答案。但我會檢查每個連接的重要性。這可能是希望... – qiback

+0

你在改變哪些值?你在改變神經元的數量嗎?你在添加/刪除圖層嗎?你在改變sigmoid函數嗎?等所有這些東西都需要進行實驗。 – Phil

+0

@ phill不只是改變用於訓練的輸入值和輸入輸出設定值,我更改並且不應答變化。 – qiback

0

首先抱歉爲遲到的答案。 現在,看看您用於輸出層的激活函數。 sigmoid函數(有關更多詳細信息,請參見wikipedia)只能用於二進制輸出(對於正常sigmoid,通常爲0到1)。所以,如果你以這種方式訓練網絡,你總會得到1,因爲它與你想要的輸出(4,2或其他)最接近。 嘗試給輸出單元一個線性激活函數,這應該更好。像Phil說的那樣,你可以使用其他一些參數。下面是爲我工作的結構:

  • hiddenLayer:乙狀結腸
  • outputLayer:線性
  • learningRate:0.1(0.3太高)
  • 曆元:100(比enugh更多,但萬也可以,因爲這是反向傳播和一個非常簡單的例子,所以沒有什麼會出錯的)。

    正如你可以在下面的圖片中看到,誤差達到0速度非常快(5%左右,這意味着5個時期):

development of error

這裏是鏈接我使用的程序:Download NNSpace。這個程序(NNSpace)也基於。NET平臺和C#,但使用圖形用戶界面而不是手動編碼每個步驟。如果您有任何問題,請隨時通過email與我聯繫。

編輯:對不起,我忘了提及的是,從來就創建的課程的一些偏見單位(沒有人會跑backprop沒有他們),鴕鳥政策知道NeuronDotNet是否自動執行呢?

1

這裏的問題是與NeuronDotNet本身,而不是你的實現。基本上是neurondotnet輸出訓練數據必須小於1的BackPrpogation網絡下面的代碼工作正常

public class LinearNeural 
{ 
    public static double[] SampleInput = new double[] { 1d,2d,3d,4d,5d,6d,7d }; 
    public static double[] SampleOutput = new double[] { 0.01d, 0.02d, 0.06d, 0.08d, 0.10d, 0.12d, 0.14d }; 
    private double learningRate = 0.3d; 
    private int neuronCount = 10; 
    private int cycles = 100; 
    private BackpropagationNetwork network; 


    public LinearNeural() 
    { 

    } 


    public List<double> DoWork() 
    { 

     LinearLayer inputLayer = new LinearLayer(1); 
     LinearLayer hiddenLayer = new LinearLayer(neuronCount); 
     LinearLayer outputLayer = new LinearLayer(1); 
     new BackpropagationConnector(inputLayer, hiddenLayer).Initializer = new RandomFunction(0d, 0.3d); 
     new BackpropagationConnector(hiddenLayer, outputLayer).Initializer = new RandomFunction(0d, 0.3d); 
     network = new BackpropagationNetwork(inputLayer, outputLayer); 
     network.SetLearningRate(learningRate); 


     TrainingSet trainingSet = new TrainingSet(1, 1); 

     for (int i = 0; i < SampleInput.Count(); i++) 
     { 
      double xVal = SampleInput[i]; 
      for (double input = SampleInput[i] - 0.05; input < SampleInput[i] + 0.06; input += 0.01) 
      { 
       trainingSet.Add(new TrainingSample(new double[] { input }, new double[] { SampleOutput[i] })); 
      } 
     } 

     network.Learn(trainingSet, cycles); 
     return StopLearning(); 

    } 


    public List<double> StopLearning() 
    { 
     var retList = new List<double>(); 
     if (network != null) 
     { 
      network.StopLearning(); 
      for (double xVal = 0; xVal < 10; xVal += 0.05d) 
      { 
       retList.Add(network.Run(new double[] {xVal})[0]); 
      } 
     } 
     return retList; 
    }