今回は、もう少し「caffe.exe」の中身を見ていきます。
なお、今回も学習処理(「caffe.exe train」)についてのみとなります。
処理の流れ
学習時の処理は、以下のような流れで行われます。
- 引数の解析
- 初期化
- 学習の実行
引数の解析
これはGoogleの「gflags」を利用して、引数の解析を行っています。
(gflags::ParseCommandLineFlags())
「gflags」の説明は省きますが、以下のように引数の定義がされていますので、これに従って解析を行います。
DEFINE_string(gpu, "",
"Optional; run in GPU mode on given device IDs separated by ','."
"Use '-gpu all' to run on all available GPUs. The effective training "
"batch size is multiplied by the number of devices.");
DEFINE_string(solver, "",
"The solver definition protocol buffer text file.");
DEFINE_string(model, "",
"The model definition protocol buffer text file.");
DEFINE_string(phase, "",
"Optional; network phase (TRAIN or TEST). Only used for 'time'.");
DEFINE_int32(level, 0,
"Optional; network level.");
DEFINE_string(stage, "",
"Optional; network stages (not to be confused with phase), "
"separated by ','.");
DEFINE_string(snapshot, "",
"Optional; the snapshot solver state to resume training.");
DEFINE_string(weights, "",
"Optional; the pretrained weights to initialize finetuning, "
"separated by ','. Cannot be set simultaneously with snapshot.");
DEFINE_int32(iterations, 50,
"The number of iterations to run.");
DEFINE_string(sigint_effect, "stop",
"Optional; action to take when a SIGINT signal is received: "
"snapshot, stop or none.");
DEFINE_string(sighup_effect, "snapshot",
"Optional; action to take when a SIGHUP signal is received: "
"snapshot, stop or none.");
また同時に、やはりGoogleの「google-glog」でログの初期化を行います。
(google::InitGoogleLogging())
初期化
ソース的には、caffe.cppのtrain()で学習処理が行われます。
ただコードのほとんどは初期化処理になります。
まず「caffe::ReadSolverParamsFromTextFileOrDie()」でソルバファイルの解析を行います。
実際にはGoogleの「Protocol Buffers」で処理を行っています。
(google::protobuf::TextFormat::Parse())
ここで読み込むパラメータ等はあらかじめ「caffe\src\caffe\proto\caffe.proto」で記述しておき、ビルド時に「caffe\src\caffe\proto\caffe.pb.cc」に変換されて利用されます。
(scriptの「ProtoCompile.cmd」で変換処理が記述されています)
解析した結果は、caffe::SolverParameterのオブジェクト「solver_param」に保存されます。
その後、設定されていないパラメータ値を設定したりします。
パラメータ設定後、「solver_param」を使用してcaffe::Solverのオブジェクト「solver」を作成します。
この時、単精度 or 倍精度で処理を行うかを指定します。
学習の実行
「caffe::Solver::solve()」で学習を実行します。
これだけです。
なお、マルチGPUの対応もされています。
ちなみに、「caffe::Solver::solve()」の中での処理ですが、イテレータでグリグリ回しながら、
- テストのタイミングが来たらテストをする
- トレーニングをする
- ロス率を計算する
- ログを表示する
- 情報を更新する
- スナップショットのタイミングが来たらファイル出力する
を繰り返します。
おまけ
学習の処理はcaffeネームスペースの中でほぼ全て行われているので、利用者側が書かなくてはいけないコードはほとんどありません。
ただ、CNN以外のDeepLearning処理を行いたいとか、自分でレイヤーを作りたいとかだと、caffeネームスペース内のクラスを修正したり追加することになります。
関連記事
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するお話(7)
C++プログラマがWindows上でCaffeを使ってDeep Learningするお話(8)