少し時間が空いてしまいましたが,3回目です.
1回目*1に失敗レポートを書くと宣言してましたが,,,なんと,解決して出来るようになりました!!!
せっかくなので,成功レポート:Lenuxで作った学習モデルをWindowsに移植してC言語で推論する方法を書きます.
前回までとはLenux側のソースが完全に変わってしまっています.
大変恐縮ですが,前回からの続きという読み方は避けて下さい.
0. PC環境
改めてPC環境を確認しておきます.
実は2回目を書いた後でLenuxが壊れ,環境を作り直しました.
ですので,OSやPythonのver.が変わっています.
Lenux
- Ubuntu 18.04 LTS
- python 3.6.9
- tensorflow-gpu 1.14.0
- keras 2.3.1
- nvidia driver 440.82
- CUDA 10.0
- cudnn 7.4.2
- Windows 10
- Visual Studio 2017 Community
1. Windows側のTensorflow環境
(1) ここ*2からC言語用のdllをダウンロード
Lenux用*3も必要になるので,併せてダウンロードします.
(2) 下記のディレクトリを作成し,ここにWindows用のzipを展開
C:\Tool\tensorflow_for_c_1.14.0
※ 以後では,このパスに環境を作るものとします.
(3) Lenux用のzipを適当な場所に展開し,includeフォルダの中にある下記の2つをコピー
- コピーするファイル
c_api_experimental.h tf_attrtype.h
- コピー先
C:\Tool\tensorflow_for_c_1.14.0\include\tensorflow\c
////////////////////////////////////////////////////
ちなみに,失敗レポートを書くつもりだったやり方はC++用のTensorflowビルド*4を使っていました.
成功している方*5もいらっしゃる様ですが,僕が使おうとしたtensorflow 1.14.0のビルドはかなりrawな状態でアップロードされている様です.
リンクしようするとlibが不足してしましました.
////////////////////////////////////////////////////
2. Lenux側でpbファイルを作成
(1) 学習モデルの作成
今回から唐突にkerasを使い始めました.
特に理由は無く,何となくです.
Windows移植に成功した理由が,kerasの導入では無いと思っています.
確かめていませんが,結果オーライですので.
(2) kerasモデルをpbファイルに変換
前回はTensorflowのチェックポイントからpbを作ってましたが,今回はkerasのh5から作りました.
def convert_keras_to_tensorflow(keras_model_filename, tf_model_filename): model = load_model(keras_model_filename) model.summary() frozen_graph = freeze_session(K.get_session(), output_names=[out.op.name for out in model.outputs]) tf.train.write_graph(frozen_graph, './', tf_model_filename, as_text=False) tf.train.write_graph(frozen_graph, './', tf_model_filename + '.txt', as_text=True) if __name__ == '__main__': # convert keras_model_filename = './model.h5' tf_model_filename = './frozen_graph.pb' convert_keras_to_tensorflow(keras_model_filename, tf_model_filename)
3. Windows側で推論処理を構築
(1) Visual Studioでc++コンソールアプリケーションを作成
(2) Tensorflowを使うための設定
- 追加のインクルードディレクトリ
C:\Tool\tensorflow_for_c_1.14.0\include
- 追加のライブラリディレクトリ
C:\Tool\tensorflow_for_c_1.14.0\lib
- 追加の依存ファイル
tensorflow.lib
- 実行フォルダにコピー
tensorflow.dll frozen_model.pb ※ Lenux側で作った学習済みネットワーク testImage.txt ※ Lenux側でも使ったテスト画像
(3) 推論処理の実行
この方のソース*6を参考にさせていただきました.
実際の画像(png)ではなく,Lenux側でテスト用に配列したテキストを読み込んでいます.
- 画像の読み込み
char image_path[512]; strcpy(image_path, directory); strcat(image_path, "\\testImage.txt"); std::vector<std::vector<float>> images(DATA_SIZE, std::vector<float>(IMG_SIZE, 0.0)); if (!readImage(image_path, images)) { std::cout << "Cannot read images" << std::endl; return -1; }
- モデルの読み込み
/* get graph info */ char model_path[512]; strcpy(model_path, directory); strcat(model_path, "\\frozen_graph.pb"); displayGraphInfo(model_path);
(4) ノード名のチェック
Pythonからpbファイルを使う場合*7と同じで,入力と出力のノード名を正確に指定することがポイントになります.
上記のdsipplayGraphInfoを実行するとコンソールで見れますので,ソースに反映します.
- 入力ノードを指定
/* prepare input tensor */ TF_Output input_op = { TF_GraphOperationByName(graph, "conv2d_1_input"), 0 }; if (input_op.oper == nullptr) { std::cout << "Can't init input_op" << std::endl; return 2; }
- 出力ノードを指定
/* prepare output tensor */ TF_Output out_op = { TF_GraphOperationByName(graph, "dense_2/Softmax"), 0 }; if (out_op.oper == nullptr) { std::cout << "Can't init out_op" << std::endl; return 3; }
(5) 実行
こんな感じでできました!!!
4. 結び
前からやりたかった事が出来て嬉しいです.
Lenux + Pythonで解析結果を出すだけだと,何となく学生時代の研究みたいな感じがしてしまうんですが,,,具体的なアプリケーション適用が現実的になってきました(^_^)
この記事はコロナショックの真っ只中で書いています.
大変な思いをされている方が大勢いらっしゃることかと思います.
私も在宅勤務を余儀なくされました.
不謹慎ですが,私の場合は在宅勤務になって通勤時間が無くなり,ソースを書いたり,研究をする時間が増えました.
今は,世の中に平穏が戻ったときのために,知力と体力を蓄えるときなのだと思っています.
今回書いたソースはここ*8です.
*1:https://changlikesdesktop.hatenablog.com/entry/2020/04/02/185249
*2:https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-windows-x86_64-1.14.0.zip
*3:https://storage.googleapis.com/tensorflow/libtensorflow/libtensorflow-cpu-linux-x86_64-1.14.0.tar.gz
*4:https://github.com/fo40225/tensorflow-windows-wheel
*5:https://qiita.com/rxoxixyxd/items/f2b8a0ddf09b6734d313
*6:https://qiita.com/iwatake2222/items/d7cb2bd10a8bbb81cd8b
*7:https://changlikesdesktop.hatenablog.com/entry/2020/04/02/192850
*8:https://github.com/changGitHubJ/mnist_keras-inference_in_windows