由于项目需要,最近一段在学习神经网络的相关知识。项目用到了OpenCV,所以打算用里面的函数实现神经网络。
关于OpenCV中神经网络的实现,资料很少,《学习OpenCV》中更是仅有一小段描述。今天找到了一个小例子,通过查文档基本上弄懂了如何搭起来神经网络的结构。
#include "stdafx.h" #include "cv.h" #include "ml.h" // The neural network CvANN_MLP machineBrain; // Read the training data and train the network. void trainMachine() { int i; //The number of training samples. int train_sample_count; //The training data matrix. //Note that we are limiting the number of training data samples to 1000 here. //The data sample consists of two inputs and an output. That's why 3. float td[1000][3]; //Read the training file /* A sample file contents(say we are training the network for generating the mean given two numbers) would be: 5 12 16 14 10 5 7.5 8 10 9 5 4 4.5 12 6 9 */ FILE *fin; fin = fopen("train.txt", "r"); //Get the number of samples. fscanf(fin, "%d", &train_sample_count); printf("Found training file with %d samples...\n", train_sample_count); //Create the matrices //Input data samples. Matrix of order (train_sample_count x 2) CvMat* trainData = cvCreateMat(train_sample_count, 2, CV_32FC1); //Output data samples. Matrix of order (train_sample_count x 1) CvMat* trainClasses = cvCreateMat(train_sample_count, 1, CV_32FC1); //The weight of each training data sample. We'll later set all to equal weights. CvMat* sampleWts = cvCreateMat(train_sample_count, 1, CV_32FC1); //The matrix representation of our ANN. We'll have four layers. CvMat* neuralLayers = cvCreateMat(4, 1, CV_32SC1); CvMat trainData1, trainClasses1, neuralLayers1, sampleWts1; cvGetRows(trainData, &trainData1, 0, train_sample_count); cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count); cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count); cvGetRows(sampleWts, &sampleWts1, 0, train_sample_count); cvGetRows(neuralLayers, &neuralLayers1, 0, 4); //Setting the number of neurons on each layer of the ANN /* We have in Layer 1: 2 neurons (2 inputs) Layer 2: 3 neurons (hidden layer) Layer 3: 3 neurons (hidden layer) Layer 4: 1 neurons (1 output) */ cvSet1D(&neuralLayers1, 0, cvScalar(2)); cvSet1D(&neuralLayers1, 1, cvScalar(3)); cvSet1D(&neuralLayers1, 2, cvScalar(3)); cvSet1D(&neuralLayers1, 3, cvScalar(1)); //Read and populate the samples. for (i=0;i<train_sample_count;i++) fscanf(fin,"%f %f %f",&td[i][0],&td[i][1],&td[i][2]); fclose(fin); //Assemble the ML training data. for (i=0; i<train_sample_count; i++) { //Input 1 cvSetReal2D(&trainData1, i, 0, td[i][0]); //Input 2 cvSetReal2D(&trainData1, i, 1, td[i][1]); //Output cvSet1D(&trainClasses1, i, cvScalar(td[i][2])); //Weight (setting everything to 1) cvSet1D(&sampleWts1, i, cvScalar(1)); } //Create our ANN. machineBrain.create(neuralLayers);//sigmoid 0 0(激活函数的两个参数) //Train it with our data. machineBrain.train( trainData,//输入 trainClasses,//输出 sampleWts,//输入项的权值 0, CvANN_MLP_TrainParams( cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,///类型 CV_TERMCRIT_ITER 和CV_TERMCRIT_EPS二值之一,或者二者的组合 10000000,//最大迭代次数 0.00000001//结果的精确性 两次迭代间权值变化量 ), CvANN_MLP_TrainParams::BACKPROP,//BP算法 0.01,//几个可显式调整的参数 0.05 ) ); } // Predict the output with the trained ANN given the two inputs. void Predict(float data1, float data2) { float _sample[2]; CvMat sample = cvMat(1, 2, CV_32FC1, _sample); float _predout[1]; CvMat predout = cvMat(1, 1, CV_32FC1, _predout); sample.data.fl[0] = data1; sample.data.fl[1] = data2; machineBrain.predict(&sample, &predout); printf("%f \n",predout.data.fl[0]); } int _tmain(int argc, _TCHAR* argv[]) { int wait; // Train the neural network with the samples trainMachine(); // Now try predicting some values with the trained network Predict(12.0,16.0);// 14 Predict(10.0,5.0);// 7.5 Predict(8.0,10.0);// 9 Predict(5.0,4.0);// 4.5 Predict(12.0,6.0);// 9 //I'll wait for an integer. :) scanf("%d",&wait); return 0; } |
一点愚见:
其实搭起来结构不是难事,难的是输入输出的确定。如果神经网络的学习效果不好,首先调整参数,实在不行再调整输入输出。如果还不行,那就换结构。而OpenCV里只实现了BACKPROP和RPROP……闹不好还得找别的类库。
It’s really a tough thing.
帮助很大!感谢!!
谢谢您的分享,刚刚接触OPenCV的神经网络方面的知识,觉得自己实现起来还是挺有难度,您的分享对我的帮助很大,期待更多的指导
您好,初学者,您的测试数据还在不,我这读不进来!