EmguCV中的多层感知器

时间:2017-04-13 18:25:12

标签: c# neural-network opencv3.1 emgucv

我试图在C#(Windows Form)中使用EmguCV 3.1(OpenCV库的点.NET包装器)实现多层感知器(MLP)神经网络。为了练习这个库,我决定使用MLP实现OR操作。

我使用"初始化"创建MLP。方法并使用" Train"方法如下:

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_FUNCTIONMAX_ACTIVATION_FUNCTION分别等于-1.7159和1.7159(according to OpenCV Documentation)。经过1000000次迭代(如我在停止条件下的代码中所见),我使用Predict方法测试我的网络进行预测,如下所示:

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

以下是NETWORK预测的示例:
-0.00734469
-0.03184918
0.02080269
-0.006674092

我希望有这样的事情:
-1.7
+1.7
+1.7
+1.7


我的代码有什么问题?

请注意,我也使用0,1表示MIN_ACTIVATION_FUNCTIONMAX_ACTIVATION_FUNCTION值,但我仍然没有任何好结果。

更新1: 我编辑我的代码,因为第一个答案引用了我(甚至我用评论中引用的想法测试我的代码)。现在,我在调用NaN方法时获得predict

2 个答案:

答案 0 :(得分:0)

您似乎在提供输出数据时出错。使用output数组而不是input

我认为你的输出响应应该是2D矩阵(有2列)。最后一层应该有2个输出神经元,因为你有2个类,例如(1, 0) is class "True"(0, 1) is class "False"。还尝试更改网络的体系结构。逻辑运算符OR是线性可分的,即可以使用单个感知器执行。

答案 1 :(得分:0)

根据新版本的EmguCV(Emgu.CV-3.1.0-r16.12),问题是版本3.1.0中的错误现在它已在Emgu.CV-3.1.0-r16.12中修复。通过下载此版本,我得到了来自我的网络的正确回复。