OpenCV neural Network training Error
I have been using the tutorial on this site titled "how to start implementing a neural network in C"( cant post link yet due to rep) and others: to create a neural network to process images of a track I have made for a car to be able to drive round it autonomously.
The process of reading in the training images (converted as required) and their respective classes works perfectly and stores to the data file Values.xml with the below code:
void readScanStore(){
cv::Mat trainingData;//mat collectionn of images to train with
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[]={110,95,63}; //number of photos for each direction (fwd l r)
char const strDirs[]={'0','1','2'}; //optional outputs " 0=go,1 right 2 left
int const numDirs = 3;//number of directions
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] << "/" << j << ".jpg";//print current working image
cv::Mat img = cv::imread(ss.str(),0);
if (!img.data)
cout << "error no file found " << ss << endl;
Size size(10,10);
Mat ImgCon;
resize(img,ImgCon,size);
ImgCon.reshape(1,1);
//assume img is continous
//reshape image to 1xtotal res
trainingData.push_back(ImgCon); //push back image
trainingLabels.push_back(i);//assign instruction corresponding to image in label set
}
}
trainingData.convertTo(trainingData, CV_32F);//,1/255.0);//convert all images to cv32f (numeric values)
cv::FileStorage fs("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
printf("complete");
}
which is then proceeded by the training procedure which loads the values of the images and uses them as training data to train the NN:
void trainNetwork(){
int nclasses = 3;
cv::FileStorage fs;
fs.open("VALUES.xml", cv::FileStorage::READ);
cv::Mat trainData;
cv::Mat classes;
fs["TrainingData"] >> trainData;
fs["classes"] >> classes;
Mat confusion(nclasses,nclasses,CV_32S, Scalar(0)); // will hold our test results
train_test(nclasses, trainData, classes, confusion);
}
which calls the following:
void train_test(int nclasses, const Mat &train_data, const Mat &train_labels, Mat &confusion) {
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, 300, 0.0001));
ann->setTrainMethod(ml::ANN_MLP::BACKPROP, 0.0001);
printf("sending data to ...
N.B my output for the
cerr << train_data.size() << " " << train_classes.size() << endl;
is [10x2680] [3 x 2680] which seems it may be "the wrong way round"