2017-04-13 75 views
6

Próbuję wprowadzić sieci neuronowe Multi-Layer Perceptrons (MLP) przy użyciu EmguCV 3.1 (opakowanie NET NET dla biblioteki OpenCV) w C# (Windows Form). Aby przećwiczyć tę bibliotekę, postanowiłem zaimplementować operację OR przy użyciu MLP.Perceptrony wielowarstwowe w EmguCV

tworzę MLP używając "Initialize" Sposób i nauczyć się go za pomocą metody "Pociąg", jak poniżej:

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); 
} 

Gdzie MIN_ACTIVATION_FUNCTION i MAX_ACTIVATION_FUNCTION są równe i 1.7159 -1.7159, odpowiednio (according to OpenCV Documentation). Po 1000000 iteracjach (jak widać w moim kodu w stanie zatrzymania), przetestować sieć do przewidywania za pomocą Przewidzieć metodę jak poniżej:

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()); 
} 

Oto próbka tego, co przewiduje sieci:
-0,00734469
-0,03184918
0,02080269
-0,006674092

Spodziewam się niektóre rzeczy tak:
-1,7
+1,7
+1.7
+1.7


Co jest nie tak wśród moich kodów?

Należy pamiętać, że używam również wartości 0, 1 dla wartości MIN_ACTIVATION_FUNCTION i MAX_ACTIVATION_FUNCTION, ale nadal nie mam żadnych dobrych wyników.

Aktualizacja 1: Edytuję moje kody, ponieważ pierwsza odpowiedź odnosi się do mnie (nawet testuję swój kod z pomysłem wymienionym w komentarzach). Teraz otrzymuję NaN, gdy zadzwonię pod numer predict.

+0

może zamieścić tutaj otrzymasz więcej informacji zwrotnych - http://www.emgu.com/forum/ –

Odpowiedz

0

Zgodnie z nową wersją EmguCV (Emgu.CV-3.1.0-r16.12) problem polegał na błędzie w wersji 3.1.0. Naprawiono go w Emgu.CV-3.1.0-r16.12. Pobierając tę ​​wersję, otrzymuję poprawne odpowiedzi z mojej sieci.

0

Wygląda na to, że wystąpił błąd w dostarczaniu danych wyjściowych. Użyj tablicy output zamiast input.

Myślę, że twoje odpowiedzi wyjściowe powinny być macierzą 2D (z 2 kolumnami). Ostatnia warstwa powinna mieć 2 neurony wyjściowe, ponieważ masz 2 klasy, na przykład (1, 0) is class "True" i (0, 1) is class "False". Spróbuj także zmienić architekturę swojej sieci. Operator logiczny OR jest rozłączalny liniowo, to znaczy może być wykonywany za pomocą pojedynczego perceptonu.

+0

Dziękuję bardzo za Twoje. Teraz moim problemem są wszystkie wyjścia na NaN! Jak mogę to naprawić? –

+0

Najpierw należy ustawić rozmiar warstwy, a następnie funkcję aktywacji. Zobacz http://stackoverflow.com/questions/36871277/opencv-3-1-ann-predict-returns-nan. Cieszę się że mogę pomóc! – Didgeridoo

+1

@ Babak.Abad Uruchomiłem Twój kod i otrzymałem również wyniki NaN. Użyłem najnowszego pakietu NuGet EmguCV v3.1.0.1 dla .NET Framework 4.5. Próbowałem również uruchomić przykład z [Wiki] (http://www.emgu.com/wiki/index.php/ANN_MLP_ (Neural_Network) _in_CSharp) dla Emgu CV 3.x, ale miałem wszystkie NaN dla 'odpowiedzi' po wywołaniu 'network.Predict (...)'. To bardzo nietypowe zachowanie z 'ANN_MLP' w Emgu CV, wygląda na to, że jest to błąd. Spróbuj przepisać swój kod za pomocą C++ (Open CV) lub używając innej biblioteki C# dla sieci neuronowych. – Didgeridoo