2017-04-13 101 views
6

我試圖在C#(Windows窗體)中使用EmguCV 3.1(OpenCV庫的一個dot包裝器)實現多層感知器(MLP)神經網絡。爲了練習這個庫,我決定實施使用MLP的OR操作。EmguCV中的多層感知器

創建MLP使用 「初始化」 方法,並使用如下 「火車」 的方法學起來:

private void Initialize() 
{ 
    NETWORK.SetActivationFunction(
    ANN_MLP.AnnMlpActivationFunction.SigmoidSym); 

    NETWORK.SetTrainMethod(ANN_MLP.AnnMlpTrainMethod.Backprop); 

    Matrix<double> layers = new Matrix<double>(new Size(4, 1)); 
    layers[0, 0] = 2; 
    layers[0, 1] = 2; 
    layers[0, 2] = 2; 
    layers[0, 3] = 1; 
    NETWORK.SetLayerSizes(layers); 
} 

private void Train() 
{ 
    // providing data for input 

    Matrix<float> input = new Matrix<float>(4, 2); 
    input[0, 0] = MIN_ACTIVATION_FUNCTION; input[0, 1] = MIN_ACTIVATION_FUNCTION; 
    input[1, 0] = MIN_ACTIVATION_FUNCTION; input[1, 1] = MAX_ACTIVATION_FUNCTION; 
    input[2, 0] = MAX_ACTIVATION_FUNCTION; input[2, 1] = MIN_ACTIVATION_FUNCTION; 
    input[3, 0] = MAX_ACTIVATION_FUNCTION; input[3, 1] = MAX_ACTIVATION_FUNCTION; 

    //providing data for output 
    Matrix<float> output = new Matrix<float>(4, 1); 
    output[0, 0] = MIN_ACTIVATION_FUNCTION; 
    output[1, 0] = MAX_ACTIVATION_FUNCTION; 
    output[2, 0] = MAX_ACTIVATION_FUNCTION; 
    output[3, 0] = MAX_ACTIVATION_FUNCTION; 


    // mixing input and output for training 
    TrainData mixedData = new TrainData(
     input, 
     Emgu.CV.ML.MlEnum.DataLayoutType.RowSample, 
     output); 

    // stop condition = 1 million iterations 
    NETWORK.TermCriteria = new MCvTermCriteria(1000000); 

    // training 
    NETWORK.Train(mixedData); 
} 

MIN_ACTIVATION_FUNCTION,並且MAX_ACTIVATION_FUNCTION等於-1.7159和1.7159,分別爲(according to OpenCV Documentation)。經過100萬次迭代(因爲你在我停止狀態代碼中看到的),我測試的網絡進行預測採用如下方法預測:

private void Predict() 
{ 
    Matrix<float> input = new Matrix<float>(1, 2); 
    input[0, 0] = MIN_ACTIVATION_FUNCTION; 
    input[0, 1] = MIN_ACTIVATION_FUNCTION; 

    Matrix<float> output = new Matrix<float>(1, 1); 

    NETWORK.Predict(input, output); 
    MessageBox.Show(output[0, 0].ToString()); 

    ////////////////////////////////////////////// 

    input[0, 0] = MIN_ACTIVATION_FUNCTION; 
    input[0, 1] = MAX_ACTIVATION_FUNCTION; 

    NETWORK.Predict(input, output); 
    MessageBox.Show(output[0, 0].ToString()); 

    ////////////////////////////////////////////// 

    input[0, 0] = MAX_ACTIVATION_FUNCTION; 
    input[0, 1] = MIN_ACTIVATION_FUNCTION; 

    NETWORK.Predict(input, output); 
    MessageBox.Show(output[0, 0].ToString()); 

    //////////////////////////////////////////////// 

    input[0, 0] = MAX_ACTIVATION_FUNCTION; 
    input[0, 1] = MAX_ACTIVATION_FUNCTION; 

    NETWORK.Predict(input, output); 
    MessageBox.Show(output[0, 0].ToString()); 
} 

這裏是一個什麼樣的網絡預測的示例:
-0.00734469
-0.03184918
0.02080269
-0.006674092

我希望有一些事情是這樣的:
-1.7
+1.7
+1.7
+1.7


我的代碼有什麼問題?

請注意,我也使用0,1爲MIN_ACTIVATION_FUNCTIONMAX_ACTIVATION_FUNCTION值,但我仍然沒有任何好的結果。

更新1: 我編輯我的代碼作爲第一個答案引用我(即使我測試我的代碼與意見中引用的意見)。現在我打電話predict方法得到NaN

+0

也許在這裏發佈會收到更多反饋 - http://www.emgu.com/forum/ –

回答

0

根據EmguCV的新版本(Emgu.CV-3.1.0-r16.12),問題是版本3.1.0中的一個錯誤。現在它被修復爲Emgu.CV-3.1.0-r16.12。通過下載此版本,我可以從我的網絡獲得正確的答覆。

0

看來您在提供輸出數據時有錯誤。使用output而不是input

我認爲你的輸出響應應該是二維矩陣(2列)。最後一層應該有2個輸出神經元,因爲你有2個類,例如(1, 0) is class "True"(0, 1) is class "False"。也嘗試更改網絡的體系結構。邏輯運算符OR是可線性分離的,即它可以使用單個感知器執行。

+0

非常感謝您的支持。現在我的問題是所有的輸出都是NaN!我該如何解決它? –

+0

確保先設置圖層大小,然後設置激活功能。請參閱http://stackoverflow.com/questions/36871277/opencv-3-1-ann-predict-returns-nan。很高興幫助你! – Didgeridoo

+1

@ Babak.Abad我運行了你的代碼並且也收到了NaN結果。我爲.NET Framework 4.5使用了最新的NuGet包EmguCV v3.1.0.1。 另外我試着從[Wiki](http://www.emgu.com/wiki/index.php/ANN_MLP_(Neural_Network)_in_CSharp)爲Emgu CV 3.x運行一個例子,但是我的所有NaN都是'response'在調用'network.Predict(...)'之後。 Emgu CV中'ANN_MLP'的行爲非常異常,似乎是bug。 嘗試使用C++(Open CV)或使用其他C#庫來重寫您的代碼以實現神經網絡。 – Didgeridoo