OpenCV中神經(jīng)網(wǎng)絡(luò)介紹與使用
點擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達(dá)
一:神經(jīng)網(wǎng)絡(luò)介紹
人工神經(jīng)網(wǎng)絡(luò)(ANN) 簡稱神經(jīng)網(wǎng)絡(luò)(NN),最早它的產(chǎn)生跟并行計算有關(guān)系,主要是學(xué)習(xí)生物神經(jīng)元互聯(lián)觸發(fā)實現(xiàn)學(xué)習(xí)、完成對輸入數(shù)據(jù)的分類與識別。最基本的單元是神經(jīng)元,有一個輸入值,一個輸出值,神經(jīng)元本身根據(jù)激活函數(shù)來說決定輸出值,最簡單例子就是感知器

上述在開始的時候通過隨機初始化生成權(quán)重,然后通過對數(shù)據(jù)X的訓(xùn)練迭代更新權(quán)重直到收斂,過程表示如下:

上述就是最簡單的單個感知器工作原理。而在實際情況下,神經(jīng)網(wǎng)絡(luò)會有多個感知器,多個層級,我們把輸入數(shù)據(jù)X的層稱為輸入層,最終輸出結(jié)果的層稱為輸出層,中間各個層級統(tǒng)統(tǒng)稱為隱藏層。一個典型的多層感知器(MLP)網(wǎng)絡(luò)如下:

這個時候我們選擇的激活函數(shù)就不能選擇簡單的二分類函數(shù),OpenCV中支持的激活函數(shù)有三個:

上述網(wǎng)絡(luò)中的權(quán)重值是未知的,只有通過訓(xùn)練我們才可以得到這些權(quán)重值,生成可用網(wǎng)絡(luò)模型,OpenCV中支持的兩種訓(xùn)練算法分別是:
反向傳播算法
RPROP算法
二:OpenCV中創(chuàng)建神經(jīng)網(wǎng)絡(luò)
首先創(chuàng)建多層感知器的層數(shù):
Mat_<int> layerSizes(1, 3);
layerSizes(0, 0) = data.cols;
layerSizes(0, 1) = 20;
layerSizes(0, 2) = responses.cols;
上面幾行代碼是創(chuàng)建一個三層的感知器,輸入層跟數(shù)據(jù)維度有關(guān)系,隱藏層有20個神經(jīng)元、最后是輸出層,一般是類別表示。
Ptr<ANN_MLP> network = ANN_MLP::create();
network->setLayerSizes(layerSizes);
network->setActivationFunction(ANN_MLP::SIGMOID_SYM, 0.1, 0.1);
network->setTrainMethod(ANN_MLP::BACKPROP, 0.1, 0.1);
上述代碼是創(chuàng)建神經(jīng)網(wǎng)絡(luò),設(shè)置層數(shù)、激活函數(shù)、訓(xùn)練方法等參數(shù)。
Ptr<TrainData> trainData = TrainData::create(data, ROW_SAMPLE, responses);
network->train(trainData);
上述代碼是創(chuàng)建訓(xùn)練數(shù)據(jù),執(zhí)行網(wǎng)絡(luò)訓(xùn)練
OpenCV3.4中的sample的代碼演示如下:
#include<opencv2/ml/ml.hpp>
usingnamespace std;
usingnamespace cv;
usingnamespace cv::ml;
int main()
{
//create random training data
Mat_<float> data(100, 100);
randn(data, Mat::zeros(1, 1, data.type()), Mat::ones(1, 1, data.type()));
//half of the samples for each class
Mat_<float> responses(data.rows, 2);
for(int i = 0; i<data.rows; ++i)
{
if(i < data.rows / 2)
{
responses(i, 0) = 1;
responses(i, 1) = 0;
}
else
{
responses(i, 0) = 0;
responses(i, 1) = 1;
}
}
/*
//example code for just a single response (regression)
Mat_<float> responses(data.rows, 1);
for (int i=0; i<responses.rows; ++i)
responses(i, 0) = i < responses.rows / 2 ? 0 : 1;
*/
//create the neural network
Mat_<int> layerSizes(1, 3);
layerSizes(0, 0) = data.cols;
layerSizes(0, 1) = 20;
layerSizes(0, 2) = responses.cols;
Ptr<ANN_MLP> network = ANN_MLP::create();
network->setLayerSizes(layerSizes);
network->setActivationFunction(ANN_MLP::SIGMOID_SYM, 0.1, 0.1);
network->setTrainMethod(ANN_MLP::BACKPROP, 0.1, 0.1);
Ptr<TrainData> trainData = TrainData::create(data, ROW_SAMPLE, responses);
network->train(trainData);
if(network->isTrained())
{
printf("Predict one-vector:\n");
Mat result;
network->predict(Mat::ones(1, data.cols, data.type()), result);
cout << result << endl;
printf("Predict training data:\n");
for(int i = 0; i<data.rows; ++i)
{
network->predict(data.row(i), result);
cout << result << endl;
}
}
return0;
}
四:基于神經(jīng)網(wǎng)絡(luò)的實現(xiàn)mnist數(shù)據(jù)集訓(xùn)練
Mat train_images = readImages(0);
normalize(train_images, train_images, -1.0, 1.0, NORM_MINMAX, -1);
Mat train_labels = readLabels(0);
printf("\n read mnist train dataset successfully...\n");
Mat response = Mat::zeros(Size(10, train_labels.rows), CV_32FC1);
for(int i = 0; i < train_labels.rows; i++) {
int digit = train_labels.at<int>(i, 0);
response.at<float>(i, digit) = 1;
}
//create the neural network
Mat_<int> layerSizes(1, 3);
layerSizes(0, 0) = train_images.cols;
layerSizes(0, 1) = 100;
layerSizes(0, 2) = 10;
Ptr<ANN_MLP> network = ANN_MLP::create();
network->setLayerSizes(layerSizes);
network->setActivationFunction(ANN_MLP::SIGMOID_SYM, 0.1, 0.1);
network->setTrainMethod(ANN_MLP::BACKPROP, 0.1, 0.1);
network->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 1000, 1e-6));
Ptr<TrainData> trainData = TrainData::create(train_images, ROW_SAMPLE, response);
printf("start network trainning...\n");
network->train(trainData);
if(network->isTrained())
{
printf("ready to save network model data...\n");
network->save("D:/vcprojects/images/mnist/ann_knowledge.yml");
}
test_ann_minist();
waitKey(0);
return0;
好消息!
小白學(xué)視覺知識星球
開始面向外開放啦??????
下載1:OpenCV-Contrib擴展模塊中文版教程 在「小白學(xué)視覺」公眾號后臺回復(fù):擴展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。 下載2:Python視覺實戰(zhàn)項目52講 在「小白學(xué)視覺」公眾號后臺回復(fù):Python視覺實戰(zhàn)項目,即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學(xué)校計算機視覺。 下載3:OpenCV實戰(zhàn)項目20講 在「小白學(xué)視覺」公眾號后臺回復(fù):OpenCV實戰(zhàn)項目20講,即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學(xué)習(xí)進階。 交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~

