无法在Java中使用Opencv 3中的ANN_MLP

时间:2016-01-19 14:55:18

标签: java c++ opencv

我尝试在OpenCV 3.0中使用ANN_MLP来训练用于简单XOR操作的模型(即00-> 0,01-> 1,10-> 1,11-> 0)。但是当我打电话给nn.predict时,它返回了NaN。代码有什么问题?这是我的Java代码:

package jm.app;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.TermCriteria;
import org.opencv.ml.ANN_MLP;
import org.opencv.ml.Ml;
import org.opencv.ml.StatModel;

public class Main {
    static{System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}

    public static void main(String[] args) {        
        Mat trainData = new Mat(4, 2, CvType.CV_32FC1);
        trainData.put(0, 0, 0);
        trainData.put(0, 1, 0);

        trainData.put(1, 0, 0);
        trainData.put(1, 1, 1);

        trainData.put(2, 0, 1);
        trainData.put(2, 1, 0);

        trainData.put(3, 0, 1);
        trainData.put(3, 1, 1);

        Mat trainLabels = new Mat(4, 1, CvType.CV_32FC1);
        trainLabels.put(0, 0, 0);
        trainLabels.put(1, 0, 1);
        trainLabels.put(2, 0, 1);
        trainLabels.put(3, 0, 0);

        ANN_MLP nn = ANN_MLP.create();
        nn.setActivationFunction(ANN_MLP.SIGMOID_SYM);
        nn.setTrainMethod(ANN_MLP.BACKPROP);        
        nn.setBackpropMomentumScale(0.1);
        nn.setBackpropWeightScale(0.1);
        nn.setTermCriteria(new TermCriteria(TermCriteria.MAX_ITER, (int)100000, 0.000001));

        Mat layers = new Mat(1, 3, CvType.CV_32SC1);
        layers.put(0, 0, 2);
        layers.put(0, 1, 3);
        layers.put(0, 2, 1);
        nn.setLayerSizes(layers);

        nn.train(trainData, Ml.ROW_SAMPLE, trainLabels);

        Mat testData = new Mat(1, 2, CvType.CV_32FC1);
        testData.put(0, 0, 1);
        testData.put(0, 1, 1);

        Mat testLabels = new Mat(1, 1, CvType.CV_32FC1);
        float res = nn.predict(testData, testLabels, ANN_MLP.RAW_OUTPUT);
        Util.printMat(testLabels);

        Mat layer1 = nn.getWeights(0);
        Mat layer2 = nn.getWeights(1);
        Mat layer3 = nn.getWeights(2);
        Util.printMat(layer1);
        Util.printMat(layer2);
        Util.printMat(layer3);             
    }
}

package jm.app;
import org.opencv.core.Mat;

public class Util {

    public static void printMat(Mat mat){
        System.out.println();
        System.out.print(mat.rows() + " * " + mat.cols());
        for(int i = 0; i < mat.rows(); i++){
            System.out.println();
            for(int j = 0; j < mat.cols(); j++){
                System.out.print(mat.get(i, j)[0] + " ");
            }
        }
        System.out.println();
    }
}

输出是:

1 * 1
NaN 

1 * 4
2.0 -1.0 2.0 -1.0 

3 * 3
-0.417962425638773 -0.11805564491195578 0.7527567170648859 
0.40930192249590086 -0.24876980957807385 -0.2929439299929529 
0.6025307693048867 0.2936134607392147 -0.10605986687856579 

4 * 1
0.5558049015443158 
0.4766362469511742 
0.3713056187114578 
-0.24058588929784652 

所以我有两个问题: 1.为什么&#34; testLabel&#34;得到NaN值? 2.为什么&#34; layer1&#34;是1 * 4矩阵? &#34; layer1&#34;是什么?在这做什么?

0 个答案:

没有答案