Caffeソース解読(八):訓練されたモデルを使用する
11917 ワード
caffemodelの使用方法を説明する前に、平均ファイルについて説明します.大規模なデータベースでは、平均ファイルを減算してトレーニングとテストを行う必要があり、速度と精度が向上します.Caffeは、平均ファイルを生成するための専用ツールを提供します.
次に、DataLayerレイヤの前処理で平均ファイルを指定します.
訓練したモデルの使い方を説明します
ステップ4
つまりトップがdataである層を削除し、Lenet_のようにtrain_test.prototxtの最初の2つのレイヤ.
道理は簡単で、私たちはもう訓練しないで、訓練データを読む必要はありません.これらの層は訓練データを読むために使われているので、削除します.
つまりbottomを取り除くのはlabelの層で、以下のようにします.
これらのレイヤはlossおよびテストの正確性を計算するために使用され、未知のlabelのデータを読み込むため、これらのレイヤも切り捨てられます.
入力を切り捨てた後、元の基礎の上で入力を再確立し、
この4つのdimは、私たちが入力した画像が1枚の単一チャネルの28であることを示しています.×28サイズの画像.
元の出力に基づいて、このようなレイヤを追加します.
注意topはnameと一致するようにします.
Opencvのライブラリを用いて、1、deploy、caffemodelと入力画像2を読み込み、caffemodelを利用してニューラルネットワークNet 3を生成し、画像をこのネットワーク4に入力し、ニューラルネットワークをforward操作して出力結果5を得、出力結果から当該画像が最終的にどのクラスに属するか、およびこのクラスに属する確率を算出するプログラムを作成する.
Opencvライブラリを使用して、次のコマンドでコンパイルします.
compute_image_mean [train_lmdb] [mean.binaryproto]
次に、DataLayerレイヤの前処理で平均ファイルを指定します.
transform_param {
scale: 0.00390625
mean_file_size: “examples/cifar10/mean.binaryproto" #
mirror: 1
crop_size: 227
}
訓練したモデルの使い方を説明します
deployファイルを書き換える
ステップ4
ステップ1:データ層(Data Layer)と接続データ層のLayersを取り除く
つまりトップがdataである層を削除し、Lenet_のようにtrain_test.prototxtの最初の2つのレイヤ.
name: "LeNet"
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TRAIN
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_train_lmdb"
batch_size: 64
backend: LMDB
}
}
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
scale: 0.00390625
}
data_param {
source: "examples/mnist/mnist_test_lmdb"
batch_size: 100
backend: LMDB
}
}
道理は簡単で、私たちはもう訓練しないで、訓練データを読む必要はありません.これらの層は訓練データを読むために使われているので、削除します.
ステップ2:出力層と出力層を接続するLayersを取り除く
つまりbottomを取り除くのはlabelの層で、以下のようにします.
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"
}
これらのレイヤはlossおよびテストの正確性を計算するために使用され、未知のlabelのデータを読み込むため、これらのレイヤも切り捨てられます.
ステップ3:入力の再確立
入力を切り捨てた後、元の基礎の上で入力を再確立し、
name: "LeNet"
input: "data"
input_shape {
dim: 1 # batchsize
dim: 1 # number of colour channels - rgb
dim: 28 # width
dim: 28 # height
}
この4つのdimは、私たちが入力した画像が1枚の単一チャネルの28であることを示しています.×28サイズの画像.
ステップ4:出力の再確立
元の出力に基づいて、このようなレイヤを追加します.
layer {
name: "prob"
type: "Softmax"
bottom: "ip2"
top: "prob"
}
注意topはnameと一致するようにします.
caffemodelの使用プログラムの作成
Opencvのライブラリを用いて、1、deploy、caffemodelと入力画像2を読み込み、caffemodelを利用してニューラルネットワークNet 3を生成し、画像をこのネットワーク4に入力し、ニューラルネットワークをforward操作して出力結果5を得、出力結果から当該画像が最終的にどのクラスに属するか、およびこのクラスに属する確率を算出するプログラムを作成する.
#include "opencv2/dnn.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
using namespace cv::dnn;
#include
#include
#include
using namespace std;
/* Find best class for the blob (i. e. class with maximal probability) */
void getMaxClass(dnn::Blob &probBlob, int *classId, double *classProb)
{
Mat probMat = probBlob.matRefConst().reshape(1, 1); //reshape the blob to 1x1000 matrix
Point classNumber;
minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
*classId = classNumber.x;
}
int main(int argc,char* argv[]){
String modelTxt = "mnist_deploy.prototxt";
String modelBin = "lenet_iter_10000.caffemodel";
String imageFile = (argc > 1) ? argv[1] : "5.jpg";
//! [Create the importer of Caffe model] caffe
Ptr<:importer> importer;
importer = dnn::createCaffeImporter(modelTxt, modelBin);
if (!importer){
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);
}
//! [Initialize network]
Net net;
importer->populateNet(net);
importer.release();
//! [Prepare blob] blob
Mat img = imread(imageFile,0); //[] "0" for 1 channel, Mnist accepts 1 channel
if (img.empty())
{
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
exit(-1);
}
resize(img, img, Size(28, 28)); //[]Mnist accepts only 28x28 RGB-images
dnn::Blob inputBlob = cv::dnn::Blob(img); //Convert Mat to dnn::Blob batch of images
//! [Set input blob] blob
net.setBlob(".data", inputBlob); //set the network input
//! [Make forward pass]
net.forward(); //compute output
//! [Gather output]
dnn::Blob prob = net.getBlob("prob"); //[] gather output of "prob" layer
int classId;
double classProb;
getMaxClass(prob, &classId, &classProb);//find the best class
//! [Print results]
std::cout << "Best class: #" << classId << "'" << std::endl;
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
return 0;
}
Opencvライブラリを使用して、次のコマンドでコンパイルします.
g++ -o test_mnist test_mnist.cpp -lopencv_dnn -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lstdc++ -lopencv_core