Ask Your Question

RubixCube's profile - activity

2018-07-12 03:07:17 -0600 received badge  Popular Question (source)
2017-04-03 06:04:38 -0600 received badge  Enlightened (source)
2017-04-03 06:04:38 -0600 received badge  Good Answer (source)
2016-05-18 09:12:34 -0600 received badge  Scholar (source)
2016-05-18 08:58:28 -0600 commented answer Neural Network in OpenCV 3.1.0

good idea, created the PR :-)

2016-05-17 07:20:29 -0600 received badge  Nice Answer (source)
2016-05-17 07:15:59 -0600 received badge  Teacher (source)
2016-05-17 03:46:43 -0600 received badge  Self-Learner (source)
2016-05-17 01:52:47 -0600 answered a question Neural Network in OpenCV 3.1.0

As already mentioned in above comments, here is a working minimum example in case anyone is into the same problem:

#include <opencv2/ml/ml.hpp>

using namespace std;
using namespace cv;
using namespace cv::ml;

int main(int argc, char* argv[])
{
    //create random training data
    Mat_<float> data(100, 100);
    randn(data, Mat::zeros(1, 1, data.type()), Mat::ones(1, 1, data.type()));

    //half of the samples for each class
    Mat_<float> responses(data.rows, 2);
    for (int i = 0; i<data.rows; ++i)
    {
        if (i < data.rows/2)
        {
            data(i, 0) = 1;
            data(i, 1) = 0;
        }
        else
        {
            data(i, 0) = 0;
            data(i, 1) = 1;
        }
    }

    /*
    Mat_<float> responses(data.rows, 1);
    for (int i=0; i<responses.rows; ++i)
        responses(i, 0) = i < responses.rows / 2 ? 0 : 1;
    */

    //create the neural network
    Mat_<int> layerSizes(1, 3);
    layerSizes(0, 0) = data.cols;
    layerSizes(0, 1) = 20;
    layerSizes(0, 2) = responses.cols;

    Ptr<ANN_MLP> network = ANN_MLP::create();
    network->setLayerSizes(layerSizes);
    network->setActivationFunction(ANN_MLP::SIGMOID_SYM, 0.1, 0.1);
    network->setTrainMethod(ANN_MLP::BACKPROP, 0.1, 0.1);
    Ptr<TrainData> trainData = TrainData::create(data, ROW_SAMPLE, responses);

    network->train(trainData);
    if (network->isTrained())
    {
        printf("Predict one-vector:\n");
        Mat result;
        network->predict(Mat::ones(1, data.cols, data.type()), result);
        cout << result << endl;

        printf("Predict training data:\n");
        for (int i=0; i<data.rows; ++i)
        {
            network->predict(data.row(i), result);
            cout << result << endl;
        }
    }

    return 0;
}
2016-05-13 06:34:20 -0600 commented question Neural Network in OpenCV 3.1.0

Thanks for your help! Actually I found out what's the problem (or at least what seems to be a major problem): The problem is the activation function, i.e. the line

network->setActivationFunction(0, 0.1, 0.1);

where 0 is equivalent to IDENTITY. Writing a 1 there (i.e. SIGMOID_SYM) solves the problem, at least the predictions do work and return some results. I'll post some working example code here soon.

Finally I would like to fully understand your point regarding the output layer size: Using SIGMOID_SYM the predictions work with both configurations, but actually do I need the explicit 1-of-k encoding? If I use a different classifier from OpenCV using a single response vector containing the class indices works fine, does this not hold for neural nets or is there a major difference?

2016-05-13 04:48:25 -0600 commented question Neural Network in OpenCV 3.1.0

Thanks for your comment! I changed the code according to your suggestions (cf. edit of my post), training still works fine but at prediction it keeps seg-faulting. Am I doing something else wrong?

2016-05-13 03:17:36 -0600 asked a question Neural Network in OpenCV 3.1.0

Hello everyone!

I am currently trying to get OpenCV's neural network module running, unluckily so far with less success. Initialization and training works fine (at least as far as I can verify it) but as soon as I try to do a prediction, I'm receiving segmentation fault errors... I tried training / predicting on both Windows 8 as well as Ubuntu 16.04 on a custom Linux build as well as on a third-party Windows build respectively, as soon as I try a prediction, the same error occurs.

I also prepared some usable example code. Of course I know that training on randomly generated data makes not too much sense in practice, I only wanted to keep things simple for a minimum running example:

#include <opencv2/ml/ml.hpp>

using namespace cv;
using namespace cv::ml;

