2017-04-13 54 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