Predicting MLP with single sample
I have trained MLP as shown in the code below to classify images into 4 classes. My class labels are 1,2,3,4
.This trains the model successfully but it thorws an Exception vector out of range during prediction
void train::trainANN(Mat hists, vector<int> labels)
{
int cols = hists.cols;//size of input layer must be equal to this number of cols
int rows = hists.rows;//used to determine rows in Mat of responses
Mat_<float> responses = Mat(labels).reshape(0, rows);
Ptr<TrainData> trainData = TrainData::create(hists, ROW_SAMPLE, responses);
Ptr<ANN_MLP> ann = ml::ANN_MLP::create();
vector<int> layers = { cols, 500, 1 };
ann->setLayerSizes(layers);
ann->setActivationFunction(ml::ANN_MLP::ActivationFunctions::SIGMOID_SYM, 1.0, 1.0);
ann->setTrainMethod(ANN_MLP::TrainingMethods::BACKPROP);
ann->setBackpropMomentumScale(0.1);
ann->setBackpropWeightScale(0.1);
ann->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 10000, 0.00001));
ann->train(trainData);
}
This is how I predict the model
float train::predictANN(Mat hist)//hist is a row matrix(one sample)
{
Mat results(1, 4, CV_32FC1);
float pred = ann->predict(hist, results);//This is the line that throws vector out of range exception
return pred;
}
I have tried to debug this code but have not fixed the error. Kindly help with why the prediction throws vector out of range exception. Thank you. NB:Am using different number of images per class during training. class 1 = 300 images, class 2 = 340 images etc
in the prediction, please do not pre-allocate the result Mat, but leave it empty.
(it will have as many rows, as your prediction input has, and as many cols, as the final layer in your net(1 here))
the main problem atm. is - that to predict one of 4 classes, you need to have 4 output nodes, not 1,
also, you would need a different way of setting up your train labels, like here
Thank you for the insight. So shoul I prepare my responses to look like:-
1 0 0 0
1 0 0 0
0 1 0 0
1 0 0 0
Where1
means sample belong to that respective class (classes columns rows number of training samples)yes, exactly.
I have created my responses using the code below and predicted with an empty results Matrix but still throwing exception vector subscript out of range
I did
responses.at<float>(i, (x-1)) = 1.f
because my class labels are1, 2, 3,4
and matrix indexing start at0
. Soclass 1
labels are found in column with index0
andclass 4
labels in column with index3
I have also update the train function now my outer layer has4
nodes"vector subscript out of range" <-- that comes from a std::vector, not a cv::Mat (and imho, your responses are ok.)
atm, i'm guessing, some operation on your labels goes fishy.
try to comment out code from bottom up (starting with the prediction) , and try to localize the error.
Thank you berak. I just realized I had a mistake in my code. All along I was loading a wrong model file before prediction. I have corrected this now no exception.
oook, nice to hear. ;)
Thank you. Now am doing my prediction as shown in function in question above at the line:-
float pred = ann->predict(hist, results)
. This gives me predicted labels between0
and3
. But my class labels are1, 2, 3, 4
. my question is, can I add1
to predicted labels before I check my cumulative scores? Thank youyes, i'd say so.
in the very same way, you subtracted 1 for the training (to make it 0-based) you later add 1 to the prediction (to make it 1-based again)