いよいよ最終回の「classification.exe」の中の処理の解説です。
WindowsネイティブでCaffeを使った認識アプリを作る場合は、これを知っておくのが一番手っ取り早いです。
では始めます。
準備
モデルの準備
認識処理を行う前に、まずモデルの準備をします。
引数で指定した、認識用のモデルと、学習済みのモデルを読み込みます。
/* Load the network. */
net_.reset(new Net<float>(model_file, TEST));
net_->CopyTrainedLayersFrom(trained_file);
「net_」は
shared_ptr<Net<float>> net_;
と宣言されている、ネットワーク全体を表すクラスのオブジェクトとなります。
入力画像の準備
次に、ネットワークから入力画像設定のため、ブロブを取り出します。
そして、そのブロブから入力データの情報を取得します。
Blob<float>* input_layer = net_->input_blobs()[0];
num_channels_ = input_layer->channels();
input_geometry_ = cv::Size(input_layer->width(), input_layer->height());
平均画像の設定
次に、平均画像ファイルをネットワークに設定します。
平均画像ファイルはバイナリのProtocol Buffersになっていますので、Caffeで利用できる形式に変換します。
変換処理はOpenCVで書かれているので、順を追ってみていけばわかりやすいと思います。
(ここではコードは省略)
ラベルの読み込み
これは「必要であれば」の処理になりますが、このサンプルでは認識した結果を、分類番号ではなく分類名で表示するため、分類名の一覧を読み込んでいます。
出力分類番号の準備
最後に評価結果を取得するためのブロブを、ネットワークから取得します。
(入力と対になるイメージです)
Blob<float>* output_layer = net_->output_blobs()[0];
認識
対象画像の読み込み
認識させたい画像を読み込みます。
OpenCVのimread()で読み込んでいますので、多くの画像フォーマットに対応していることになります。
画像の認識
ネットワークに認識させたい画像を設定します。
実際には、まず入力用のブロブを取得し、全レイヤーで使用するチャンネル数、画像サイズを調整します。
Blob<float>* input_layer = net_->input_blobs()[0];
input_layer->Reshape(1, num_channels_, input_geometry_.height, input_geometry_.width);
/* Forward dimension change to all layers. */
net_->Reshape();
次に、入力画像を読み込むためのバッファを用意し、そこに入力画像を設定します。
設定する際に、フォーマット変換やリサイズなどの処理を行います。
この処理もOpenCVで書かれているのでわかりやすいです。
その後、順方向に処理を行います。
net_->Forward();
最後に、認識結果として出力された上位5つ(デフォルト)の確率と分類名の組み合わせで一旦保存します。
出力
認識した結果を出力します。
認識結果として一旦保存された確率と分類名を、標準出力に表示します。
備考
これで、WindowsネイティブでCaffeを使った認識アプリを作れるようになったと思います。
できればGUI付きにしたいと思いますので、今後は、MFCや.NETと組み合わせたアプリを開発し、そのノウハウを公開していきたいと思います。
関連記事
C++プログラマがWindows上でCaffeを使ってDeep Learningするお話(1)
C++プログラマがWindows上でCaffeを使ってDeep Learningするお話(2)
C++プログラマがWindows上でCaffeを使ってDeep Learningするお話(3)
C++プログラマがWindows上でCaffeを使ってDeep Learningするお話(4)
C++プログラマがWindows上でCaffeを使ってDeep Learningするお話(5)
C++プログラマがWindows上でCaffeを使ってDeep Learningするお話(6)
C++プログラマがWindows上でCaffeを使ってDeep Learningするお話(7)