Hi,
As many of you are aware i am using an MLP to use real time image recogniton to drive a car.
my testing data and training data are used from the same set of images- meaning all test data is currently also in the training set, which is why I cannot figure out when running my testNetwork funciton, it produces a score of 0/114 correct answers, as naturally the fact that it has been trained using this data and more, it should work. I know training data should be seperate but I wanted to get it working like this first..
all 3 functions are as follows, I used @berak 's code as a good baseline to adapt it to my needs, I highly recommend taking a look at it if you are learning to use Opencv MLP abilities as it is very useful.
void readScanStore(){
cv::Mat trainingData;//mat collectionn of images to train with
cv::Mat TestData;
char const *path = "/home/pi/selfdrivingcarV1/train_data/";//needs folders of 0 1 2 3 holdig 50 pics each for representing outputs
int const numFilesDirs[]={128,217,217}; //number of photos for each direction ()LEFT =0 RIGHT =1 straight =2
char const strDirs[]={'0','1','2'}; //optional outputs " 0=go,1 right 2 left
int const numDirs = 3;//number of directions
cv::Mat TestLabels (0,0,(CV_32S));
cv::Mat trainingLabels (0,0,(CV_32S));
//same as svm??
for (int i=0;i!=numDirs; i++){//outer for loop to go through all 4 output options
int numFiles = numFilesDirs[i];//assign inner loop based on size of samples from current outerloop val
for (int j=0;j!=numFiles;j++){//loop through all files within current output value
std::cout << "direction" << strDirs[i] << "file: " << j <<".jpg" << "\n";// print current output val and files associated with that direction
std::stringstream ss;
ss << path << strDirs[i] << "/" <<"i (" << j+1 << ").jpg";//print current working image
cv::Mat img = cv::imread(ss.str(),0);
if (!img.data)
cout << "error no file found " << ss.str() << endl;
Size size(10,10);
Mat ImgCon;
resize(img,ImgCon,size);
ImgCon =ImgCon.reshape(1,1);
//assume img is continous
//reshape image to 1xtotal res
if (j%5==0){//push every 5 images to test set
TestData.push_back(ImgCon);
TestLabels.push_back(i);
}
trainingData.push_back(ImgCon); //push back image
trainingLabels.push_back(i);//assign instruction corresponding to image in label set
}
}
TestData.convertTo(TestData, CV_32F);
trainingData.convertTo(trainingData, CV_32F);//,1/255.0);//convert all images to cv32f (numeric values)
cv::FileStorage fs("TRAIN_VALUES.xml",FileStorage::WRITE);//store numeric values in xml file as training data values for each image.
fs << "TrainingData" <<trainingData;//assign each image
fs << "classes" << trainingLabels;//assign associated classes
cv::FileStorage ffs("TEST_VALUES.xml",FileStorage::WRITE);//store numeric values in xml file as training data values for each image.
ffs << "TestData" <<TestData;//assign each image
ffs << "classes" << TestLabels;//assign associated classes
printf("complete");
}
void trainNetwork() {
int nclasses = 3;
cv::FileStorage fsa;
fsa.open("TRAIN_VALUES.xml", cv::FileStorage::READ);
cv::Mat train_data;
cv::Mat train_labels;
fsa["TrainingData"] >> train_data;
fsa["classes"] >> train_labels;
int nfeatures = train_data.cols;
Ptr<ml::ANN_MLP> ann = ml::ANN_MLP::create();
Mat_<int> layers(4,1);
layers(0) = nfeatures; // input
layers(1) = nclasses * 8; // hidden
layers(2) = nclasses * 4; // hidden
layers(3) = nclasses; // output, 1 pin per class.
ann->setLayerSizes(layers);
ann->setActivationFunction(ml::ANN_MLP::SIGMOID_SYM,0,0);
ann->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 1000, 0.0001));
ann->setTrainMethod(ml::ANN_MLP::BACKPROP, 0.0001);
printf("sending data to train_test"); // setup the ann:
// ann requires "one-hot" encoding of class labels:
Mat train_classes = Mat::zeros(train_data.rows, nclasses, CV_32F);////should this be 32f ONLY???????
printf("%i\n",train_classes.rows);
//////////////////////////////////////////////////////////////////////////
for(int i=0; i<train_classes.rows; i++)
{
train_classes.at<float>(i, train_labels.at<int>(i)) = 1.f;
}
cerr << train_data.size() << " " << train_classes.size() << endl;
/////////////////////////////////////////////////////////////////////////////////////
ann->train(train_data, ml::ROW_SAMPLE, train_classes);
cv::FileStorage fs("NNPARAMS.xml",FileStorage::WRITE);//store numeric values in xml file as training data values for each image.
ann->write(fs);
}
void TestNetwork(){
cv::FileStorage fsa;
fsa.open("TEST_VALUES.xml", cv::FileStorage::READ);
cv::Mat test_data;
cv::Mat test_labels;
fsa["TestData"] >> test_data;
fsa["classes"] >> test_labels;
cout << test_data.row(1).size()<<endl;
FileStorage fs("NNPARAMS.xml",FileStorage::READ);
Ptr<ml::ANN_MLP> Neural_Net = cv::Algorithm::read<ml::ANN_MLP>(fs.root());
if (!Neural_Net->isTrained()) printf("network not trained \n");
else {
int corrcount =0;
for (int i=0; i<test_data.rows; i++){
Mat Result;
Neural_Net->predict(test_data.row(i),Result);
int truth = test_labels.at<int>(i);
cv::Point max_loc;
cv::minMaxLoc(Result,0,0,&max_loc,0);
int pred = max_loc.x;
if (pred == truth)
corrcount++;
printf("actual : %i , Expected : %i\n",pred,truth);
}printf("Test Result : %i/%i",corrcount,test_data.rows);
}
}
#endif
Any idea as to why Using this TestNetwork Function I am recieving no correct values?