int main(int argc, char *argv[])
{
    //create random training data
    Mat_<float> data(100, 100);
    randn(data, Mat::zeros(1, 1, data.type()), Mat::ones(1, 1, data.type()));

    //half of the samples for each class
    Mat_<float> responses(data.rows, 1);
    for (int i=0; i<responses.rows; ++i)
        responses(i, 0) = i < responses.rows / 2 ? 0 : 1;

    //create the neural network
    Mat_<int> layerSizes(1, 3);
    layerSizes(0, 0) = data.cols;
    layerSizes(0, 1) = 20;
    layerSizes(0, 2) = 1;

    Ptr<ANN_MLP> networkPtr = ANN_MLP::create();
    ANN_MLP* network = networkPtr.get();
    network->setLayerSizes(layerSizes);
    network->setActivationFunction(0, 0.1, 0.1);
    network->setTrainMethod(0, 0.1, 0.1);

    /*
    //test to change variable type flags -> problem stays the same
    Mat_<int> varType = Mat(1, data.cols+1, CV_8U);
    for (int i = 0; i<data.cols; ++i)
        varType(0, i) = VAR_ORDERED;
    varType(0, varType.cols-1) = VAR_CATEGORICAL;
    //varType(0, varType.cols-1) = VAR_ORDERED;
    Ptr<TrainData> trainData = TrainData::create(data, ROW_SAMPLE, responses, noArray(), noArray(), noArray(), varType);
    */

    Ptr<TrainData> trainData = TrainData::create(data, ROW_SAMPLE, responses);
    network->train(trainData);

    if (network->isTrained())
    {
        printf("Predict:\n");
        network->predict(Mat::ones(1, data.cols, data.type())); //SEGMENTATION FAULT
        printf("Prediction done!\n");
    }

    return 0;
}

Does anyone got the Neural Network running in OpenCV 3.1.0? For me either I'm doing something wrong (in case, please let me know) or this is a bug in OpenCV... I would appreciate any comments :-)

edit - updated source code:

#include <opencv2/ml/ml.hpp>

using namespace cv;
using namespace cv::ml;

int main(int argc, char *argv[])
{
    //create random training data
    Mat_<float> data(100, 100);
    randn(data, Mat::zeros(1, 1, data.type()), Mat::ones(1, 1, data.type()));

    //half of the samples for each class
    Mat_<float> responses(data.rows, 2);
    for (int i = 0; i<data.rows; ++i)
    {
        if (i < data.rows/2)
        {
            data(i, 0) = 1;
            data(i, 1) = 0;
        }
        else
        {
            data(i, 0) = 0;
            data(i, 1) = 1;
        }
    }

    //Mat_<float> responses(data.rows, 1);
    //for (int i=0; i<responses.rows; ++i)
    //    responses(i, 0) = i < responses.rows / 2 ? 0 : 1;

    //create the neural network
    Mat_<int> layerSizes(1, 3);
    layerSizes(0, 0) = data.cols;
    layerSizes(0, 1) = 20;
    layerSizes(0 ...
(more)
2013-08-10 08:45:41 -0600 received badge  Nice Question (source)
2013-08-09 09:03:06 -0600 received badge  Student (source)
2013-08-09 08:58:55 -0600 asked a question individual votes from Random Forests

Hello everyone,

I am using OpenCV for a machine learning classification task where I am using random forests at the moment. For analysing the predictive quality I would like to look not only on the classifier's bare class output.

Looking one steep deeper into the decision tree/random forest algorithm, each leaf node votes for the class with the maximum fraction of all train data samples reaching that specific leaf. Consequently, for each leaf l and for each class k there is a score s(l,k) = #samples from class k in leaf l. For my analysis I want to compute this score s(l,k) for all leafs l and all classes k. (That is, because a prediction of a leaf where all classes have more or less the same fraction of samples voting for them is expected to be less reliable than a prediction where all samples in a leaf voting for the same class).

Computing this number s(l,k) is trivial in theory - while growing the tree don't just store the bare class prediction based on the majority voting but instead the number of votes for each class. But unluckily in practice this turns out to be a little harder.

Since I don't want to modify the OpenCV source code I tried to find another solution based on the CvRTrees::get_tree() method: after growing the forest, run with the training set through each tree (starting at the root) and accumulate in every leaf the number of votes for each class. But going this way I need the training set for each tree of the forest. The problem here is now, that this training set does not coincide with the training set of my random forest because the training set for each tree instead is computed by takeing N = |training set| random samples with replacement from the forest's training set.

So finally to go this way I need the individual training sets from each of the forest's trees. Re-computing is not possible (due to randomisation) and so I have to extract them from the growing of the trees. To takle this problem I tried to use the CvRTrees::get_tree() method, returning a CvForestTree which is a subclass of CvDTree, i.e. with CvDTree::get_data() I have access to the tree's specific train data - or at least I expected to have. I did the following:

CvRTrees* randomForest = new CvRTrees();
randomForest->train(...);

for (int t=0; t<100; ++t) //ntrees = 100
{
    CvForestTree* tree = randomForest->get_tree(t);
    const CvMat* currentTrainData = tree->get_data()->train_data;
    printf("%d \n", currentTrainData->rows);
}

At least in theory this should give the train data of each tree, but unluckily each time currentTrainData equals the whole training set of the random forest.

Does anyone know what I am doing wrong or how to get the scores s(l,k) / the real train data of each tree?

I tried to find out as much as possible with the OpenCV reference manual (http ... (more)