我一直在使用OpenCV一段時間。我決定最近檢查它的機器學習的力量。所以我最終實現了一個用於人臉識別的神經網絡。總結一下我的人臉識別策略:OpenCV神經網絡Sigmoid輸出
- 從某個臉部數據庫的csv中讀取圖像。
- 將圖像逐行掃描到Mat陣列。
- 應用PCA降維。
- 使用PCA預測來訓練網絡。
使用訓練好的網絡預測測試數據。
所以一切都很好,直到預測階段。我正在使用最大響應輸出單位對臉部進行分類。所以通常OpenCV的sigmoid實現應該給出-1到1的值,這在文檔中有說明。 1是課堂的最大封閉。在準確度接近0之後,我檢查了每個測試數據的每個類的輸出響應。我驚訝的價值觀:14.53,-1.7,#IND。如果sigmoid被應用,我怎麼能得到這些值?我在哪裏做錯了?
爲了幫助您瞭解此事,併爲那些不知道如何運用主成分分析,並與NN使用它我米分享我的代碼:
閱讀CSV:
void read_csv(const string& filename, vector& images, vector& labels, char separator = ';') { std::ifstream file(filename.c_str(), ifstream::in); if (!file) { string error_message = "No valid input file was given, please check the given filename."; CV_Error(1, error_message); } string line, path, classlabel; while (getline(file, line)) { stringstream liness(line); getline(liness, path, separator); getline(liness, classlabel); if(!path.empty() && !classlabel.empty()) { Mat im = imread(path, 0); images.push_back(im); labels.push_back(atoi(classlabel.c_str())); } } }
逐行滾動圖像:
Mat rollVectortoMat(const vector<Mat> &data)
{
Mat dst(static_cast<int>(data.size()), data[0].rows*data[0].cols, CV_32FC1);
for(unsigned int i = 0; i < data.size(); i++)
{
Mat image_row = data[i].clone().reshape(1,1);
Mat row_i = dst.row(i);
image_row.convertTo(row_i,CV_32FC1, 1/255.);
}
return dst;
}
轉換標籤的載體,MAT標籤
Mat getLabels(const vector<int> &data,int classes = 20)
{
Mat labels(data.size(),classes,CV_32FC1);
for(int i = 0; i <data.size() ; i++)
{
int cls = data[i] - 1;
labels.at<float>(i,cls) = 1.0;
}
return labels;
}
主要
int main()
{
PCA pca;
vector<Mat> images_train;
vector<Mat> images_test;
vector<int> labels_train;
vector<int> labels_test;
read_csv("train1k.txt",images_train,labels_train);
read_csv("test1k.txt",images_test,labels_test);
Mat rawTrainData = rollVectortoMat(images_train);
Mat rawTestData = rollVectortoMat(images_test);
Mat trainLabels = getLabels(labels_train);
Mat testLabels = getLabels(labels_test);
int pca_size = 500;
Mat trainData(rawTrainData.rows, pca_size,rawTrainData.type());
Mat testData(rawTestData.rows,pca_size,rawTestData.type());
pca(rawTrainData,Mat(),CV_PCA_DATA_AS_ROW,pca_size);
for(int i = 0; i < rawTrainData.rows ; i++)
pca.project(rawTrainData.row(i),trainData.row(i));
for(int i = 0; i < rawTestData.rows ; i++)
pca.project(rawTestData.row(i),testData.row(i));
Mat layers = Mat(3,1,CV_32SC1);
int sz = trainData.cols ;
layers.row(0) = Scalar(sz);
layers.row(1) = Scalar(1000);
layers.row(2) = Scalar(20);
CvANN_MLP mlp;
CvANN_MLP_TrainParams params;
CvTermCriteria criteria;
criteria.max_iter = 1000;
criteria.epsilon = 0.00001f;
criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
params.train_method = CvANN_MLP_TrainParams::BACKPROP;
params.bp_dw_scale = 0.1f;
params.bp_moment_scale = 0.1f;
params.term_crit = criteria;
mlp.create(layers,CvANN_MLP::SIGMOID_SYM);
int i = mlp.train(trainData,trainLabels,Mat(),Mat(),params);
int t = 0, f = 0;
for(int i = 0; i < testData.rows ; i++)
{
Mat response(1,20,CV_32FC1);
Mat sample = testData.row(i);
mlp.predict(sample,response);
float max = -1000000000000.0f;
int cls = -1;
for(int j = 0 ; j < 20 ; j++)
{
float value = response.at<float>(0,j);
if(value > max)
{
max = value;
cls = j + 1;
}
}
if(cls == labels_test[i])
t++;
else
f++;
}
return 0;
}
注:我曾經在& T「第一個20級的我的數據集。
可以請你設置的參數通過手,即mlp.create(層,CvANN_MLP :: SIGMOID_SYM,1,1); – baci
如果它工作提交錯誤報告,因爲默認值0對alpha和beta沒有意義。 – baci
它似乎令人驚訝地將S形輸出值修正爲建議的範圍。現在,我正在使用其他參數來提高準確性。我將很快發佈我的神經網絡經驗。謝謝你的方式:) – yutasrobot