【caffe】使用自己的图像数据训练lenet并用opencv进行预测
前面已經介紹了使用使用mnist數據集進行訓練lenet,并使用opencv加在caffemodel進行預測。更進一步也是最終的目的,還是要學會使用自己的數據集訓練caffemodel并進行預測。這里先以訓練lenet為例進行說明。
1、數據格式的轉換(images to lmdb)
通過前面幾篇介紹,我們已經知道,可直接用于caffe訓練的數據格式有lmdb和leveldb兩種,但lmdb的效率更高,因此這里需要先將原始圖像數據轉換為lmdb。
1.1 在工作目錄細新建一個文件夾,這里命名為images_to_lmdb,圖像格式的轉換將在這個文件夾下進行。將分好類的訓練數據(這里包括前景(車輛)和背景數據,二者合適的比例為1:3,一部分用于訓練,一部分測試)也拷貝到這個文件夾下,分別創建train.txt和test.txt兩個文本文件,指定源圖像的路徑(如果不是剪切好的圖像,需要指定目標所在的區域)和類別(這里前景設為0, 背景設為1),如下圖所示。
1.2 在當前目錄下新建兩個文本文件,分別重命名為images_to_train_lmdb.bat 和?images_to_test_lmdb.bat.分別輸入以下內容(注意路徑輸入正確):
D:\Libraries\caffe\msvc2013_64\bin\convert_imageset.exe --shuffle --gray --resize_width=28 --resize_height=28 images\ train.txt train_lmdb -backend=lmdb pauseD:\Libraries\caffe\msvc2013_64\bin\convert_imageset.exe --shuffle --gray --resize_width=28 --resize_height=28 images\ test.txt test_lmdb -backend=lmdb pause
1.3 雙擊images_to_train_lmdb.bat執行,可以得到訓練數據,保存在文件夾train_lmdb中。執行過程如下:
同樣,雙擊images_to_test_lmdb.bat可得到訓練數據。
2、計算均值
在當前文件夾下新建文本文件,并命名為computer_image_mean.bat,并輸入如下內容:
D:\Libraries\caffe\msvc2013_64\bin\compute_image_mean.exe train_lmdb mean.binaryproto --backend=lmdb pause
保存,雙擊執行,得到文件mean.binaryproto。
至此,訓練數據準備完畢,下面進行訓練。
3、設置訓練參數
3.1 在工程目錄下新建文件夾,并命名為glnet_train_test,訓練工作將在這個文件夾下進行,將上兩步得到的訓練數據,即兩個文件夾train_lmdb和test_lmdb,以文件mean.binaryproto拷貝到當前文件夾下。
3.2 新建兩個文本文件,分別命名為lenet_solver.prototxt和lenet_train_test.prototxt。
向lenet_solver.prototxt輸入如下內容,并保存。
# The train/test net protocol buffer definition net: "lenet_train_test.prototxt" # test_iter specifies how many forward passes the test should carry out. # In the case of MNIST, we have test batch size 100 and 100 test iterations, # covering the full 10,000 testing images. test_iter: 100 # Carry out testing every 500 training iterations. test_interval: 500 # The base learning rate, momentum and the weight decay of the network. base_lr: 0.01 momentum: 0.9 weight_decay: 0.0005 # The learning rate policy lr_policy: "inv" gamma: 0.0001 power: 0.75 # Display every 100 iterations display: 100 # The maximum number of iterations max_iter: 10000 # snapshot intermediate results snapshot: 5000 snapshot_prefix: "lenet" # solver mode: CPU or GPU solver_mode: GPU
向lenet_train_test.prototxt輸入如下內容,并保存
name: "LeNet" layer {name: "myNet"type: "Data"top: "data"top: "label"include {phase: TRAIN}transform_param {#mean_file:"mean.binaryproto"scale: 0.00390625}data_param {source: "train_lmdb"batch_size: 64backend: LMDB} } layer {name: "myNet"type: "Data"top: "data"top: "label"include {phase: TEST}transform_param {scale: 0.00390625#mean_file:"mean.binaryproto"}data_param {source: "test_lmdb"batch_size: 100backend: LMDB} } layer {name: "conv1"type: "Convolution"bottom: "data"top: "conv1"param {lr_mult: 1}param {lr_mult: 2}convolution_param {num_output: 20kernel_size: 5stride: 1weight_filler {type: "xavier"}bias_filler {type: "constant"}} } layer {name: "pool1"type: "Pooling"bottom: "conv1"top: "pool1"pooling_param {pool: MAXkernel_size: 2stride: 2} } layer {name: "conv2"type: "Convolution"bottom: "pool1"top: "conv2"param {lr_mult: 1}param {lr_mult: 2}convolution_param {num_output: 50kernel_size: 5stride: 1weight_filler {type: "xavier"}bias_filler {type: "constant"}} } layer {name: "pool2"type: "Pooling"bottom: "conv2"top: "pool2"pooling_param {pool: MAXkernel_size: 2stride: 2} } layer {name: "ip1"type: "InnerProduct"bottom: "pool2"top: "ip1"param {lr_mult: 1}param {lr_mult: 2}inner_product_param {num_output: 500weight_filler {type: "xavier"}bias_filler {type: "constant"}} } layer {name: "relu1"type: "ReLU"bottom: "ip1"top: "ip1" } layer {name: "ip2"type: "InnerProduct"bottom: "ip1"top: "ip2"param {lr_mult: 1}param {lr_mult: 2}inner_product_param {num_output: 2 ####根據訓練的目標種類進行設定,這里設置為2weight_filler {type: "xavier"}bias_filler {type: "constant"}} } layer {name: "accuracy"type: "Accuracy"bottom: "ip2"bottom: "label"top: "accuracy"include {phase: TEST} } layer {name: "loss"type: "SoftmaxWithLoss"bottom: "ip2"bottom: "label"top: "loss" }
參數設置完畢,下面進行訓練和測試。
4、訓練和測試
4.1 在當前文件夾下新建文本文件,命名為train.bat,輸入如下內容,并保存。
D:\Libraries\caffe\msvc2013_64\bin\caffe.exe train --solver=lenet_solver.prototxt pause
雙擊執行,過程如下:
最終得到如下訓練模型:
4.2 下面進行測試,新建文本文件并命名為test.bat,并輸入如下內容并保存。
D:\Libraries\caffe\msvc2013_64\bin\caffe.exe test --model lenet_train_test.prototxt -weights=lenet_iter_10000.caffemodel pause
雙擊執行,測試結果如下:
5、使用opencv加在caffemodel
5.1上面已經得到了caffemodel,在使用opencv進行預測前,需要先新建一個文本文件并命名為lenet.prototxt,輸入如下內容,并保存。
name: "LeNet" input: "data" input_dim: 64 #訓練的bacth_size input_dim: 1 #通道數 input_dim: 28 #長 input_dim: 28 #寬 layer {name: "conv1"type: "Convolution"bottom: "data"top: "conv1"param {lr_mult: 1}param {lr_mult: 2}convolution_param {num_output: 20kernel_size: 5stride: 1weight_filler {type: "xavier"}bias_filler {type: "constant"}} } layer {name: "pool1"type: "Pooling"bottom: "conv1"top: "pool1"pooling_param {pool: MAXkernel_size: 2stride: 2} } layer {name: "conv2"type: "Convolution"bottom: "pool1"top: "conv2"param {lr_mult: 1}param {lr_mult: 2}convolution_param {num_output: 50kernel_size: 5stride: 1weight_filler {type: "xavier"}bias_filler {type: "constant"}} } layer {name: "pool2"type: "Pooling"bottom: "conv2"top: "pool2"pooling_param {pool: MAXkernel_size: 2stride: 2} } layer {name: "ip1"type: "InnerProduct"bottom: "pool2"top: "ip1"param {lr_mult: 1}param {lr_mult: 2}inner_product_param {num_output: 500weight_filler {type: "xavier"}bias_filler {type: "constant"}} } layer {name: "relu1"type: "ReLU"bottom: "ip1"top: "ip1" } layer {name: "ip2"type: "InnerProduct"bottom: "ip1"top: "ip2"param {lr_mult: 1}param {lr_mult: 2}inner_product_param {num_output: 2 #和lenet_train_test.prototxt中保持一致。weight_filler {type: "xavier"}bias_filler {type: "constant"}} } layer {name: "prob"type: "Softmax"bottom: "ip2"top: "prob" }
5.2 使用opencv加在模型進行預測(具體參考 OpenCV Load caffe model)
這里直接附上代碼:
#include <opencv2/dnn.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp> #include <fstream> #include <iostream> #include <cstdlib> /* Find best class for the blob (i. e. class with maximal probability) */ void getMaxClass(cv::dnn::Blob &probBlob, int *classId, double *classProb) {cv::Mat probMat = probBlob.matRefConst().reshape(1, 1); //reshape the blob to 1x1000 matrix cv::Point classNumber;cv::minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);*classId = classNumber.x; }std::vector<cv::String> readClassNames(const char *filename = "label.txt") {std::vector<cv::String> classNames;std::ifstream fp(filename);if (!fp.is_open()){std::cerr << "File with classes labels not found: " << filename << std::endl;exit(-1);}std::string name;while (!fp.eof()){std::getline(fp, name);if (name.length())classNames.push_back(name.substr(name.find(' ') + 1));}fp.close();return classNames; }int main(int argc, char **argv) {void cv::dnn::initModule();cv::String modelTxt = "lenet.prototxt";cv::String modelBin = "lenet_iter_10000.caffemodel";cv::String imageFile = "0001.png";cv::dnn::Net net = cv::dnn::readNetFromCaffe(modelTxt, modelBin);if (net.empty()){std::cerr << "Can't load network by using the following files: " << std::endl;std::cerr << "prototxt: " << modelTxt << std::endl;std::cerr << "caffemodel: " << modelBin << std::endl;exit(-1);}//! [Prepare blob] cv::Mat img = cv::imread(imageFile, cv::IMREAD_GRAYSCALE);if (img.empty()){std::cerr << "Can't read image from the file: " << imageFile << std::endl;exit(-1);}cv::resize(img, img, cv::Size(28, 28));//cv::dnn::Blob inputBlob = cv::dnn::Blob(img); //Convert Mat to dnn::Blob image batch cv::dnn::Blob inputBlob = cv::dnn::Blob::fromImages(img);//! [Prepare blob] //! [Set input blob] net.setBlob(".data", inputBlob); //set the network input //! [Set input blob] //! [Make forward pass] net.forward(); //compute output //! [Make forward pass] //! [Gather output] cv::dnn::Blob prob = net.getBlob("prob"); //gather output of "prob" layer int classId;double classProb;getMaxClass(prob, &classId, &classProb);//find the best class //! [Gather output] //! [Print results] std::vector<cv::String> classNames = readClassNames();std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;std::cout << "Probability: " << classProb * 100 << "%" << std::endl;//! [Print results] return 0; } //main
測試結果如下:
DONE!
2017.08.01
總結
以上是生活随笔為你收集整理的【caffe】使用自己的图像数据训练lenet并用opencv进行预测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【caffe】OpenCV Load c
- 下一篇: 【深度学习】基于深度学习的目标检测研究进